本文转载自微信公众号《前端思南》,作者图思。转载本文请联系前端司南公众号。众所周知,node-sass是前端工程师组织CSS的一大利器和法宝。不过用过的朋友都知道,node-sass是让人又爱又恨!你喜欢它是因为它支持CSS工程;你讨厌它是因为有时你不明白为什么它又出错了。最近在生产环境两次踩了node-sass的坑,让我下定决心放弃node-sass。什么是节点sass?node-sass虽然是大家耳熟能详的老朋友,但还是有必要介绍一下。Node-sass是一个库,它提供Node.js到LibSass的绑定,LibSass是流行的样式表预处理器Sass的C++版本。它允许您以令人难以置信的速度并通过连接中间件自动将.scss文件本地编译为css。从上面的介绍可以看出,node-sass是一个在nodejs环境下提供的Bridge,它提供了调用LibSass的能力(而LibSass是用C++实现的样式预处理器)。ps:可以看出node-sass并不是完全靠javascript实现的,而是靠C++的能力。毕竟编译型语言还是很快的。Round1:安装node-sass后刚进入前端领域的朋友可能会问这样一个问题:为什么我的node-sass安装失败了?在网上搜索这个问题,你会找到答案。其中之一就是使用cnpm,但是我用起来感觉很奇怪。刚开始使用Angular4的时候,在执行ngeject的时候出现了很多错误。后来一直使用设置npm淘宝镜像源的方法来处理这个问题。同时这也是解决npminstall下载卡顿或失败的技巧。毕竟有些包裹被封了。npmconfigsetregistryhttps://registry.npm.taobao.org但是这个问题解决了,不代表就万事大吉了。。。Round2:node-sass和node版本不兼容总的来说,NodeJS环境个人电脑安装完成后,很长一段时间都不会考虑升级。但是,前段时间在研究Vite的时候,发现自己的NodeJS版本已经不符合要求了。兼容性NoteVite要求Node.js版本>=12.0.0。所以,我升级了NodeJS版本。但是,当我跑一些老项目的时候,发现项目报错了。模块构建失败(来自./node_modules/sass-loader/dist/cjs.js):错误:NodeSass不支持您当前的环境:Windows64位不支持运行时(83)有关支持哪些环境的更多信息,请参阅:https://github.com/sass/node-sass/releases.releases/tag/v快速查看13.0可知错误消息说NodeSass不支持当前的运行环境。我想这一定是与NodeJS版本不匹配。我首先检查了我的NodeJS版本。nove-vv14.16.0嗯,是新版本,没错。于是去github上查了一下node-sass,发现还是老样子,node-sass@4.13.0版本真的不支持node@14,惨!其实我只需要将NodeJS版本降到13,问题也可以解决。但是我觉得还是有问题的。新项目需要高版本的NodeJS,旧项目需要低版本的NodeJS。我本地只有一个Node环境,所以有矛盾。看来开发环境也需要容器化。老大提醒,还有nvm可以管理node版本。虽然这个问题不能完全归咎于node-sass,但谁说它不支持node@14呢?用着还是不舒服!Round3:node-sass:Commandfailed这是我上个月在生产环境跑CI/CD遇到的一个问题。错误/builds/coollu-r-d/coollu-fe/xkgj_web/node_modules/node-sass:Commandfailed。接着是一堆错误信息。即便我已经在Docker容器中执行了构建任务,也就是说不存在与上面Node版本不兼容的问题,但是还是一次又一次的遇到报错。这谁受得了?使用DartSassDartSass是Sass官网推广的工具,包括基于DartVM的命令行工具和基于Node的纯Javascript实现。前者所说的DartVM是非常流行的Flutter选择的编程语言Dart的虚拟机;后者似乎可以快速与Node环境中现有的工作流集成,如webpack、gulp等。DartSass的命令行工具比JavascriptLibrary性能更好,但为了快速对接webpack等工具,我们一般通过npminstall--save-devsass直接使用sass的JavascriptLibrary。切换到DartSass后,无论是安装还是兼容高版本的Node都没有问题。总的来说,体验还是很不错的!DartSass是我们对它的习惯称呼,它最早确实是在npm上以dart-sass这个名字发布的,但现在已经更名为sass。切换到DartSass后我应该做什么?众所周知,在Vue项目中,scoped样式会通过hash属性选择器(如[data-v-67c6b990])进行隔离,如果要进行样式穿透,会用到/deep/深度选择器在Vue@2中。注意/deep/本身是一个CSS提案(好像是用来解决web组件的样式穿透问题的,我在使用Angular的时候对它有过简单的了解),后来被废弃了,而Vue的/deep/和CSS的/deep/不是同一个概念!考虑到用户很容易误认为Vue的/deep/和CSS废弃的/deep/提案是一回事,他们会误认为/deep/是一个不可用的特性,而Vue也发布了RFC对此做了调整,并且::v-deep后来来了。使用DartSass后,在运行开发环境时可能会遇到不支持/deep/的问题。需要用::v-deep代替,缩写为:deep(selector),例如::deep(.foo){position:relative;}
