使用更具体的模块导入的 benefit/difference 是什么?

What is the benefit/difference in using more specific module imports?

例如,假设我有一个 Angular 6 应用程序并想从 @angular/material 包中导入 MatIconModule

我能做到:

import { MatIconModule } from '@angular/material/icon';

import { MatIconModule } from '@angular/material';

这对最终的应用程序包或构建过程有任何影响吗?

这个问题并不是专门针对 @angular/material 包的,而是关于从允许这种特定和非特定模块导入的任何包导入模块的一般问题.

我觉得以前一定有人问过这个问题,但我找不到类似的问题。

我不认为这个问题完全是基于某些用户建议的意见。请看我发布的答案。

它显然基于您的编码结构,但我建议您使用

import { Observable, Observer } from 'rxjs';

阅读

import { Observable } from 'rxjs/Observable'; import { Observer } from 'rxjs/Observer';

我猜代码看起来更独立,对开发人员更友好。

出现这样的代码时,场景会变得更加清晰。

import { filter, map, catchError, publishReplay, refCount, take } from 'rxjs/operators';

发生这种情况时会更容易。

P.S :导入所有运算符会显着扩大构建输出并增加构建持续时间。所以只导入正在使用的运算符似乎更好。此外,由于 RxJS 模块的 polyfill-ish 性质,每个代码库导入一次运算符(或 Observable 的静态方法)就完全足够了。这些导入应该发生在一个集中的位置。

所以我做了一些测试...

TLDR:开发包可能更大,但生产包似乎不受影响。 (虽然我的测试非常有限)。

在我的测试中我使用了:

Node:                  10.3.0
Angular CLI:            6.0.8
Angular:                6.1.8
@angular/material:      6.4.7
webpack:                4.8.3

我使用 ng new 创建了一个新应用程序,并将 material 图标模块导入 app.module.ts 2 种不同的方式,然后 运行 ng build 分别导入。

import { MatIconModule } from '@angular/material/icon';

import { MatIconModule } from '@angular/material';

生成的 vendor.js 分别为 3.9 MB6.3 MB

查看生成的代码,您可以看到一个只导入了图标模块,而另一个导入了整个 material 组件库,即使导入仅指定了 MatIconModule class。

运行 ng build --prod 产生了相同的包。所以(至少在这个有限的例子中)它似乎对生产构建没有影响。我想 tree shaking 正在发挥作用。但是,也许使用不同的包,情况可能并非如此。

在我看来,为了安全起见,最好在可能的情况下始终更加具体。

以下是此回答可能会提出的一些其他问题。更好的答案可能会解决这些问题:

是否有任何示例表明这在生产构建中可能真正重要?

以这种方式构建的包是否有可能在生产构建中无法正确修剪?