monorepo中如何共享bundle
monorepo中如何共享bundle
在monorepo中的多个app,由于它们的npm 包都是在最顶层的workspace 管理安装的,在编译各个子应用的时候,为了节省bundle的大小,如何才能将每个应用中公用的vendor bundle 抽出来。本篇就是基于此对webpack的一些探讨
借助optimization>splitChunks 来将某些包单独编译成vendor bundle
{
optmization:{
runtimeChunk:{
name:'runtime',
},
splitChunks:{
cacheGroups:{
vendor:{
test: /[\\/]node_modules[\\/]/,
name:'vendor',
chunks:'all',
enforce:true,
}
}
}
}
}
如上所诉,将node_modules里面的包单独编译成vendor, 由于在monorepo 中每个子应用的依赖的包都是一样的,这个思路看似可行。但是有以下几个问题
- 摇树的存在
- 尽管子应用的依赖是一致的,但是子应用对于同样的包使用的程度是不一致的,所以在prod 编译的时候,摇树会将公用的包给摇掉,可能会造成其他的子应用炸掉
- 一个子应用产生的vendor,它在window里面是通过子应用的名字来管理的,例如
self['app1']={xxx}
, 所以这个vendor bundle哪怕没有摇掉,也无法直接被其他应用直接引用
(self["appbunlde"]=self["appbundle"]||[]).push([['bundle'],{...modules}]);
既然一个子应用的vendor不能被其他的应用共享,那就创建一个commonapp,它的职责就是将公用的包困扎在一起,然后子应用直接用它不久行了。这么一些确实可行。
//inex.js
import * as ModuleA from 'moduleA';
import * as ModuleB from 'moduleA/sub';
// webpack.config.js
{
output:{
library:{
name:'vendor',
type:'umd',
}
}
}
// webpack 的输出里面有如下的片段
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["vendor"] = factory();
else
root["vendor"] = factory();
})(self,()=>{
/// xxxx 省略一大坨
__webpack_require__.d(__webpack_exports__, {
ModuleA: () => (),
ModuleB: () => ()
});
return __webpack_exports__;
})
//############################################################其他应用####################################
// index.js 其他应用里
import some from 'moduleA';
import other from 'moduleA/sub';
// 在使用这个bundle 的应用里面的webpack 配置
{
externals:{
'moduleA':'vendor.ModuleA',
'moduleA/sub':'vendor.ModuleB',
}
}
// 这个是对应到bundle 里面的改动,它还可以有其他的配置,自己体会吧
{
'moduleA':(module,exports,__webpack_require_)=>{
exports = vendor.ModuleA;
},
'moduleA/sub':(module,exports,__webpack_require_)=>{
exports = vendor.ModuleB;
},
}
确实ModuleA,ModuleB 被困扎到一起了。那么问题来了,为啥需要困扎呢。如果ModuleA,ModuleB有CDN文件的化,直接copy/paste, 就可以将他们合成一个文件。何须用webpack.
感觉折腾了个寂寞
为什么我们需要webpack, 是为了在一个app 内部,将所需要的package 或者说 import/require 等语法中所引用的文件整合到一个大的文件中。然后再压缩。它本质上解决的是代码之间的捆绑,如果我们想把同样的代码先捆绑成bundle,然后再消费这个bundle,这个时候就不是webpack 的活了。因为webpack 这个时候只是留下了接口去兼容外面的bundle,并没有捆绑他们,所以。我们完全可以手动的将一些包裹文件整合一起。
分类:
前端工程化
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构