前端 | Vue-cli3 中如何将 node-sass 替换为 dart-sass | Vue

前言

这里选择使用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

快速使用

替换也非常的简单,只需要几个步骤

  1. 卸载 node-sass
 npm uninstall node-sass
 
 yarn remove node-sass
  1. 安装 dart-sass
 npm install --dev sass

 yarn add sass --dev
  1. 更新 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)

结尾

本期的内容就到这里,路过的小伙伴记得支持一下哦!