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

Anduril發表於2021-06-08

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'
};

參考https://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 ? 參考

https://webpack.docschina.org/configuration/

相關文章