08.ElementUI 2.X 源碼學習:源碼剖析之工程化(三)
- 2021 年 6 月 8 日
- 筆記
- 0x02.FrontEnd, element
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.js
entry.js
,複製文件icon.png
manifest.json
。
🚧 build/webpack.test.js
項目未使用此打包配置,入口src/index.js
,打包構建文件dist/app.js
,具體作用未知。
0x.02 🔖 鏈接匯總
點擊以下鏈接,可以快速查看本系列其他文章:
0x.03 📚 參考
//webpack.docschina.org/configuration/