使用webpack动态要求供应商模块

时间:2016-01-27 23:01:06

标签: webpack

通常,使用静态需求或导入(CommonJS / ES导入),webpack可以要求/ node_modules /中的任何模块,例如:

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

但我想从/ node_modules / like中动态加载模块:

var vendorModuleId = 'vendor-module';

...

var vendorModule = require(vendorModuleId);

这不起作用,因为webpack无法在编译时确定依赖关系,并且在我们可能想要动态加载的情况下将所有/ node_modules /包括在捆绑包中显然是疯了一些供应商模块。

我正在寻找一种方法来欺骗webpack动态解析这些模块 。最好通过webpack配置文件告诉webpack / node_modules /中的哪些模块应该包含在bundle中。

有些人说ContextReplacementPlugin对这些情况很有用,但我无法理解。

任何人都知道如何做到这一点?提前谢谢!

3 个答案:

答案 0 :(得分: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);
    
  5. 它会将已配置的供应商添加到您的捆绑包中。如果您需要延迟加载这些模块,您需要使用require.resolve和类似承诺的接口来创建更复杂的模块,以获取所需的模块。

答案 1 :(得分:1)

Webpack now supports dynamic loading,例如:

// js
const _ = await import(/* webpackChunkName: "lodash" */ 'lodash')

// webpack.config.js
output: {
  filename: '[name].bundle.js',
  chunkFilename: '[name].bundle.js',
  path: path.resolve(__dirname, 'dist')
},

该代码段假设您也有Syntax Dynamic Import Babel Plugin

答案 2 :(得分: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());