我有一个 Angular(版本 15.2)工作区,其中有一个
host
应用程序、三个 modules
和两个 libraries
。
此结构显示了什么正在被什么使用:
host
moduleA
library1
moduleB
library1
library2
moduleC
library1
library2
host
以这种方式延迟加载三个模块:
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
const routes: Routes = [
{
path: "a",
loadChildren: () => import("a").then(m => m.AModule)
},
{
path: "b",
loadChildren: () => import("b").then(m => m.BModule)
},
{
path: "c",
loadChildren: () => import("c").then(m => m.CModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {
}
三个模块中的每一个都使用
library1
和/或 library2
,如开头的结构所示。
延迟加载按预期工作,这意味着当我导航到“localhost:4200/a”时,我可以从网络上看到我只得到
moduleA.js
(当然是由 Angular 生成的名称)。
当然,我也看到了文件
common.js
,正如我所期望的,它包含 library1
、moduleA
和 moduleB
中使用的 moduleC
的所有代码。
问题是这个
common.js
文件还包含来自library2
的代码,该代码仅由moduleB
和moduleC
共享。这会导致浏览器加载当时无用的代码,并使延迟加载系统的目的无效(尽管不是完全无效)。
因此,我想知道在角度配置中是否需要添加或更改一些内容,以获得每个库的不同捆绑包。
期望的结果是,当导航到“localhost:4200/a”时,浏览器将下载
moduleA.js
和 library1.js
。然后,当导航到“localhost:4200/b”时,浏览器将下载moduleB.js
、library2.js
,但不会下载已经下载的library1
。
我已经探索了像 Angular 选项
vendorChunk: false
、commonChunk: false
这样的解决方案,然后尝试通过 Angular json 使用 webpack 的 SplitChunkPlugin
。
使用
SplitChunkPlugin
方法,我能够获得一个common.js
文件,其中仅包含library1
的代码,所有惰性导入模块都使用该代码,但是library2
的代码被重复了在 moduleB
和 moduleC
。这就是我的自定义 webpack 配置的样子:
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
library1: {
test: /[\\/]projects[\\/]library1[\\/]/,
name: 'library1',
chunks: 'all'
},
library2: {
test: /[\\/]projects[\\/]library2[\\/]/,
name: 'library2',
chunks: 'all'
}
}
}
}
};
SplitChunksPlugin
确实是我需要的。该插件没有创建两个单独的包,因为每个库的大小不足以创建单独的包,因为 Webpack 对于输出包有一些默认的最小和最大大小。
因此,强制 Webpack 创建单独的包(无论其大小如何)的一种方法是将键“enforce: true”添加到SplitChunksPlugin
选项中:
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
library1: {
test: /[\\/]projects[\\/]library1[\\/]/,
name: 'library1',
enforce: true,
chunks: 'all'
},
library2: {
test: /[\\/]projects[\\/]library2[\\/]/,
name: 'library2',
enforce: true,
chunks: 'all'
}
}
}
}
};
强制键“告诉 webpack 忽略 splitChunks.minSize、splitChunks.minChunks、splitChunks.maxAsyncRequests 和 splitChunks.maxInitialRequests 选项,并始终为此缓存组创建块。