1、多库联调场景
目前在开发一个工程项目,考虑到可扩展性和功能解耦,将每个功能模块都单独拆分出来。在正式使用、单独维护某个功能包的时候没什么问题,最为头疼的是联调两个功能模块的时候,就比较掣肘了。
我们举下面的场景为例来说明:
工程目录及引用关系如下图所示:
工程目录及功能模块引用图示
当我们开发 C 模块的时候,需要 同时联调 A 模块的功能,而由于 A 模块是以 npm 包放在在 node_modules 中,所以我们直接修改 A 模块并没有什么用,修改的效果并不会出现的 C 模块的调试内容中。
通常我们的解决方法是采用 npm link
方式解决:先在 A 模块下执行 npm link
;然后去 C 模块中执行 npm link A
,这样我们就能方便联调这两个模块。
然而这种 npm link 的方式在某些场景还是有限制:
npm link
后有可能会报错找不到 A 模块中的 xx 类型定义;这个目前我也没有找到好的解决方案。。。如果没有上述这两个问题,我以往我都直接使用 npm link
的方式联合开发,联调地也是蛮开心的。
然而正在开发的工程项目中却恰恰遇到上述这两个问题,避无可避。总不能每修改一次 A 后发一个 npm 包,然后去 C 模块下重新安装 A 包(万一 A 包修改得不对,又得重来一次)。。。这种感觉就是好比你去某陌生小区找朋友,只能靠猜、问路人来定位到具体xx单元(有些小区布局奇葩一些的,连号的单元楼可能隔着很远很远)
想想就抓狂,这种非人的开发体验、落后的联调效率,简直是在浪费生命;
好吧,那就只能想办法解决喽~
一般是到网上寻现有方案,拿来就用最好;可这次到网上找了半天,也没有搜索到我这种方案的解法,不得不去 webpack 官方上找合理配置项来解决我的问题 —— 毕竟 Webpack 那么强大,方案总是有的。
在 Webpack 的官方文档里摸爬滚打了一番,发现配合 resolve.alias
、resolve.mainFields
就能解决上述两则难题,相比 npm link
感觉这种方案更加适合大型工程项目联调:
首先给 A 模块目录下的 package.json 新增 idebug
字段,指向该模块的入口文件(假设为 src/index.ts
)
//...
"browser": "dist/index.umd.js",
"idebug": "src/index.tsx",
// ...
其次在 C 模块目录里的 webpack 配置项更改 resolve
配置,将新增的 idebug
字段作为 mainFields
数组的第一个属性:
module.exports = {
//...
resolve: {
alias: {
'A$': path.resolve(__dirname, '../A/'),
},
mainFields: ['idebug', 'browser', 'module', 'main']
//...
}
};
上述
idebug
名字可以自定义,只要保证 A 模块中的 package.json 和 C 模块的 webpack 配置项中的mainFields
中的名字一致即可;
这样在运行 C 模块的 Webpack 时,就不会去找本目录下的 node_modules 中的 A 模块,而是去加载 ../A/src/index.ts
文件,达到了 C 模块和 A 模块源码联调的目的;
一些说明:
path.resolve()
来获取绝对路径alias
的时候,可以用 $
结尾,兼容引入子包的问题no npm link, no pains~
REFERENCE
参考文档
resolve
的解释,附中文版resolve
配置项中各个属性的功能含义,诸如 resolve.modules
、resolve.alias
、resolve.mainFields
等resolve
和 resolveLoader
对路径的规则—END—