如何用Angular CLI生成多最小公共代码块?需公私分离
拆分Angular应用的公共代码块:公共端与私有端分离方案
当然可以实现!我之前在Angular 5.x + CLI 1.6.x的项目里遇到过完全一样的问题,通过自定义Webpack配置就能把公共端和私有端的共享代码拆分成独立的chunk,避免私有代码被提前加载。
核心思路
你的问题本质是默认的common chunk把公共端和私有端的共享代码混在了一起,我们需要通过Webpack的CommonsChunkPlugin(因为Angular CLI 1.6对应Webpack 3,还没有Webpack 4的splitChunks)手动拆分,让:
- 公共端的共享代码(比如全局
shared模块)打包到public-commonchunk,随首次加载 - 私有端的共享特性模块打包到
private-commonchunk,仅在私有懒加载模块被加载时才会加载
具体步骤
1. 导出Webpack配置(不可逆操作,谨慎执行)
Angular CLI 1.x默认隐藏Webpack配置,需要先导出:
ng eject
执行后项目会生成webpack.config.js,同时package.json的脚本会替换成Webpack相关命令。
2. 修改Webpack配置中的CommonsChunkPlugin
找到配置里的plugins数组,替换原有的CommonsChunkPlugin配置为以下内容:
// 先提取第三方依赖到vendor chunk new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: (module) => { // 匹配node_modules里的第三方包 return module.context && module.context.indexOf('node_modules') !== -1; } }), // 提取公共端的共享代码到public-common chunk new webpack.optimize.CommonsChunkPlugin({ name: 'public-common', chunks: ['main'], // 只针对公共端入口main的chunk minChunks: (module, count) => { // 匹配被至少2个公共端模块引用,且不属于私有共享模块的代码 return count >= 2 && module.context && !module.context.includes('src/app/private-shared'); } }), // 提取私有端的共享代码到private-common chunk new webpack.optimize.CommonsChunkPlugin({ name: 'private-common', chunks: ['private-module1', 'private-module2'], // 替换成你的私有懒加载模块chunk名 minChunks: (module, count) => { // 匹配被至少2个私有模块引用,且属于私有共享模块的代码 return count >= 2 && module.context && module.context.includes('src/app/private-shared'); } })
注意:
- 把
src/app/private-shared替换成你实际的私有共享模块路径private-module1等要替换成你私有懒加载模块对应的chunk名(可以通过ng build --stats-json查看chunk名称)
3. 调整入口与加载逻辑
- 确保
index.html里只引入vendor、public-common和main的bundle,私有相关的bundle会在懒加载时自动被Angular加载 - 检查私有共享模块:确保它们只被私有懒加载模块引用,没有被公共端的任何模块(包括
core、shared)引用,否则还是会被打包到public-common里
4. 测试打包效果
执行打包命令:
npm run build -- --prod
查看dist目录,你会看到生成了public-common.[hash].js和private-common.[hash].js两个独立的chunk,打开应用时只有公共端的chunk会被首次加载,私有chunk只有在登录后访问私有模块时才会请求。
额外提示
如果你不想执行ng eject(毕竟不可逆),也可以尝试使用社区的自定义Webpack构建工具,但在Angular CLI 1.6的版本中,ng eject是最直接可靠的方式。
内容的提问来源于stack exchange,提问作者bygrace
相关产品推荐
相关产品推荐

