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~

參考文檔

下面的是個人公衆號二維碼圖片,歡迎關注。
我的微信公衆號

相關文章
相關標籤/搜索