[英]Webpack: How can we *conditionally* use a plugin?
在 Webpack 中,我有以下插件:
plugins: [
new ExtractTextPlugin('styles.css'),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
drop_console: true,
}),
]
我只想将UglifyJsPlugin
应用于特定目标,所以我尝试使用我想要的条件:
plugins: [
new ExtractTextPlugin('styles.css'),
(TARGET === 'build') && new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
drop_console: true,
}),
]
但是,这失败了,显示以下错误消息:
E:\myProject\node_modules\tapable\lib\Tapable.js:164
arguments[i].apply(this);
^
TypeError: arguments[i].apply is not a function
请注意,上面的代码类似于在plugins
数组末尾设置false
(发出相同的错误):
plugins: [
new ExtractTextPlugin('styles.css'),
false
]
所以,问题是:有没有办法在 Webpack 上使用条件插件? (除了使用变量?)
您可以使用这种使用扩展运算符的语法
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css'
}),
...(prod ? [] : [new BundleAnalyzerPlugin()])
],
我在webpack.config.js
给定条件推送到 plugins 数组
const webpack = require('webpack');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: {
...
},
output: {
...
},
module: {
rules: [
...
]
},
plugins: [
new ExtractTextPlugin('styles.css'),
]
};
if (TARGET === 'build') {
module.exports.plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
drop_console: true,
}),
);
}
如果没有变量,它将如下所示:
plugins: [
new ExtractTextPlugin('styles.css'),
(TARGET === 'build') && new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
drop_console: true,
}),
].filter(function(plugin) { return plugin !== false; })
我认为最干净的方法是设置多个构建。 如果您的webpack.config.js
导出一组配置对象而不是单个对象,则 webpack 将自动为每个对象进行构建。 我有几个不同的构建,所以我将共享配置定义为变量,循环遍历构建之间不同的因素,并在循环内使用条件来检查它是哪个构建。 例如:
let allConfigs = [];
let buildTypes = ['dev', 'optimized'];
buildTypes.forEach( (type) => {
let buildConfig = {};
// ... other config
buildConfig.plugins = [];
if (type === 'optimized') {
// add Uglify to plugins array
}
// ...other config
allConfigs.push(buildConfig);
});
plugins: [
new ExtractTextPlugin('styles.css'),
(TARGET === 'build') && new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
drop_console: true,
}),
].filter(Boolean)
你可以有一个 webpack 配置,建立在另一个之上,并在后一个中添加一些插件(和/或更改输出名称等):
这个webpack.release.config.js使用了webpack.config (开发版),但是使用了更多的插件......
process.env.NODE_ENV = 'release';
const config = require('./webpack.config'),
webpack = require('webpack');
config.output.filename = 'app.min.js';
// use another plugin, compare to the basic version ←←←
config.plugins.push(new webpack.optimize.UglifyJsPlugin({
minimize: true
}));
module.exports = config;
另请参阅此处以获取完整示例。
您可以在 webpack 中使用mode参数将development
/ production
值传递给 webpack 配置,然后有条件地加载插件。
NPM 脚本:
"start": "webpack --watch --mode=development",
"build": "webpack --mode=production",
webpack.config.js:
module.exports = (env, argv) => {
console.log("mode: ", argv.mode);
const isDev = argv.mode === "development";
const pluginsArr = [new CleanWebpackPlugin()];
// load plugin only in development mode
if (isDev) {
pluginsArr.push(new ExtensionReloader({}));
}
return {
entry: {},
devtool: isDev ? "inline-source-map" : "", // generate source code only in development mode
plugins: pluginsArr,
output: {},
};
};
可以使用noop-webpack-plugin (noop 表示不操作):
const isProd = process.env.NODE_ENV === 'production';
const noop = require('noop-webpack-plugin');
// ...
plugins: [
isProd ? new Plugin() : noop(),
]
或者没有额外模块的更好/推荐的解决方案:
const isProd = process.env.NODE_ENV === 'production';
// ...
plugins: [
isProd ? new Plugin() : false,
].filter(Boolean)
// filter(Boolean) removes items from plugins array which evaluate to
// false (so you can use e.g. 0 instead of false: `new Plugin() : 0`)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.