如何获取Webpack命令行flag设置的mode值?开发环境禁用image-webpack-loader
你遇到的问题根源在于:你的config对象是在Webpack配置函数外部定义的,这时候Webpack还没有解析命令行传入的mode参数,所以process.env.NODE_ENV的值并不是你期望的命令行模式值(除非你提前在系统环境变量里设置了它)。而Webpack自动注入process.env.NODE_ENV是在编译应用代码阶段,不是在配置文件自身的执行阶段。
要解决这个问题,你需要在Webpack提供的配置函数(就是接收env和argv的那个函数)里,根据argv.mode来动态设置image-webpack-loader的disable选项。下面是两种可行的修改方式:
方式一:在配置函数内重构Rules配置
直接把模块规则的定义移到配置函数中,这样就能直接访问argv.mode:
module.exports = (env, argv) => { const isDevelopment = argv.mode === 'development'; const config = { entry: './src/entry.js', output: { filename: 'script.js', }, module: { rules: [ { test: /\.(png|svg|jpg|jpeg|webp)$/, use: [ { loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'images/', }, }, { loader: 'image-webpack-loader', options: { disable: isDevelopment, } }, ], }, ], }, mode: isDevelopment ? 'development' : 'production', }; if (isDevelopment) { config.devtool = 'source-map'; } return config; };
方式二:修改已有的Config对象的Rules
如果你不想重构整个config对象,也可以在配置函数里找到对应的loader规则,修改它的options.disable值:
const config = { entry: './src/entry.js', output: { filename: 'script.js', }, module: { rules: [ { test: /\.(png|svg|jpg|jpeg|webp)$/, use: [ { loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'images/', }, }, { loader: 'image-webpack-loader', options: { // 先设一个默认值,后面再动态修改 disable: false, } }, ], }, ], }, }; module.exports = (env, argv) => { const isDevelopment = argv.mode === 'development'; config.mode = isDevelopment ? 'development' : 'production'; if (isDevelopment) { config.devtool = 'source-map'; // 找到image-webpack-loader的规则并修改disable选项 const imageRule = config.module.rules.find(rule => rule.test.test('.png')); const imageWebpackLoader = imageRule.use.find(use => use.loader === 'image-webpack-loader'); imageWebpackLoader.options.disable = true; } return config; };
验证方式
现在运行你的命令:
- 执行
webpack --mode=development时,image-webpack-loader会被禁用,图片不会被压缩优化; - 执行
webpack --mode=production时,loader正常工作,图片会被处理。
另外补充一点:Webpack的mode参数会自动为你设置process.env.NODE_ENV(通过DefinePlugin),但这只作用于你的应用代码,而不是Webpack配置文件本身。配置文件是在Node.js环境中运行的,所以如果要在配置文件里使用环境变量,要么通过argv.mode获取,要么手动在启动命令前设置,比如NODE_ENV=development webpack(Windows下用set NODE_ENV=development && webpack)。不过用argv.mode是更可靠的方式,因为它直接读取命令行传入的mode值。
内容的提问来源于stack exchange,提问作者user10908202

