08.ElementUI 2.X 源碼學習:源碼剖析之工程化(三)

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.exportsnodejscommonjs的實現, 這種擴展實現稱為commonjs2

// commonjs
exports.a = 'a';
exports.b = 'b';

// commonjs2
module.exports = {
    a : 'a',
    b : 'b'
};

參考//github.com/webpack/webpack/issues/1114

build/config.js

文件內容是打包配置的公用配置。

carbon (40).png

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

carbon (41).png

build/webpack.common.js

commonjs2 規範打包構建類庫。

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

image.png

build/webpack.component.js

commonjs2 規範對每個組件單獨打包構建,支援按需引入。

  • 調用命令:webpack --config build/webpack.component.js
  • 入口文件:components.json中的組件列表。
  • 輸出文件:把packages目錄下的組件,以commonjs2規範單獨構建輸出到lib/components-name.js

image.png

build/webpack.conf.js

umd 規範打包構建類庫,不僅可以 NodeJs 環境使用,也可以在瀏覽器環境(browser)使用,需要設置umdNamedDefine: true

  • 調用命令:webpack --config build/webpack.conf.js
  • 入口文件:src/index.js
  • 輸出文件:以umd規範構建輸出到lib/index.js

image.png

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/目錄下。

carbon (37).png

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.jsexamples/extension/src/entry.js
  • 輸出文件:構建內容輸出至examples/extension/dist目錄下。生成文件 background.js entry.js ,複製文件 icon.png manifest.json

image.png

🚧 build/webpack.test.js

項目未使用此打包配置,入口src/index.js,打包構建文件dist/app.js,具體作用未知。

0x.02 🔖 鏈接匯總

點擊以下鏈接,可以快速查看本系列其他文章:

ElementUI源碼學習:從零開始搭建Vue組件庫匯總

0x.03 📚 參考

//webpack.docschina.org/configuration/