如何使用Angular Ivy实现tree shaking 构建时排除多余组件
结论
Angular 11.2.14 自带的 Ivy tree shaking 机制无法直接对你当前写法里的未使用首页组件做摇树优化。
原因说明
- Tree shaking 属于编译期静态优化能力,只能识别编译阶段就能确定永远不会执行的代码分支。你当前用
switch判断运行时变量environment.sitename的写法,编译阶段无法预判运行时的变量取值,所以两个返回分支都会被保留,对应的组件自然不会被删除。 - 此外如果两个首页组件都被声明在对应 NgModule 的
declarations/entryComponents数组中,Angular 会默认标记组件为已使用,哪怕没有显式引用也不会被摇掉。
可行解决方案
方案1:使用Angular原生文件替换功能(最稳妥,无兼容问题)
Angular 构建配置原生支持不同构建环境下替换指定文件,完全规避冗余代码引入的问题:
- 新建两个站点对应的首页导出文件:
src/app/home/home.bhcl.ts
import { HomeComponent } from './home.component'; export const HomeEntryComponent = HomeComponent;
src/app/home/home.nl.ts
import { HomeNlComponent } from './home-nl.component'; export const HomeEntryComponent = HomeNlComponent;
- 新增通用占位文件
src/app/home/home.ts,作为替换基准:
// 仅作为占位文件,构建时会被对应站点的配置替换 export const HomeEntryComponent = null;
- 在
angular.json中对应项目的configurations节点下,给两个站点分别新增文件替换规则:
"configurations": { "bhcl": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.bhcl.ts" }, { "replace": "src/app/home/home.ts", "with": "src/app/home/home.bhcl.ts" } ], // 其他生产配置保持不变 "aot": true, "buildOptimizer": true }, "nl": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.nl.ts" }, { "replace": "src/app/home/home.ts", "with": "src/app/home/home.nl.ts" } ], // 其他生产配置保持不变 "aot": true, "buildOptimizer": true } }
- 业务代码中直接导入通用文件的导出值即可:
import { HomeEntryComponent } from './home/home'; // 路由配置直接使用 const routes = [ { path: '', component: HomeEntryComponent } ];
该方案构建时只会引入当前站点对应的组件代码,不会加载另一个站点的组件,比tree shaking可靠性更高。
方案2:优化写法适配编译期摇树
如果你不想改文件结构,可以调整写法让编译期可以识别死代码:
- 确保生产构建开启了
aot: true和buildOptimizer: true,Angular 11生产构建默认开启这两个配置。 - 把动态获取组件的写法改为静态三元表达式,同时确保
environment.sitename是编译期可确定的常量(不要做动态赋值):
export const HomeEntryComponent = environment.sitename === EmbassyName.BHCL ? HomeComponent : HomeNlComponent;
- 确保未使用的组件没有在其他地方被显式引用,也没有在NgModule的
declarations之外的地方声明。
编译阶段如果能确定environment.sitename的固定值,build optimizer会直接删掉未使用的分支,对应的组件没有其他引用的话就会被tree shaking移除。
内容的提问来源于stack exchange,提问作者desertSniper87
相关产品推荐
相关产品推荐

