使用Webpack的DefinePlugin动态要求多个文件?

时间:2019-02-07 08:15:20

标签: javascript webpack

我有一个要导入的文件名数组。文件名是在构建时计算的。如果我只有一个文件名,则可以:

new webpack.DefinePlugin({
  component_file: '"path/Component"',
})

然后在源代码中

require(component_file);

按预期,其中包括path/Component

但是,如果我尝试以下操作,它将无法正常工作。

new webpack.DefinePlugin({
  component_files: ['"path/Component"', '"path/Component2"'],
})

然后在源代码中

// component_files is converted object by Webpack.
Object.keys(component_files).forEach(file => require(file));

这将导致错误Cannot find module '0'。这是有道理的,因为Webpack只是进行静态分析,因此无法处理以变量作为参数的require。可以做我想做的事吗?

2 个答案:

答案 0 :(得分:0)

您可以使用它们作为配置中的条目,而不是使用DefinePlugin定义应用程序中所需的依赖关系,以便在编译时将它们包括在内:

{
  entry: [
    ...component_files,
    'app.js'
  ]
}

答案 1 :(得分:0)

要通过环境变量实现动态捆绑,您必须将require语句包装在条件块中,条件块将被确定为“死代码”。
然后,在构建时,这些无效的require语句将被删除,这将导致最终包中的排除。

每个条件块的谓词必须在构建时评估为布尔值。仅当谓词是2个原始值或纯布尔值之间的简单比较时,才会发生这种情况。例如:

// webpack.config.json
new DefinePlugin({
  "process.env.component_a": "true",
  "process.env.component_b": "false",
  "process.env.component_c": "'true'",
})

// in application:
if (process.env.component_a) {
  const a = require('./a') // will be included
}
if (process.env.component_b) {
  const b = require('./b') // will be excluded
}

if (process.env.component_c === "true") {
  const c = require('./c') // will be included
}

重要提示
保留未定义的值不足以将模块从最终捆绑包中排除。

/* THE WRONG WAY */

// webpack.config.json
new DefinePlugin({
  "process.env.component_a": "true",

})

// in application:
if (process.env.component_a) {
  const a = require('./a') // will be included
}
if (process.env.component_b) {
  // even though this block is unreachable, b will be included in the bundle!
  const b = require('./b') 
}