Webpack 技巧 - 联合 alias 和 mainFields 提升多库联调效率

一、多库联调场景

目前在开发一个工程项目,考虑到可扩展性和功能解耦,将每一个功能模块都单独拆分出来。在正式使用、单独维护某个功能包的时候没什么问题,最为头疼的是联调两个功能模块的时候,就比较掣肘了。node

咱们举下面的场景为例来讲明:webpack

  • 工程项目中有 A、B、C 这 3 个功能模块,每一个功能模块都是单独的一个 npm 包;
  • 其中 A 是基础工具包,B、C 是业务功能模块;C 包依赖 A 包的功能

工程目录及引用关系以下图所示:
功能模块web

1.一、联调的难题

当咱们开发 C 模块的时候,须要 同时联调 A 模块的功能,而因为 A 模块是以 npm 包放在在 node_modules 中,因此咱们直接修改 A 模块并无什么用,修改的效果并不会出现的 C 模块的调试内容中。npm

1.二、一般的解决方案

一般咱们的解决方法是采用 npm link 方式解决:先在 A 模块下执行 npm link;而后去 C 模块中执行 npm link A,这样咱们就能方便联调这两个模块。json

然而这种 npm link 的方式在某些场景仍是有限制:数组

  1. 若是你使用 Typescript 开发,npm link 后有可能会报错找不到 A 模块中的 xx 类型定义;这个目前我也没有找到好的解决方案。。。
  2. 若是 A 包只以压缩版本发行(即 dist 目录只存 index.min.js 文件),那么你每次修改 A 文件后必须手动打包一次,那么 C 模块才会感知文件的变化触发 hot reload

若是没有上述这两个问题,我以往我都直接使用 npm link 的方式联合开发,联调地也是蛮开心的。微信

然而正在开发的工程项目中却偏偏遇到上述这两个问题,避无可避。总不能每修改一次 A 后发一个 npm 包,而后去 C 模块下从新安装 A 包(万一 A 包修改得不对,又得重来一次)。。。这种感受就是比如你去某陌生小区找朋友,只能靠猜、问路人来定位到具体xx单元(有些小区布局奇葩一些的,连号的单元楼可能隔着很远很远)ide

想一想就抓狂,这种非人的开发体验、落后的联调效率,简直是在浪费生命;工具

好吧,那就只能想办法解决喽~布局

二、优化的解决方案

通常是到网上寻现有方案,拿来就用最好;可此次到网上找了半天,也没有搜索到我这种方案的解法,不得不去 webpack 官方上找合理配置项来解决个人问题 —— 毕竟 Webpack 那么强大,方案老是有的。

在 Webpack 的官方文档里摸爬滚打了一番,发现配合 resolve.aliasresolve.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 的时候,能够用 $ 结尾,兼容引入子包的问题
  • 通常来说,webpack 项目都有 devproduction 两套配置流程,咱们只在 dev 的时候采用上述方案, production 仍是保持原有的配置。

no npm link, no pains~

参考文档

下面的是个人公众号二维码图片,欢迎关注。
我的微信公众号

相关文章
相关标签/搜索