Cod*_*n25 11 typescript angular-cli tree-shaking angular angular8
我们目前正在尝试优化复杂的 Angular 应用程序(性能和包大小)。
我们发现我们有部分未使用的组件,但我们不能 100% 确定它们。无论如何......我们目前要问的问题是在 Angular 中摇树究竟是如何工作的。
问题 1)如果在模块的声明、导入或提供者数组中有条目,但该模块没有在任何地方使用,它们是否也通过摇树移除或包含在最终包中?
例子:
@NgModule({
imports: [
FirstModule,
SecondModule // Is not used anymore (probably) but imported here
],
declarations: [SampleComponent] // Is not used anymore (probably) but imported here
})
export class SampleModule {
}
Run Code Online (Sandbox Code Playgroud)
信息:该模块/组件的路由已被删除。
问题 2)仅从路由模块中移除这些组件是否足以使摇树过程成功?
问题 3)要使摇树过程达到最佳状态,应该具备哪些条件?
使用 Angular 8.2 版
Kev*_*eal 10
关于摇树在 Angular 中的工作原理
摇树主要在缩小阶段完成,并不特定于 Angular。terser
是他们在 Angular CLI 中使用的压缩器,它是支持 ES6 语法的 Uglify 的一个分支。
terser
读取您的代码,如果它没有在其他地方引用,并且可以肯定删除某些代码不会产生副作用,那么它将删除该代码。
terser
不能确定带有装饰器的类在定义时是否有副作用(装饰器是函数调用)。在 Angular 的生产版本中,他们有一个名为“build-optimizer”的 webpack 插件,它会去使用他们的装饰器的地方,并/*@__PURE__*/
在编译的 javascript(来自 Typescript)旁边添加一个特殊的注释,它terser
识别并删除装饰类(如果它是其他地方未提及)。
关于从 NgModule 中移除组件
构建过程只是从您的main.ts
文件开始,并抓取所有文件的所有导入以包含在您的构建中。如果从 main.ts 文件中,您的组件文件从未被爬行过程找到的任何文件导入,则它将永远不会被包含在内。这不是摇树,它根本没有包含在构建过程中。
如果您的模块文件是唯一导入组件文件的地方,那么删除该导入就足以不将该组件包含在您的构建中。
关于你可以做的事情
您可以进行一些特定于 Angular 的更改,以确保您只构建您使用的代码。
{providedIn: root}
装饰选项Injectable
并删除任何可注入服务、保护的地方,无论来自任何 Angular 装饰的providers: []
.此外,在调用站点(不是定义),您可以使用/@__PURE__/
注释标记任何没有副作用的函数,这样即使在某处调用它们,如果返回值可以通过其他一些优化删除,函数本身也可以移除。我还没有测试过这个,但理论上它应该可以工作。
我不知道所有不同的构建阶段如何转换您的代码,以及它们是否在terser
可以看到它们之前移动或删除注释。
您可以使用此 Playground 工具对其进行测试:https : //terser-playground.surge.sh/
用这个例子试试:
(function() {
const a = 1;
const b = 2;
const c = /*@__PURE__*/ test();
console.log(a + b);
}());
function test() {
return 3
}
Run Code Online (Sandbox Code Playgroud)
您可以使用webpack-bundle-analyzer,它可以帮助您在最终输出文件中可视化大小和不同使用的组件。这样您就可以确定是否使用了模块,然后您可以安全地删除它。
归档时间: |
|
查看次数: |
6409 次 |
最近记录: |