從範例看 Webpack 加載(一):common chunk and vendor chunk

前端天天都在 Webpack,究竟它是怎麼 pack 的?而且又是怎麼在 Browser 上運行的呢?

Tony Pai
4 min readSep 18, 2017

本篇使用官方範例 common-chunk-and-vendor-chunk

建議搭配 編譯後的代碼 一同觀看

事前準備

連接 package、安裝相依套件後,執行指令 build 所有範例檔。

yarn link && yarn link webpack
yarn && yarn build:examples

範例說明

可分為下列三個項目:

  • 設定檔
  • 檔案結構
  • 代碼簡述

設定檔

webpack.config.js 可以對 Webpack 的打包行為依據不同的情境做設定。

entry: {
vendor: ["./vendor1", "./vendor2"],
pageA: "./pageA",
pageB: "./pageB",
pageC: "./pageC"
},
plugins: [
new CommonsChunkPlugin({
names: ["common", "vendor"],
minChunks: 2
})
]

本設定檔的目的是,從除了指定放入 vendor 以外的所有 Chunk 中找出被重複引入兩次以上的 Module,並將其分離至 common。

檔案結構

打包後會產出設定檔所指定的 common 以及 vendor 檔,還有三個 Entry Points 分別是 pageA、pageB 和 pageC。

.
`-common.js
`-pageA.js
`-pageB.js
`-pageC.js
`-vendor.js

在本範例中 require 了 utility1、utility2 和 utility3 三個 Module,utility2 和 utility3 分別被 pageB 和 pageC require 了兩次,所以被放到了 common.js Chunk。而 utility1 未達標準,則被放在原引用處 pageA Chunk 當中。

代碼簡述

打包後的 JS 是以 Chunk 為單位,須先加載 Chunk 然後將 Module 載入記憶體中後方能被取用。

以下為本範例的相關代碼:

vendor.js 中的部分代碼

webpackJsonp(chunkIds, moreModules, executeModules)

用於加載 Chunk 及 Module 的函數。

流程簡述:

  1. installedChunks[chunkId] 為 0 表示 Chunk 已加載完成。
  2. moreModules 中的 key/value 塞入對應的 modules 陣列。
  3. 加載 executeModules 中的 Module 並執行。

installedModules

存放加載後的 Module。

var installedModules = {
[moduleId]: {
i: moduleId, // module Id
l: false, // isLoaded flag
exports: {} // module function
}
};

installedChunks

存放加載後的 Chunk。

var installedChunks = {
[chunkId]: 0 // 0: 已加載, [resolve, reject]: 待加載
};

P.S. resolve, reject 在動態載入 Chunk 時會進一步介紹。

__webpack_require__(moduleId)

將欲載入的 Module 於 installedModules 中初始化後並執行,於最後回傳函數。

執行簡述:

  1. 如果 installedModules[moduleId] 已存在則立即回傳。
  2. 若否則初始化。
  3. 執行 Module 並標記為已加載後回傳。(module.l = true

__webpack_require__.s

存放 Entry Module 的 Module Id。

結語

本篇介紹了基本的 Chunk 及 Module 加載(靜態),之後會進一步介紹動態加載。最後,無論是在文章中有看到不合理或者可以改進的地方,都可以在下方留言交流。

參考連結

--

--