webpack動態匯入和require.context分析及注意事項
實驗webpack版本
4.19.0
tldr;
-
動態匯入語法必須是字串拼接,不能傳入函式。
正確:import('./src' + args + '.index') 錯誤:import(someFn())
-
動態匯入變數必須以
./
或者webpack設定的alias
開始進行字串拼接。import('./src' + args + '/index.js') 或 import('Src/' + args + '/index.js') Src是一個alias地址
-
import('./src' + args + '/index.js')
動態匯入中的args變數在打包階段只是一個佔位符的作用,等價於查詢./src/*/index.js中 -
require.context(目錄,是否遞迴搜尋,篩選器)
引數只有靜態常量有效
動態匯入import和require.context的基本概念
作用於兩個階段
- 打包編譯時候進行詞法分析,決定哪些檔案要打包,拆分還是合併。
- 程式執行時使用第一階段打好的模組。
在編譯階段都會打包非註釋部分
不管程式裡有沒有實際呼叫了動態匯入或require.context部分的程式碼,只要這部分程式碼 被webpack發現,只要不被註釋,webpack都會按照語法執行打包。因為這是編譯階段語法分析的結果。
動態匯入
import('./src' + args + '/index.js')
遇到import是變數拼接的語法,就會把匹配的檔案分別作為一個獨立chunk進行打包。
編譯階段
- 根據語法拆分多個獨立包
- 變數只是類似佔位符的作用
打包過程發生在編譯階段,webpack看不懂類似import(someFunction())
這種語法,因為在編譯階段不知道someFunction()是什麼,
webpack只認識這種語法import('./app' + xx + '/store/index.js')
,webpack的理解就是
把變數替換成佔位符,把匹配這個模式./app/*/store/index.js
的檔案分別打成chunk,然後程式執行的時候,再根據變數生成的路徑,匹配對應chunk塊。
- 有效的變數拼接開頭
-
以webpack配置的alias開頭
alias: { Root: 'e:/xx', } import('Root/' + args + 'index.js) 複製程式碼
-
以./開頭的語法
import('Root/' + args + 'index.js)
-
諸如
../
和絕對路徑
開頭都無效。
-
require.context
語法require.context(目錄,是否遞迴目錄, 檔案篩選條件)
所有引數必須是直接字串,變數無效。
會在目錄裡進行遞迴或非遞迴的按照篩選條件篩選,把符合條件的檔案單獨打包成一個檔案。 形如:
var map = {
"./game/index.js": "./src/domain/game/index.js",
"./index.js": "./src/domain/index.js"
};
function webpackContext(req) {
var id = webpackContextResolve(req);
return __webpack_require__(id);
}
function webpackContextResolve(req) {
var id = map[req];
if(!(id + 1)) { // check for number or string
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
return id;
}
webpackContext.keys = function webpackContextKeys() {
return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "./src/domain sync recursive \\/index\\.js$";
複製程式碼