项目中使用的 scss 编译过慢,经常在编译中途停止不动,怀疑是 sass-loader 版本问题,决定升级。
原版本:
node: 14.16.1
node-sass: ^7.0.1
sass-loader: ^7.3.1
vue.config.js 中 全局 scss 变量配置
module.exports = {
css: {
loaderOptions: {
scss: {
// 全局sass变量
//sass-loader 8.0.0以前版本 , v8 - prependData, v10+ - additionalData
data: `@import "~@/assets/scss/index.scss";`
},
sass: {
// 全局sass变量
//sass-loader 8.0.0以前版本 , v8 - prependData, v10+ - additionalData
data: `@import "~@/assets/scss/index.scss";`
}
},
},
}
现在一看就不对劲,node-sass 和 sass-loader 版本号,不完全对应,根据实际体验是可以用,但是用的不得劲。
升级后
node: 16.15.1
,对应 npm
版本:8.11.0
,node_modules
版本:93
node-sass: ^6.0.1
sass-loader: ^10.0.1
vue.config.js 中 全局 scss 变量配置
module.exports = {
css: {
loaderOptions: {
scss: {
additionalData: `@import "~@/assets/scss/index.scss";`
},
sass: {
additionalData: `@import "~@/assets/scss/index.scss";`
}
},
},
}
经官方寻找的版本号,node-sass 上有 node和 node-sass 对应版本号。
官方推荐 node 版本:node 官方下载地址
下载特定 node 版本:查看 node 与 npm、node_modules 对应版本号并下载
node-sass 对应的 sass-loader 部分版本号:
sass-loader 4.1.1,node-sass 4.3.0
sass-loader 7.0.3,node-sass 4.7.2
sass-loader 7.3.1,node-sass 4.7.2
sass-loader 7.3.1,node-sass 4.14.1
sass-loader 10.0.1,node-sass 6.0.1
综上,得出升级后对应的版本号。
TIPS:
升级过程中,当前最新 Node 是 v18+,想着升都升了,不如再升高级点,到 v17+,升级上去遇到报错 Error: error:0308010C:digital envelope routines::unsupported。
原因: node v17 中的 OpenSSL3.0 对允许算法和密钥大小增加了严格的限制,可能会对生态系统造成一些影响。在 node v17 以前一些可以正常运行的的应用程序,但是在 V17 版本可能会抛出以上异常。
解决方法:
windows 运行: set NODE_OPTIONS=--openssl-legacy-provider
mac or linux 运行: export NODE_OPTIONS=--openssl-legacy-provider
当然,我当时由于第 2 点的报错未解决,又装回了 v16+。升级后启动项目报错:ValidationError: Invalid options object. Sass Loader has been initialised using an options object that does not match the API schema.
一开始查找到的都是 node-sass 和 sass-loader 的版本号不对应,但是此处版本都是经过我精挑细选,从众多版本号中脱颖而出,独一无二的呢。
必然不可能不对应(虽然比对、卸载重装了好多次,还把 package-lock.json 删掉,重新生成[npm insatall 可重新生成 package-lock.json])。
最后发现原因是,上面的全局 scss 变量配置没有修改,sass-loader 已经 v10+,配置中还是使用的 v8- 的关键字。老字怎么配得上我新版本,不报错简直是天理不容!!!
综上,此错的原因可能有两个,node-sass , sass-loader 版本不对应;或 vue.config.js 中全局 scss 变量配置关键字有误。npm i 的时候,如果
sass-loader
使用 v10.0.1,node-sass
使用 v6.0.1,即 版本号写死或版本号前为 ~ ,只升级最小的版本号,安装过程中会提示 当前 sass-loader 对应的 node-sass 为 v4+ 或 v5+。版本号前改为 ^ 解决,每次升级大版本号后面的。安装好后,查看 package-lock.json,最终安装的node-sass
为v6.0.1
,sass-loader
为v10.2.1
。
解决报错后,启动项目,完美执行,除了编译过程中,进度 67% 68% 处,两个数字反复横跳多次(不知原因),没有其他问题。也不卡着不动了,治好了我多年的心焦症。
另:项目中 element-ui 样式刚开始引入的 scss 文件 (@import '~element-ui/packages/theme-chalk/src/index'),编译过程中提示 sass 2.0
中,某些用法会被弃用,检查出超多警告,之前在 element-ui 下执行 sass-migrator division */*.scss ,不会打印警告了。但感觉也会去检查,只是检查过程不打印出来而已, 甚至可能是编译中间卡住的罪魁祸首。
趁此次升级,改为引入 css
文件(@import '~element-ui/packages/theme-chalk/lib/index.css'
),一举解决。packages 下的文件为插件源代码,lib 为编译后输出的代码,使用 lib 方便些
完美 ending
[20220911 更新]:
- 上面
vue.config.js
中配置的全局引入scss
,会在每个使用 scss 的 vue 组件中引入。因此,此处适合配置全局变量和mixin
之类,单纯的全局样式,不建议在此处引入。如果执意在此处引入全局样式,有的 vue 文件中没有 style 样式标签,想要全局样式在此处生效,需要 vue 文件中写一个<style lang="scss">中间必须有内容 </style>
(猜测因为配置文件是在每个 vue 文件单独引入的原因)。 -
全局样式 scss,在
vue-cli4 + webpack 4.x
项目的main.js
中,引入不报错,但也不生效(暂时没找到原因)。在vue-cli5 + webpack5.x
项目的main.js
中,引入生效。保险起见,在app.vue
中全局引入最好。
-引入 scss 文件时,使用@import url('xxx.scss')
语法,会被解析为 css 文件,里面的变量不会生效。应使用@import 'xxx.scss'