webpack動態匯入和require.context分析及使用注意

奔跑愛學習發表於2018-09-22

webpack動態匯入和require.context分析及注意事項

實驗webpack版本

4.19.0

tldr;

  1. 動態匯入語法必須是字串拼接,不能傳入函式。

    正確:import('./src' + args + '.index') 錯誤:import(someFn())

  2. 動態匯入變數必須以./ 或者webpack設定的alias開始進行字串拼接。

    import('./src' + args + '/index.js') 或 import('Src/' + args + '/index.js') Src是一個alias地址

  3. import('./src' + args + '/index.js')動態匯入中的args變數在打包階段只是一個佔位符的作用,等價於查詢./src/*/index.js中

  4. require.context(目錄,是否遞迴搜尋,篩選器)引數只有靜態常量有效

動態匯入import和require.context的基本概念

作用於兩個階段

  1. 打包編譯時候進行詞法分析,決定哪些檔案要打包,拆分還是合併。
  2. 程式執行時使用第一階段打好的模組。

在編譯階段都會打包非註釋部分

不管程式裡有沒有實際呼叫了動態匯入或require.context部分的程式碼,只要這部分程式碼 被webpack發現,只要不被註釋,webpack都會按照語法執行打包。因為這是編譯階段語法分析的結果。

動態匯入

import('./src' + args + '/index.js') 遇到import是變數拼接的語法,就會把匹配的檔案分別作為一個獨立chunk進行打包。

編譯階段

  1. 根據語法拆分多個獨立包
  2. 變數只是類似佔位符的作用

打包過程發生在編譯階段,webpack看不懂類似import(someFunction())這種語法,因為在編譯階段不知道someFunction()是什麼, webpack只認識這種語法import('./app' + xx + '/store/index.js'),webpack的理解就是 把變數替換成佔位符,把匹配這個模式./app/*/store/index.js的檔案分別打成chunk,然後程式執行的時候,再根據變數生成的路徑,匹配對應chunk塊。

  1. 有效的變數拼接開頭
    1. 以webpack配置的alias開頭

       alias: {
           Root: 'e:/xx',
       }
       import('Root/' + args + 'index.js)
      複製程式碼
    2. 以./開頭的語法 import('Root/' + args + 'index.js)

    3. 諸如../絕對路徑開頭都無效。

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$";
複製程式碼

相關文章