Skip to content

Commit

Permalink
fix: 设置内容安全策略
Browse files Browse the repository at this point in the history
  • Loading branch information
asnowwolf committed May 12, 2024
1 parent cdf986d commit f0c6ac9
Show file tree
Hide file tree
Showing 88 changed files with 28,674 additions and 13 deletions.
852 changes: 852 additions & 0 deletions assets/videos/4 Runtime Performance Optimizations-f8sA-i6gkGQ.cn.vtt

Large diffs are not rendered by default.

1,350 changes: 1,350 additions & 0 deletions assets/videos/4 Runtime Performance Optimizations-f8sA-i6gkGQ.en.vtt

Large diffs are not rendered by default.

852 changes: 852 additions & 0 deletions assets/videos/4 Runtime Performance Optimizations-f8sA-i6gkGQ.tw.vtt

Large diffs are not rendered by default.

117 changes: 117 additions & 0 deletions assets/videos/CpLOm4o_FzM.cn.vtt
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
WEBVTT
Kind: subtitles
Language: zh-CN
00:00.240 --> 00:04.080
Circular dependency in DI detected.
当你遇到某个依赖其自身的依赖项时,就会出现本错误

00:04.080 --> 00:09.200
有时是直接依赖,但更常见的是间接依赖

00:09.200 --> 00:13.600
浏览器的控制台中会抛出一个运行时错误,告诉你哪个类受到了影响

00:13.600 --> 00:18.400
更有用的是,此警告会同时显示在浏览器控制台和命令行终端里

00:18.400 --> 00:21.760
最重要的是,它提供了此循环依赖的依赖路径

00:21.760 --> 00:26.960
仔细去看,它还会告诉我们,我们的一个 Storage 类注入了某个 User 类

00:26.960 --> 00:31.520
而这个 User 类本身又依赖原来那个 Storage 类
我们继续前进,来看一个简单的重现过程

00:31.520 --> 00:35.680
然后我们会花一些时间,来深入理解 Angular 的依赖注入体系

00:35.680 --> 00:40.480
仔细看源码,你会注意到我们有两个服务,User 和 Storage

00:40.480 --> 00:45.600
问题在于 User 类在自己的构造函数中注入了一个 Storage 类

00:45.600 --> 00:49.840
而 Storage 类也在自己的构造函数中注入了一个 User 类
这导致它们陷入了一种不正常的“相互依赖”关系中

00:49.840 --> 00:54.800
此问题的解决方案是要打破这种依赖,因此要做某种重构

00:54.800 --> 00:59.440
让某个 @Injectable 依赖另一个 @Injectable 固然是没问题的

00:59.440 --> 01:04.640
但这种依赖关系只应该是单向的,这意味着我们需要重构

01:04.640 --> 01:10.400
以便从 Storage 中移除 User 服务
或者反过来,从 User 中移除 Storage 服务

01:10.400 --> 01:14.800
一般而言,最好将 @Injectable 服务中依赖项的数量最小化

01:14.800 --> 01:20.000
因为那样也会减少将来出现类似问题的可能性
目前,我们的 Storage 类中有一个方法

01:20.000 --> 01:25.040
用来把此用户写入数据库中,但是它依赖 User 服务,以获取当前用户的值

01:25.040 --> 01:30.480
我们可以通过重构代码来解决此问题:
改用参数接收此用户的值,而不再注入完整的用户类

01:30.480 --> 01:35.120
这不仅能让我们从构造函数中移除此依赖项

01:35.120 --> 01:39.040
还能让代码更便于进行单元测试,因为你不再

01:39.040 --> 01:44.320
需要 Mock 或关心一个额外的依赖项,该方法将只依赖其输入参数

01:44.320 --> 01:49.600
这会让测试更简单。现在,我们保存这些修改,此错误消失了

01:49.600 --> 01:54.480
但是在结束讨论之前,我们先对 Angular 的依赖注入体系做一个深入研究

01:54.480 --> 01:59.280
以便理解为什么会出现本错误
当你使用 Angular CLI 生成某个服务时,你会注意到

01:59.280 --> 02:04.000
该类带有 @Injectable 装饰器
当它带有 \{ providedIn: 'root' \} 选项时

02:04.000 --> 02:07.840
Angular 就会实例化此类,并且让他在整个应用中可见

02:08.400 --> 02:13.040
和组件不同,该类只会作为单例对象实例化一次

02:13.040 --> 02:17.760
那么,如果有两个类互相依赖,你要如何决定先实例化哪个呢?

02:17.760 --> 02:21.760
这是一个经典的先有鸡还是先有蛋的悖论
并且,如果你要遵循依赖倒置原则,它也是不合理的

