webpack
是一個預編譯模塊打包工具,它只會對使用到的模塊進行打包。
一個模塊是否被使用?可以根據該模塊是否被 require
來判斷。如果require時指定的是具體的模塊名稱與正確的路徑,那么 webpack
便可以在編譯打包時正確的引用到該模塊。
require('tools'); //preset alias tools
require('./js/main');
如果 require的只是一個表達式(即需要運算才能得到結果),對於 webpack而言結果就不會精確了。
require('./img/' + name + '.jpg');
由變量 name
結合常量 ./img/
與 .jpg
等構成的一個表達式,其最終的結果是需要執行才會得知的,但是 webpack本身又是一個預編譯的打包工具,因此這里 webpack並不知道你最終會打包那個模塊,所以在打包時就需要自己分析並提取出如下的關鍵信息:
- directory : ./img
- Regular expression : /^.*.jpg$/
當你在請求一個含有表達式的模塊時,webpack並不能預先精准匹配到要打包的模塊,所以它會自動創建一個上下文語句,這個上下文的起點就時你當前 require所處的 JS文件,然后根據你指定的目錄與要匹配的模塊類型(擴展名)來生成一個正則表達式,然后在根據這個正則匹配
將指定目錄下的所有符合匹配條件的模塊都打包進來。
由此我們可以說明 webpack可以通過require進行動態模塊加載,但是會將指定匹配目錄下的所有符合條件的模塊都打包進來。
另外上下文語句還包含了一個將模塊加載翻譯成對應模塊id的字典。以上例為例的話,它就類似於:
’./img/webpack.jpg‘ : 42,
'./img/nodejs.jpg':43,
'./img/express.jpg' :44
當然,你也可以手動創建一個上下文語句,通過手動創建上下文,你可以自定義一個模塊打包范圍。
首先,通過 require.context
來創建上下文,它接受三個參數,分別是“指定要打包的目錄”,“是否搜尋子目錄”,“匹配的正則”。
同樣的,上下文的起點就是當前的JS文件。
var context = require.context('../img',false,/^.*\.jpg/);
console.log(context.keys()); //拿到匹配的到模塊Map表。
console.log(context('./webpack.jpg'));//拿到最終打包好的模塊。
總結:不論是自動創建上下文語句還是手動創建上下文語句,上下文語句本身就有不容忽視的作用,因為它可以在 webpack打包的默認流程中加入你自己額外定制的流程。