Webpack 需要外部表达式
Webpack require expression external
我有一个表达式 require 应该在运行时得到解决,但我无法理解这个简单示例的 webpack 配置:
import something from 'module';
import pkg from './package.json';
let a;
if (pkg.main) {
a = require(pkg.main);
}
生成的构建应包含 module
,但在运行时还需要 ./package.json
和 pkg.main
作为 commonjs 模块——换句话说,将它们从构建中排除。
我的 webpack.config.js
到目前为止:
var webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
filename: '[name].js',
path: './build'
},
target: 'node-webkit',
plugins: [
new webpack.ExternalsPlugin('commonjs', './package.json')
],
module: {
noParse: /\.min\.js/,
exprContextRegExp: /$^/,
exprContextCritical: false,
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
}
]
}
};
现在发生的是 pkg.main
的要求导致 webpackMissingModule
异常,如果我删除 exprContextRegExp
,要求将使用上下文。
感谢您的帮助
对于任何想知道的人:你可以用这个插件解决它:
function() {
this.parser.plugin('call require', function(expr) {
if (expr.arguments.length !== 1) {
return;
}
const param = this.evaluateExpression(expr.arguments[0]);
if (!param.isString() && !param.isConditional()) {
return true;
}
});
}
webpack 无法解决的问题将保留原样。
更新:使用 NPM 包
安装它:yarn add webpack-ignore-dynamic-require
启用它
// webpack.config.js
const IgnoreDynamicRequire = require('webpack-ignore-dynamic-require');
module.exports = {
// ...
plugins: [
new IgnoreDynamicRequire()
]
}
原答案:自制
为了捆绑服务器应用程序,我需要它,因为它使用 require
加载本地 JSON 文件。
基于,我能够为 Webpack 4 创建一个插件。它可能适用于 Webpack 5。
class IgnoreDynamicRequire {
apply(compiler) {
compiler.hooks.normalModuleFactory.tap('IgnoreDynamicRequire', factory => {
factory.hooks.parser.for('javascript/auto').tap('IgnoreDynamicRequire', (parser, options) => {
parser.hooks.call.for('require').tap('IgnoreDynamicRequire', expression => {
// This is a SyncBailHook, so returning anything stops the parser, and nothing allows to continue
if (expression.arguments.length !== 1 || expression.arguments[0].type === 'Literal') {
return
}
const arg = parser.evaluateExpression(expression.arguments[0])
if (!arg.isString() && !arg.isConditional()) {
return true;
}
});
});
});
}
}
这比之前的答案复杂得多,但我们需要访问 parser
object。之后,只需将其包含在您的 plugins
数组中:
plugins: [
new IgnoreDynamicRequire()
]
所有未解析为字符串的 require
调用均保持原样。
我有一个表达式 require 应该在运行时得到解决,但我无法理解这个简单示例的 webpack 配置:
import something from 'module';
import pkg from './package.json';
let a;
if (pkg.main) {
a = require(pkg.main);
}
生成的构建应包含 module
,但在运行时还需要 ./package.json
和 pkg.main
作为 commonjs 模块——换句话说,将它们从构建中排除。
我的 webpack.config.js
到目前为止:
var webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
filename: '[name].js',
path: './build'
},
target: 'node-webkit',
plugins: [
new webpack.ExternalsPlugin('commonjs', './package.json')
],
module: {
noParse: /\.min\.js/,
exprContextRegExp: /$^/,
exprContextCritical: false,
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
}
]
}
};
现在发生的是 pkg.main
的要求导致 webpackMissingModule
异常,如果我删除 exprContextRegExp
,要求将使用上下文。
感谢您的帮助
对于任何想知道的人:你可以用这个插件解决它:
function() {
this.parser.plugin('call require', function(expr) {
if (expr.arguments.length !== 1) {
return;
}
const param = this.evaluateExpression(expr.arguments[0]);
if (!param.isString() && !param.isConditional()) {
return true;
}
});
}
webpack 无法解决的问题将保留原样。
更新:使用 NPM 包
安装它:yarn add webpack-ignore-dynamic-require
启用它
// webpack.config.js
const IgnoreDynamicRequire = require('webpack-ignore-dynamic-require');
module.exports = {
// ...
plugins: [
new IgnoreDynamicRequire()
]
}
原答案:自制
为了捆绑服务器应用程序,我需要它,因为它使用 require
加载本地 JSON 文件。
基于
class IgnoreDynamicRequire {
apply(compiler) {
compiler.hooks.normalModuleFactory.tap('IgnoreDynamicRequire', factory => {
factory.hooks.parser.for('javascript/auto').tap('IgnoreDynamicRequire', (parser, options) => {
parser.hooks.call.for('require').tap('IgnoreDynamicRequire', expression => {
// This is a SyncBailHook, so returning anything stops the parser, and nothing allows to continue
if (expression.arguments.length !== 1 || expression.arguments[0].type === 'Literal') {
return
}
const arg = parser.evaluateExpression(expression.arguments[0])
if (!arg.isString() && !arg.isConditional()) {
return true;
}
});
});
});
}
}
这比之前的答案复杂得多,但我们需要访问 parser
object。之后,只需将其包含在您的 plugins
数组中:
plugins: [
new IgnoreDynamicRequire()
]
所有未解析为字符串的 require
调用均保持原样。