Webpack5中SCSS嵌套@import时资源相对路径解析错误求助
SCSS @import 资源路径解析错误的解决方案
问题原因
使用SCSS的@import导入子文件时,sass-loader会将子文件的代码合并到主SCSS文件中,导致css-loader解析资源路径时,会以主SCSS文件的位置为基准,而非子文件自身的位置,因此找不到子文件夹内的资源。
文件结构
/script.js /style.scss /subfolder/ image.png substyle.scss /webpack.config.js
相关代码与配置
webpack.config.js
module.exports = { mode: 'production', entry: './script.js', module: { rules: [ { test: /\.scss$/i, use: [ 'style-loader', 'css-loader', 'sass-loader' ] }, { test: /\.css$/i, use: 'css-loader' } ] } }
script.js
import './style.scss'
style.scss
@import "subfolder/substyle";
subfolder/substyle.scss
body{ background: url(image.png); }
报错信息
Module not found: Error: Can't resolve 'image.png' in 'E:\webpacktest' resolve 'image.png' in 'E:\webpacktest' Parsed request is a module using description file: E:\webpacktest\package.json (relative path: .) using description file: E:\webpacktest\package.json (relative path: ./image.png) no extension E:\webpacktest\image.png doesn't exist as directory E:\webpacktest\image.png doesn't exist resolve as module looking for modules in E:\webpacktest\node_modules single file module using description file: E:\webpacktest\package.json (relative path: ./node_modules/image.png) no extension E:\webpacktest\node_modules\image.png doesn't exist E:\webpacktest\node_modules\image.png doesn't exist E:\node_modules doesn't exist or is not a directory
解决方法
方法1:手动调整资源路径(快速但不灵活)
修改subfolder/substyle.scss中的资源路径,使其相对于主SCSS文件的位置:
body{ background: url('./subfolder/image.png'); }
缺点:如果substyle.scss被其他不同路径的SCSS文件导入,该路径会再次失效。
方法2:使用resolve-url-loader解析原始路径(推荐)
该方法可以保留子文件内的相对路径,无需手动修改,适配多种导入场景。
- 安装依赖:
npm install resolve-url-loader --save-dev
- 修改webpack配置,在
sass-loader之前添加resolve-url-loader,并开启sass-loader的sourceMap:
module.exports = { mode: 'production', entry: './script.js', module: { rules: [ { test: /\.scss$/i, use: [ 'style-loader', 'css-loader', 'resolve-url-loader', { loader: 'sass-loader', options: { sourceMap: true // 必须开启,resolve-url-loader依赖此解析原始路径 } } ] }, { test: /\.css$/i, use: 'css-loader' } ] } }
原理:resolve-url-loader会利用sass-loader生成的sourceMap,将资源路径重新解析为相对于原始子SCSS文件的位置,而非合并后的主文件路径。
内容的提问来源于stack exchange,提问作者Loran
相关产品推荐
相关产品推荐

