2016-01-27 71 views
4

通常供應商模塊,具有靜態需要或進口(CommonJS的/ ES進口),的WebPack可以要求任何模塊從/ node_modules /,例如:動態需要具有的WebPack

var vendorModule = require('vendor-module'); 

但是我要動態地加載從模塊/ node_modules /像:

var vendorModuleId = 'vendor-module'; 

... 

var vendorModule = require(vendorModuleId); 

這不起作用,因爲的WebPack不能確定在編譯時的依賴,這顯然是瘋了包括所有的/ node_modules /束中的以防萬一,我們可能要動態加載一些供應商模塊。

我正在尋找一種方式來的WebPack誘騙解決這些模塊動態。優選地,通過webpack配置文件告訴webpack包中的哪些模塊應該包含在/ node_modules /中。

有人說ContextReplacementPlugin可以用於這些情況,但我無法理解如何。

任何人有任何想法如何做到這一點?提前致謝!

+0

創建軟件包後 - 你需要在其中包含這些模塊?或者如果需要,您需要延遲加載這些模塊? –

+0

懶惰的負載將作爲一個選項很好,但不是必需的 – martijnboland

回答

3

您可以通過加載器爲導入和導出需要的模塊創建一個文件。

  1. 創建一個空文件「./vendors.js」;
  2. npm install exports-loader imports-loader --save-dev
  3. webpack.config.js

    // config needed vendor modules 
    var vendorModules = [ 
        'one', 'two', 'three', 'vendor-module' 
    ]; 
    
    ... 
    
    module.exports = { 
    ... 
        loaders: [{ // Add loader 
         include: require.resolve('./vendors.js'), 
         loader: 'imports-loader?' + vendorsModules.map(function(module, index) { 
          return 'dep' + index + '=' + module; 
         }).join(',') + '!exports-loader?' + vendorsModules.map(function(module, index) { 
          return module + '=dep' + index; 
         }).join(',') 
        },...] 
        ... 
    } 
    
  4. 在模塊,你需要要求供應商:

    // import * as vendorsModules from './vendors'; 
    var vendorsModules = require('./vendors'); 
    
    var vendorModuleId = 'vendor-module'; 
    ... 
    var vendorModule = vendorsModules[vendorModuleId]; 
    console.log('module', vendorModule); 
    

這將增加了配置廠商捆綁軟件。如果您需要延遲加載這些模塊,則需要使用require.resolve和承諾類接口來獲取所需的模塊,以執行更復雜的模塊工廠。

+0

有趣的方法,謝謝!我還注意到有一個新的選項添加到ContextReplacementPlugin中,它接受預定義的地圖。這兩個選項值得檢查。 – martijnboland

+0

@martijnboland我想是的 - https://github.com/webpack/docs/wiki/context。如果我在你面前檢查解決方案,我會編輯答案 –

0

您可以參考使用動態dynamic loading模塊路徑:

// module.js 
export default { 
    init:() => console.log('module.init'), 
}; 

// index.js 
const id = 'module'; 
import(`./${id}.js`).then(obj => obj.default.init());