webpack中imports-loader,exports-loader,expose-loader的區別
3
Webpack有幾個和模組化相關的loader,imports-loader
,exports-loader
,expose-loader
,比較容易混淆。今天,我們來理一理。
imports-loaders
文件介紹的是:用於向一個模組的作用域內注入變數(Can be used to inject variables into the scope of a module.),官方的文件總是言簡意賅但是不太好懂。我們來舉個例子。
例子完整的程式碼可以點這裡jqGreen.js
檔案裡僅一行程式碼
//沒有模組化
$('#box' ).css('color','green');
index.js
檔案也只有一行程式碼
require('./jqGreen');
我們的配置檔案中,是把index.js
作為入口檔案的。
{
entry:{
index:'./src/js/index.js'
}
}
注意,我們並沒有引入jquery
。所以執行的結果是$ is not defined
。
但是如果我們稍微修改一下jqGreen
的引入方式,就能很輕鬆的解決這個問題。index.js
檔案
require('imports?$=jquery!./jqGreen');
當然,這個能執行之前,我們要npm install imports-loader
$
注入進模組jqGreen.js
。同時,我們指定了變數$=jquery
。等於是在jqGreen.js
檔案的最頂上,加上了var $=require('jquery')
。這樣,程式就不會報$ is not defined
的錯誤了。
exports-loader
exports有匯出
的意思,這讓我們猜測它有從模組中匯出變數的功能。實際情況大致如此。我們來看個小例子。
例子的完整程式碼在 這裡Hello.js
檔案中僅有一個方法,直接繫結在全域性變數window
上面。
window.Hello = function(){
console.log('say hello.' );
}
然後我們在index.js
檔案裡去引用這個Hello.js
:var hello = require('./Hello.js');
。這樣引用的結果是變數hello
是undefined
。因為我們在Hello.js
檔案裡沒有寫module.exports=window.Hello
,所以index.js
裡我們require
的結果就是undefined
。這個時候,exports-loader
就派上用場了。我們只用把index.js
的程式碼稍微改動一下:var hello = require('exports-loader?window.Hello!./Hello.js');
,這個時候,程式碼就能正確的運行了。變數hello
就是我們定義的window.hello
啦。var hello = require('exports-loader?window.Hello!./Hello.js');
這行程式碼,等於在Hello.js
里加上一句module.exports=window.Hello
,所以我們才能正確的匯入。
expose-loader
把一個模組匯出並付給一個全域性變數。文件裡給了一個例子:
require("expose?libraryName!./file.js");
// Exposes the exports for file.js to the global context on property "libraryName".
// In web browsers, window.libraryName is then available.
例子中的註釋是說把file.js中exports出來的變數付給全域性變數"libraryName"
。假如file.js
中有程式碼module.exports=1
,那麼require("expose?libraryName!./file.js")
後window.libraryName
的值就為1(我們這裡只討論瀏覽器環境)。
我這裡還有一個稍稍複雜點的從一個umd模組的檔案裡匯出到全域性變數的例子,有興趣的同學點選這裡。