Webpack 的 sass-loader 是没有处理资源(比如图片和字体)的相对路径的。在项目代码中这一点也许不是问题,但是对于 node_modules 中的资源文件就不是那么回事了。
https://webpack.docschina.org/loaders/sass-loader/#resolving-import-at-rules
SCSS 中用@import
引入模块时,只会单纯的引入代码,不会处理资源(url
)的相对路径。
比如:
@font-face test {
font-family: test:
url:(./font/test.woff);
}
所以如果从node_modules
引入 SASS 或 SCSS 文件,文件中的相对路径仍然是相对于包在node_modules
中的路径,从而引发 Webpack 找不到模块的错误。
对此,有几种方法可以解决这个问题:
resolve-url-loader
使用 Webpack 的加载器,放在 sass-loader 之前。
方法
示例:
[
{
loader: 'resolve-url-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
注意:sass-loader必须输出sourcemap。
优点
- SASS包不需要特殊处理,直接使用相对路径。
缺点
- 项目需要配置Webpack。
SCSS变量
在SCSS代码中设置一个默认变量,默认为.
。在项目中重写这个变量,根据引用位置在设定实际的相对路径。
方法
比如在node_modules中有这样一个文件 test/index.scss:
$root: '.' !default;
@font-face test {
font-family: test:
url:(#{$root}/font/test.woff);
}
如果在 src/style.scss 引入了这个文件,那么需要修改$root
。比如:
$root: '../node_modules/test';
@import 'test'
这样$root
变量被覆盖为相对于引入位置的路径,资源也能被正确查找到。
优点
- 可以适用于各种打包工具,比如 Webpack 和 Rollup。
缺点
- 包代码与业务代码耦合。
- 每引用一次都要重新设定路径
base64
既然路径有问题,那可以干脆不要路径了,使用内联的数据。
比如:
@font-face {
font-family: din;
src: url('data:font/woff;charset=utf-8;base64,...') format('woff');
}
优点
- 没有路径问题
缺点
- 不易管理
- 体积增大