Vue-cli3 中如何将 node-sass 替换为 dart-sass
介绍
这里选择使用 dart-sass
还有一个更主要的原因,sass
官方已经将 dart-sass
作为未来主要的的开发方向了,有任何新功能它都是会优先支持的,而且它已经在社区里稳定运行了很长的一段时间,基本没有什么坑了。dart-sass
之所以容易安装,主要是因为它会被编译成纯 js,这样就可以直接在的 node 环境中使用。虽然这样它的运行速度会比基于 libsass 的慢一些些,但这些速度的差异几乎可以忽略不计。整个社区现在都在拥抱 dart-sass
,我们没有理由拒绝!而且它的确大大简化了用户的安装成本。
目前 vue-cli
在选择 sass
预处理的时候也会默认优先使用 dart-scss
,相关 pr
相关的说明可以见该篇文章: Announcing Dart Sass
具体 dart-sass
性能评测可见:Perf Report
使用教程
替换也非常的简单,只需要几个步骤
- 卸载
node-sass
npm uninstall node-sass
yarn remove node-sass
- 安装
dart-sass
npm install --dev sass
yarn add sass --dev
- 更新
vue.config.js
文件
module.exports = {
css: {
loaderOptions: {
sass: {
implementation: require('sass'),
}
}
}
}
如果你用了 stylelint
, 那可能需要修改下校验规则
module.exports = {
...
rules: {
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: ['v-deep'],
},
],
},
...
};
FAQ
替换 sass
后不再支持 /deep/
写法
替换 node-sass
之后有一个地方需要注意,就是它不再支持之前 sass
的那种 /deep/
写法,需要统一改为 ::v-deep
的写法。相关: issue
具体 demo:
.a {
>>> {
.b {
color: red;
}
}
}
/* 或者 */
.a {
/deep/ {
.b {
color: red;
}
}
}
/* 修改为 */
.a {
::v-deep {
.b {
color: red;
}
}
}
不管你是否使用 dart-sass
,我都是建议你使用 ::v-deep
的写法,它不仅兼容了 css 的 >>>
写法,还兼容了 sass /deep/
的写法。而且它还是 vue 3.0 RFC 中指定的写法。
而且原本 /deep/
的写法也本身就被 Chrome 所废弃,你现在经常能在控制台中发现 Chrome 提示你不要使用 /deep/
的警告。
补充
在读完 vue 3.0 RFC 后发现,其实更推荐下面的写法
/* DEPRECATED */
::v-deep .bar {}
/* 用伪元素写法传入一个css选择器作为参数 */
::v-deep(.bar) {}
/* 上边的写法会编译为下边的样子 */
[v-data-xxxxxxx] .bar {}
此外还有两种 scope css 写法:
在 <style scoped>
代码快中使用 ::v-global()
, 在这代码块中是全局范围
::v-global(.foo) {}
/* 被编译为 */
.foo {}
专门修改 slot
插槽中元素的样式,你在子组件中修改插槽中样式是没用的,因为传入组件的插槽内容输入父组件,而 Scoped styling
是在编译时确定的,我们在子组件中可以这么写
::v-slotted(.foo) {}
/* 编译为 */
.foo[v-data-xxxxxxx-s] {}
注意 -s
(感觉像是 slot 的缩写)后缀,这表明这个样式只针对于 slot
中的内容
如果控制台 Error: Cannot find module ‘node-sass’
如果控制台报下面的错误, 可能是 sass-loader
版过旧, 建议将版本更新到 7.1.0 +
Module build failed (from ./node_modules/sass-loader/lib/loader.js):
Error: Cannot find module 'node-sass'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
at Function.Module._load (internal/modules/cjs/loader.js:507:25)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at Object.sassLoader (/path-of-your-project-directory/node_modules/sass-loader/lib/loader.js:24:22)