02:21.760 --> 02:26.960
让我们简要回顾一下。当你遇到了 DI 检测到循环依赖的情况时

02:26.960 --> 02:31.600
第一步是通过组件和服务的构造函数来找出

02:31.600 --> 02:35.680
到底是哪些依赖项产生了循环依赖

02:35.680 --> 02:40.160
找出来之后,你可以重构代码以打破这种循环

02:40.160 --> 02:44.720
欲知详情和范例,请阅读Angular官方文档的“依赖注入”指南
143 changes: 143 additions & 0 deletions assets/videos/CpLOm4o_FzM.en.vtt
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
WEBVTT
Kind: subtitles
Language: en
00:00.240 --> 00:04.080
Circular dependency in DI detected.
You'll encounter this error when you\h\h

00:04.080 --> 00:09.200
have a dependency that depends on itself,\h
either directly, or more often indirectly.\h

00:09.200 --> 00:13.600
A runtime error will be thrown in the browser\h
console telling you which class is effected, but\h\h

00:13.600 --> 00:18.400
what's perhaps more useful is a warning that can\h
be seen both in the console and in the terminal.\h

00:18.400 --> 00:21.760
Most importantly, it provides the\h
path of the circular dependency.\h

00:21.760 --> 00:26.960
If we look closely, it's telling us we have a\h
storage class that injects a user class, which\h\h

00:26.960 --> 00:31.520
itself depends on the original storage class.
Let's go ahead and look at a simple reproduction,\h\h

00:31.520 --> 00:35.680
and then we'll take some time to go in depth\h
about angular's dependency injection system.\h

00:35.680 --> 00:40.480
If we take a look at our source code, you'll\h
notice we have two services, user and storage.\h

00:40.480 --> 00:45.600
The problem is that user has injected storage\h
in its constructor and storage has injected\h\h

00:45.600 --> 00:49.840
user in its constructor, putting them in\h
an impossible codependent relationship.\h

00:49.840 --> 00:54.800
The solution to this problem is to break the loop,\h
which will most likely require some refactoring.\h\h

00:54.800 --> 00:59.440
It's perfectly okay for an @Injectable to depend\h
on another @Injectable, but the relationship\h\h

00:59.440 --> 01:04.640
can only go one way, which means in this case we\h
need to refactor to remove the user service from\h\h

01:04.640 --> 01:10.400
storage, or vice versa, remove the storage service\h
from user, and generally speaking, it's a good\h\h

01:10.400 --> 01:14.800
idea to minimize the number of dependencies in\h
an @Injectable service, because that will reduce\h\h

01:14.800 --> 01:20.000
the likelihood of similar issues coming up in the\h
future. Now in our storage class we have a method\h\h

01:20.000 --> 01:25.040
to write the user to the database, but it depends\h
on the user service for the current user value.\h\h

01:25.040 --> 01:30.480
We can address the problem here by refactoring\h
our code to take the user value as an argument,\h\h

01:30.480 --> 01:35.120
rather than inject the entire user class. Not only\h
does that allow us to remove the dependency from\h\h

01:35.120 --> 01:39.040
the constructor, it will also make this code\h
easier to unit test, because you don't have\h\h

01:39.040 --> 01:44.320
an additional dependency to mock or worry about,\h
and the method only depends on its input arguments\h\h

01:44.320 --> 01:49.600
making it easier to reason about. Now if we go\h
ahead and save our changes, the error is gone. But\h\h

01:49.600 --> 01:54.480
before we wrap things up, let's take a deeper look\h
at Angular's dependency injection to understand\h\h

01:54.480 --> 01:59.280
why this error happens in the first place. When\h
you generate a service with the Angular CLI you'll\h\h

01:59.280 --> 02:04.000
notice how the class is decorated with @Injectable\h
when used with the \{ providedIn: 'root' \} option,\h\h

02:04.000 --> 02:07.840
Angular will instantiate the class and make\h
it visible throughout the entire application.\h\h

02:08.400 --> 02:13.040
Unlike a component, this class is only\h
instantiated once as a singleton. Now\h\h

02:13.040 --> 02:17.760
imagine two classes that depend on each other, how\h
do you determine which one to instantiate first?\h\h

02:17.760 --> 02:21.760
It's a classic chicken or the egg paradox, and\h
that just doesn't work when you're following\h\h

02:21.760 --> 02:26.960
the dependency inversion principle. Let's go ahead\h
and recap. When you encounter circular dependency\h\h

02:26.960 --> 02:31.600
in DI detected, the first step is to determine\h
which dependencies create a loop by mapping\h\h

