如果我不将我的代码包装在 ngModules 或服务中怎么办?

What if I don't wrap my code in ngModules or services?

我目前开始使用 Angular,之前使用过 React。

到目前为止,在其他堆栈上,假设我写了一个新文件 handle-error.js 并有选择地将它导入到几个页面上,比如 endpoint1.jsendpoint2.js。鉴于这些 "endpoints" 中的每一个都被定义为 webpack 上的入口文件,webpack 通常已经解决了如何有选择地导入这个公共模块 handle-error.js 或是否将其包含在公共包中。

另一方面,对于 angular,我看到了几个包含在@ngModule 类 中的公共库。所以我想知道,如果我只是在我的组件中导入 handle-error.js 而不是将其包装在 @ngModule 中,我会失去什么?

编辑:

假设我的应用程序结构如下:

|__ base app module
  |__ page 1 module
  |__ page 2 module
    |__ imports handleError() (*)

文档明确指出模块的一个主要目的是延迟加载。 handleError 只被第 2 页需要,那岂不是只有第 2 页被请求才延迟加载?

另一个问题是:我是否也应该将其包装在服务中?虽然我可能已经知道答案 - 它有助于模拟测试。

webpack will usually already work out on how to selectively import this common module handle-error.js or whether to include it in a commons bundle

是的,没错,在Angular中也是如此。尽量不要认为 og NgModules 与 webpack 包有任何关系。虽然由路由器定义的惰性模块确实会作为一个单独的 webpack 包出现。这纯粹是 Angular 编译器使用的一种打包策略。

So I'm left wondering, what do I lose if I simply import handle-error.js in my components instead of wrapping it inside an @ngModule?

我的 Angular 项目的源代码中大约有 25% 是这样完成的。

库、额外的 类、接口、函数式编程、实用程序和其他类似的东西不需要在 NgModule 中,除非你需要使用 Angular 依赖注入器.

The documentation clearly states that one main purpose of modules are lazy loading. Since handleError is only required by page 2, wouldnt it only be lazy loaded once page 2 is requested?

Angular和Webpack都不能基于动态使用的tree shake代码。而 webpack 可以根据导入的用法进行 tree shake。它无法判断一个类型的全局定义是否在过程中被引用。

这在 Angular 中特别困难,因为依赖注入器的工作方式。

因此,将 NgModule 视为向 Angular 声明正在使用项目中的 内容 的一种前期方式(组件、服务、供应商等)。

如果没有模块被另一个模块引用,则可以从构建中删除整个模块。 Angular 必须以这种方式解决问题,因为它使用 运行 时间依赖注入器。

例如;

 const thing = injector.get(SOME_UNKNOWN_TOKEN);

在上面的示例中,名为 SOME_UNKNOWN_TOKEN 的依赖令牌要求注入器提供 thing 的值。

Angular 无法知道 SOME_UNKNOWN_TOKEN 的提供者、内容或方式。它来自什么模块,谁负责提供它等等..等等..

所以它不能完全基于导入的tree shake。提供由 SOME_UNKNOWN_TOKEN 定义的 thing 的源代码可能没有被与 Angular 源代码直接相关的任何东西导入(想想第三方库)。

我知道这不能直接回答您的问题,但这就是 为什么 我们使用模块而不是直接导入东西。如果我们没有依赖注入器,可以安全地假设 Angular 在代码连接方式上与 React 非常相似。

Another question would also be: should I also wrap it in a service? Although I already probably know the answer - it helps on mocks for tests

这纯粹是基于 Angular 中的依赖注入器做出的决定。

DI 允许您做很多值得学习的特殊事情,因为这是可以建立许多组件到组件连接的方式。组件也可以提供自己的服务等等。

我不使用 DI 处理复杂的数据结构。就像对象实例树或我需要创建事物的许多实例的地方。 DI 非常适合依赖于其他服务的单一服务。