從範例看 Webpack 加載(一):common chunk and vendor chunk
本篇使用官方範例 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 載入記憶體中後方能被取用。
以下為本範例的相關代碼:
webpackJsonp(chunkIds, moreModules, executeModules)
用於加載 Chunk 及 Module 的函數。
流程簡述:
installedChunks[chunkId]
為 0 表示 Chunk 已加載完成。- 將
moreModules
中的 key/value 塞入對應的modules
陣列。 - 加載
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
中初始化後並執行,於最後回傳函數。
執行簡述:
- 如果
installedModules[moduleId]
已存在則立即回傳。 - 若否則初始化。
- 執行 Module 並標記為已加載後回傳。(
module.l = true
)
__webpack_require__.s
存放 Entry Module 的 Module Id。
結語
本篇介紹了基本的 Chunk 及 Module 加載(靜態),之後會進一步介紹動態加載。最後,無論是在文章中有看到不合理或者可以改進的地方,都可以在下方留言交流。