1. 程式人生 > >webpack中imports-loader,exports-loader,expose-loader的區別

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');。這樣引用的結果是變數helloundefined。因為我們在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模組的檔案裡匯出到全域性變數的例子,有興趣的同學點選這裡