在 webpack 中一般都会设置 webpack 的 devtool 以开启 sourceMap 功能。在使用了 resolve-url-loader
和 sass-loader
的情况下,当进行生产环境输出关闭 webpack 的 sourceMap 功能时,可能会产生类似如下报错信息:
ModuleNotFoundError: Module not found: Error: Can’t resolve ‘../../images/abc.png’
经过对 resolve-url-loader
和 sass-loader
的源码分析调试发现,resolve-url-loader
在复杂路径查找上依赖于 sass-loader
处理后的 sourceMap 信息,sass-loader
的 sourceMap 开关默认以 webpack 全局为准。
当关闭了 webpack 的 sourceMap 时, 对于被 @import
的 scss
文件来说,resolve-url-loader
因缺失 sourceMap 信息而无法确定真实的文件路径,相对路径查找法因此失效。具体可参考以下引用部分代码自行分析。
- https://github.com/bholloway/resolve-url-loader/blob/master/packages/resolve-url-loader/index.js#L56
- https://github.com/bholloway/resolve-url-loader/blob/master/packages/resolve-url-loader/lib/engine/postcss.js#L75
- https://github.com/webpack-contrib/sass-loader/blob/master/src/getSassOptions.js#L78
说明: 以上相关插件的代码引用版本分别为:resolve-url-loader@3.1.1
和 sass-loader@8.0.2
。
原因找到了后,经过分析相关代码逻辑得知,开启 sass-loader
的 sourceMap
即可解决。示例如下:
rules: [ { test: /\.scss$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'resolve-url-loader', { loader: 'sass-loader', options: { // implementation: require('sass'), // 须设置为 true,使得 resolve-url-loader 能够得到原始文件信息以尝试各种路径查找(options.join) sourceMap: true, sassOptions: { // sourceMap: path.join(process.cwd(), '/sass.map'), // outFile: pluginDesc, // sourceMapRoot: pwd, // omitSourceMapUrl: true, // sourceMapContents: true, includePaths: [path.resolve(src, './styles/'), path.resolve(pwd, './src/styles/')], }, }, }, ], }, ]
相关参考:
- https://www.npmjs.com/package/node-sass
- https://www.npmjs.com/package/resolve-url-loader
- https://github.com/bholloway/resolve-url-loader
- https://www.npmjs.com/package/sass-loader
- https://www.npmjs.com/package/sass-loader#sourcemap