02:31.600 --> 02:35.680
out the dependencies and the constructor\h
of your components modules and services.\h\h

02:35.680 --> 02:40.160
Once identified you can then refactor your code\h
to break the loop. For additional details and\h\h

02:40.160 --> 02:44.720
examples check out the dependency injection\h
guide in the official Angular documentation.
117 changes: 117 additions & 0 deletions assets/videos/CpLOm4o_FzM.tw.vtt
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
WEBVTT
Kind: subtitles
Language: zh-TW
00:00.240 --> 00:04.080
Circular dependency in DI detected.
当你遇到某个依赖其自身的依赖项时,就会出现本错误

00:04.080 --> 00:09.200
有时是直接依赖,但更常见的是间接依赖

00:09.200 --> 00:13.600
浏览器的控制台中会抛出一个运行时错误,告诉你哪个类受到了影响

00:13.600 --> 00:18.400
更有用的是,此警告会同时显示在浏览器控制台和命令行终端里

00:18.400 --> 00:21.760
最重要的是,它提供了此循环依赖的依赖路径

00:21.760 --> 00:26.960
仔细去看,它还会告诉我们,我们的一个 Storage 类注入了某个 User 类

00:26.960 --> 00:31.520
而这个 User 类本身又依赖原来那个 Storage 类
我们继续前进,来看一个简单的重现过程

00:31.520 --> 00:35.680
然后我们会花一些时间,来深入理解 Angular 的依赖注入体系

00:35.680 --> 00:40.480
仔细看源码,你会注意到我们有两个服务,User 和 Storage

00:40.480 --> 00:45.600
问题在于 User 类在自己的构造函数中注入了一个 Storage 类

00:45.600 --> 00:49.840
而 Storage 类也在自己的构造函数中注入了一个 User 类
这导致它们陷入了一种不正常的“相互依赖”关系中

00:49.840 --> 00:54.800
此问题的解决方案是要打破这种依赖,因此要做某种重构

00:54.800 --> 00:59.440
让某个 @Injectable 依赖另一个 @Injectable 固然是没问题的

00:59.440 --> 01:04.640
但这种依赖关系只应该是单向的,这意味着我们需要重构

01:04.640 --> 01:10.400
以便从 Storage 中移除 User 服务
或者反过来,从 User 中移除 Storage 服务

01:10.400 --> 01:14.800
一般而言,最好将 @Injectable 服务中依赖项的数量最小化

01:14.800 --> 01:20.000
因为那样也会减少将来出现类似问题的可能性
目前,我们的 Storage 类中有一个方法

01:20.000 --> 01:25.040
用来把此用户写入数据库中,但是它依赖 User 服务,以获取当前用户的值

01:25.040 --> 01:30.480
我们可以通过重构代码来解决此问题:
改用参数接收此用户的值,而不再注入完整的用户类

01:30.480 --> 01:35.120
这不仅能让我们从构造函数中移除此依赖项

01:35.120 --> 01:39.040
还能让代码更便于进行单元测试,因为你不再

01:39.040 --> 01:44.320
需要 Mock 或关心一个额外的依赖项,该方法将只依赖其输入参数

01:44.320 --> 01:49.600
这会让测试更简单。现在,我们保存这些修改,此错误消失了

01:49.600 --> 01:54.480
但是在结束讨论之前,我们先对 Angular 的依赖注入体系做一个深入研究

01:54.480 --> 01:59.280
以便理解为什么会出现本错误
当你使用 Angular CLI 生成某个服务时,你会注意到

01:59.280 --> 02:04.000
该类带有 @Injectable 装饰器
当它带有 \{ providedIn: 'root' \} 选项时

02:04.000 --> 02:07.840
Angular 就会实例化此类,并且让他在整个应用中可见

02:08.400 --> 02:13.040
和组件不同,该类只会作为单例对象实例化一次

02:13.040 --> 02:17.760
那么,如果有两个类互相依赖,你要如何决定先实例化哪个呢?

02:17.760 --> 02:21.760
这是一个经典的先有鸡还是先有蛋的悖论
并且,如果你要遵循依赖倒置原则,它也是不合理的

02:21.760 --> 02:26.960
让我们简要回顾一下。当你遇到了 DI 检测到循环依赖的情况时

02:26.960 --> 02:31.600
第一步是通过组件和服务的构造函数来找出

02:31.600 --> 02:35.680
到底是哪些依赖项产生了循环依赖

02:35.680 --> 02:40.160
找出来之后,你可以重构代码以打破这种循环

02:40.160 --> 02:44.720
欲知详情和范例,请阅读Angular官方文档的“依赖注入”指南
Loading

0 comments on commit f0c6ac9

Please sign in to comment.