2016-01-27 21 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());