Webpack开发环境如何禁用SCSS/CSS引用资源的哈希与复制导出
出现这个现象的原因是css-loader默认会解析SCSS/CSS中所有url()引用的资源,触发Webpack的静态资源处理逻辑,默认会将资源重命名加哈希后输出到构建目录,你当前配置没有区分开发/生产环境的资源处理规则,才会导致开发阶段产生冗余文件。
方案一:直接关闭CSS的URL解析(最简单)
如果本地开发时静态资源路径可以直接通过开发服务访问,直接在开发环境下关闭css-loader的url解析能力,从根源上不处理CSS里的资源引用,就不会复制文件也不会加哈希。
修改SCSS规则中的css-loader配置,替换原来的字符串写法为带环境判断的对象配置:
{ test: /\.scss$/, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { // 生产环境开启URL解析,开发环境关闭 url: production } }, 'sass-loader' ] }
注意:使用该方案需要保证开发服务能直接映射到你的静态资源原始目录,比如SCSS中写
url('../img/logo.png')时,访问开发服务对应路径能直接拿到原文件,否则会出现资源404。
方案二:保留URL解析,仅禁用开发环境的文件输出与哈希
如果需要保留css-loader的url解析能力(比如路径别名、路径拼接的场景),可以新增静态资源处理规则,开发环境下保留原始文件名,并且不将文件写入磁盘:
- 首先在
module.rules中新增静态资源匹配规则:
{ test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|eot|ttf|otf)$/i, type: 'asset/resource', generator: { // 生产环境用带哈希的文件名输出到static目录,开发环境用原始路径和文件名 filename: production ? 'static/[contenthash:15][ext][query]' : '[path][name][ext]', // 核心配置:开发环境下不把资源文件输出到磁盘 emit: production } }
- 保持
css-loader默认配置(即url: true)即可。
额外优化建议
你当前自定义的generateHash()函数每次构建都会生成随机字符串,哪怕文件内容没有变化也会生成新的文件名,不利于生产环境的静态资源缓存,建议替换为Webpack内置的contenthash,仅当文件内容变化时哈希值才会更新:
output: { filename: production ? 'bundle.[contenthash:15].min.js' : 'bundle.js', path: path.resolve(__dirname, 'wwwroot'), // 生产构建前自动清理旧的构建产物 clean: production }, plugins: [ new MiniCssExtractPlugin({ filename: production ? 'style.[contenthash:15].min.css' : 'style.css' }) ]
本地开发推荐使用webpack-dev-server,默认所有构建产物保存在内存中,不会写入本地磁盘,完全不会产生冗余的未暂存文件。你当前配置里的watchContentBase是webpack-dev-server旧版本的配置,新版本替换为static即可:
devServer: { static: path.resolve(__dirname, 'wwwroot'), hot: true }
问题现象参考截图:
内容的提问来源于stack exchange,提问作者nick

