0x.00 📢 前言
👇 項目工程化系列文章鏈接如下,推薦按照順序閱讀文章 👇。
1️⃣ 源碼剖析之工程化(一):項目概覽、package.json、npm script
2️⃣ 源碼剖析之工程化(二):項目構建、MD解析
3️⃣ 源碼剖析之工程化(三):打包配置
本系列文章主要通過解析element項目源碼,從結構、功能、源碼方面逐一解析,學習其模塊化、組件化、規范化、自動化等多維度優秀實踐。主要內容包含項目結構、npm script、項目構建、文檔解析、打包配置、發布部署等。
本文是第三篇,介紹項目的打包配置功能。
0x.01 📦 打包配置
🚨 項目中
webpack版本為4.X,文中涉及語法、功能與最新版本5.X相比存在變化。
📝 commonjs vs commonjs2
接下來配置 libraryTarget的選項中可以看到'commonjs'、'commonjs2'。兩者之前的有什么區別?
commonjs 規范只定義了exports, 而 module.exports 是nodejs對commonjs的實現, 這種擴展實現稱為commonjs2。
// commonjs
exports.a = 'a';
exports.b = 'b';
// commonjs2
module.exports = {
a : 'a',
b : 'b'
};
build/config.js
文件內容是打包配置的公用配置。

外部擴展(externals) 從輸出的 bundle 中排除依賴,在運行時(runtime)從外部獲取這些擴展依賴(external dependencies),主要解決組件依賴導致代碼冗余問題。其中 exports.externals = externals; 內容格式如下 👇。

build/webpack.common.js
以 commonjs2 規范打包構建類庫。
- 調用命令:
webpack --config build/webpack.common.js。 - 入口文件:
src/index.js。 - 輸出文件:以
commonjs2規范構建輸出到lib/element-ui.common.js(類庫主入口文件)。

build/webpack.component.js
以 commonjs2 規范對每個組件單獨打包構建,支持按需引入。
- 調用命令:
webpack --config build/webpack.component.js。 - 入口文件:
components.json中的組件列表。 - 輸出文件:把
packages目錄下的組件,以commonjs2規范單獨構建輸出到lib/components-name.js。

build/webpack.conf.js
以 umd 規范打包構建類庫,不僅可以 NodeJs 環境使用,也可以在瀏覽器環境(browser)使用,需要設置umdNamedDefine: true。
- 調用命令:
webpack --config build/webpack.conf.js。 - 入口文件:
src/index.js。 - 輸出文件:以
umd規范構建輸出到lib/index.js。

externals 配置
通過這種方式引入的依賴庫,不會打包到 bundle 中。以下任何一種形式在各種模塊上下文使用:
root:可以通過一個全局變量訪問 library(例如,通過 script 標簽)。commonjs:可以將 library 作為一個 CommonJS 模塊訪問。commonjs2:和上面的類似,但導出的是 module.exports.default。amd:類似於 commonjs,但使用 AMD 模塊系統。
一個形如 { root, amd, commonjs, ... } 的對象僅允許用 libraryTarget: 'umd' 這樣的配置.
// 防止將某些 import 的包(package)打包到 bundle 中,
// 在運行時(runtime)再去從外部獲取這些擴展依賴
externals: {
// config.vue
// {
// root: 'Vue',
// commonjs: 'vue',
// commonjs2: 'vue',
// amd: 'vue'
// }
vue: config.vue
},
生成lib\index.js中,依賴庫vue引入聲明代碼如下:
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("vue"));
else if(typeof define === 'function' && define.amd)
define("ELEMENT", ["vue"], factory);
else if(typeof exports === 'object')
exports["ELEMENT"] = factory(require("vue"));
else
root["ELEMENT"] = factory(root["Vue"]);
})
build/webpack.demo.js
提供了兩套打包配置,生產模式用於項目網站的構建,開發模式用於組件展示測試的構建。使用了CSS、JS構建的優化插件,還配置 splitChunks抽取公共模塊解決重復引入第三方庫的問題。
npm run deploy:build 命令打包構建項目網站。
- 調用命令:
webpack --config build/webpack.demo.js。 - 模式:
production。 - 入口文件:
examples/entry.js。 - 輸出文件:構建內容輸出至
examples/element-ui/目錄下。
npm run deploy:build 命令打包運行項目網站,用於開發調試。
- 調用命令:
webpack-dev-server --config build/webpack.demo.js。 - 模式:
development。 - 入口文件:
examples/entry.js。 - 輸出文件:構建內容輸出至
examples/element-ui/目錄下。
npm run dev:play 命令用於組件庫開發中的功能展示。
- 調用命令:
webpack-dev-server --config build/webpack.demo.js。 - 模式:
development。 - 入口文件:
examples/entry.js。 - 輸出文件:構建內容輸出至
examples/element-ui/目錄下。

build/webpack.extension.js
用於構建名為Element Theme Roller的 chorme 插件項目,復用大部分 webpack.demo.js 打包配置。npm run deploy:extension用於項目生產發布;npm run dev:extension用於開發調試。
- 調用命令:
webpack --config build/webpack.extension.js。 - 入口文件:
examples/extension/src/background.js和examples/extension/src/entry.js。 - 輸出文件:構建內容輸出至
examples/extension/dist目錄下。生成文件background.jsentry.js,復制文件icon.pngmanifest.json。

🚧 build/webpack.test.js
項目未使用此打包配置,入口src/index.js,打包構建文件dist/app.js,具體作用未知。
0x.02 🔖 鏈接匯總
點擊以下鏈接,可以快速查看本系列其他文章:
