如果對webpackJsonp
、installedModules
、installedChunks
、__webpack_require__
和 還沒有概念的建議先閱讀《從範例看 Webpack 加載(一):common chunk and vendor chunk》瞭解基本的 chunk 和 module 加載之後再往下看會比較容易理解。
範例說明
可分為下列兩個項目:
- 檔案結構
- 代碼簡述
檔案結構
由於本範例沒有定義 webpack.config.js
,所以打包行為是基於 examples/build-common.js
的設定去執行。
webpack \
--display-reasons \
--display-used-exports \
--display-provided-exports \
--display-reasons \
--display-used-exports \
--display-provided-exports \
--display-chunks \
--display-max-modules 99999 \
--display-origins \
--display-entrypoints \
--output-public-path "js/" \
./example.js js/output.js
本範例用了兩種方式去 import module,第一種是 return Promise 的方式,第二種是使用 dynamic expression 定義 module 名稱然後 import(這種做法稱為 async context),兩種方式都會額外切出 chunk。
.
`-0.output.js
`-1.output.js
`-2.output.js
`-output.js
在本範例中 import 了 a、b、c/1 和 c/2 四個 Module,c/1 和 c/2 使用 async context 的方式 import,分別被放到 1.output.js 和 0.output.js。b 則是用 return Promise 的方式 import,被獨立放到 2.output.js。a 是一般的 import,所以放在 output.js。
代碼簡述
以下為 Webpack 用來實作靜態加載和動態加載的相關代碼:
ES5 Modules: CommonJS Modules
ES6 Modules: Harmony Modules
__webpack_require__.e = function requireEnsure(chunkId)
用 createElement
的方式將 Chunk 以 <script>
嵌入至 <head>
,若超過 12 秒未完成加載則 timeout 並 reject error。
__webpack_require__.d(exports, name, getter)
於 __webpack_require__.n
中作用,為 Harmony Module 定義 getter function 並讓其符合 Spec Mode 且相容 CommonJS。
__webpack_require__.n(module)
取得 default export 並回傳。
__webpack_require__.o(object, property)
於 __webpack_require__.d
中作用,確認 property 是否存在於 object。
map
指定為動態加載的 Modules 會將 moduleId
和 chunkId
紀錄在 map 變數之中。
var map = {
`./${module_name}`: [moduleId, chunkId],
`./${module_name}.js`: [moduleId, chunkId]
};
webpackAsyncContext(req)
函數會判斷 map
中是否有 req
所請求的 Module,若有則透過 __webpack_require__.e
先將 Chunk 加載完畢後再行載入 Module,反之則 reject error。
結語
這次介紹了靜態加載與動態加載的差別,下次會介紹 Plugin 是怎麼影響打包行為的。最後,無論是在文章中有看到不合理或者可以改進的地方,都可以在下方留言交流。