- 作者:老汪软件技巧
- 发表时间:2024-08-31 00:01
- 浏览量:
前言
node-sass: Command failed., gyp ERR! build error 这几个词相信很多小伙伴一定看着眼熟,当你的终端出现这些词时那么毫无疑问,你的项目跑不起来了。。。。。。
你可能通过各种方式去解决了这个报错,但是应该没有人去深究到底是咋回事,接下来让我们彻底弄懂,再遇到类似问题时能够举一反三,顺利解决。
关键词:node-sass libsass node-gyp
先来看个截图感受一下
熟悉吧?截图里我们看到了几个关键词 node-sass libsass node-gyp .cpp,我们一一来解释一下
node-sass
node-sass 是一个用于在 Node.js 中编译 Sass 文件的库,node-sass 可以将 .scss 或 .sass 文件编译为标准的 .css 文件,供浏览器或其他工具使用。
当你的项目中使用 sass 来写样式时,会直接或间接地引入这个这个库。
libsass
一个用 C++ 编写的高性能 Sass 编译器,这就是为什么你能在终端日志中看到 .cpp 的文件。
注意,搞这么麻烦就是为了高性能编译sass。
node-gyp
node-sass引入了 c++ 编写的库,那么直接在 node 中肯定是使用不了的,毕竟是两种不同的语言嘛,那么就需要 node-gyp 登场了。
node-gyp 是一个用于编译和构建原生 Node.js 模块的工具,这些原生模块通常是用 C++ 编写的。
node-sass 需要在安装时编译 libsass 的 C++ 代码,以生成可以在本地机器上运行的二进制文件。在这个编译过程中,node-gyp 就被用作构建工具,它负责调用 C++ 编译器(如 g++ 或 clang++),并将 libsass 的源代码编译为与当前系统兼容的二进制文件。
node-gyp 本身是一个用 JavaScript 编写的工具。它使用 Node.js 的标准模块(如 fs 和 path)来处理构建和配置任务,但是需要一些外部工具来实际进行编译和构建,例如 make、gcc等,这些工具必须安装在系统中,node-gyp 只是协调和使用这些工具。
普通模块(JavaScript/TypeScript)
普通模块是用 JavaScript 或 TypeScript 编写的,Node.js 本身可以直接执行或通过编译(如 TypeScript 编译器)转换为可执行代码,Node.js 使用 V8 引擎执行 JavaScript 代码。
原生模块(C/C++ 编写)
原生模块是用 C/C++ 编写的代码,这些模块通常用于高性能需求或需要直接与底层系统 API 交互的场景。它们通过 node-gyp 进行编译,并在 Node.js 中以二进制文件的形式加载。
例如以下模块:
许多现有的高性能库和工具是用 C++ 编写的。为了利用这些库的功能,Node.js 可以通过模块接口调用这些 C++ 库,尤其某些高级功能,如加密算法、图像处理等,已经在 C++ 中得到了成熟的实现,Node.js 可以直接集成这些功能,而不必再重新造轮子而且性能还肯定不如用 c++ 写的库。
所谓的原生模块接口就是 node-gyp,感兴趣的可以看看 node-gyp 的实现,或者了解下包信息 npm info node-gyp
node-gyp 基于 gyp,并在其之上添加了 Node.js 特定的功能,以支持 Node.js 模块的编译。
gyp
gyp(Generate Your Projects)是一个用于生成构建配置文件的工具,它负责将源代码(C++ 代码)转换为特定平台的构建配置文件(如 Makefile、Visual Studio 项目文件等),生成构建文件后,使用生成的构建文件来编译项目。例如,在 Unix 系统上,运行 make;在 Windows 上,使用 Visual Studio 编译项目。
从前端的角度来看,你可以把gyp理解成 webpack,而 make 命令则是 npm run build
为什么报错?
现在,我们已经了解了一些基本概念,并且知道了c++原生模块是需要在安装时编译才能使用的,那么很明显,上面的错误就是在编译时出错了,一般出现这个错误都是因为我们有一些老的项目的 node 版本发生了变化,例如上面的报错就是,在 node14 还运行的好好的,到了 node16 就报错了,我们再来看一下报错细节
这个错误发生在编译 node-sass 的过程中,具体是在编译 binding.cpp 文件时。binding.cpp 是 node-sass 的一部分,用于将 libsass 与 Node.js 接口连接起来。
报错发生在 v8-internal.h 文件里,大概意思是这个c++头文件里使用了比较高级的语法,node-sass中的c++标准不支持这个语法,导致报错,就相当于你在 js 项目里引入一个三方库,这个三方库使用了 es13 的新特性(未编译为es5),但是你的项目只支持 es6,从而导致你的项目报错。
所以解决思路就很清晰了,要么降级 node 版本,要么升级 node-sass,要么干脆就不用node-sass了
解决方案rebuild 大法
npm rebuild node-sass 重新编译模块,对于其他编译错误该方法可能会有效果,但是如果 node-sass 和 node 版本不匹配那就没得办法了,适合临时使用,不推荐。
升级node-sass
以下是 node-sass 支持的最低和最高版本的指南,找对应的版本升级就好了
但是!node-sass 与node版本强绑定,还得去想着保持版本匹配,心智负担较重,所以使用 sass 更好
更换为 sass
官方也说了,不再释放新版本,推荐使用 Dart Sass
Sass 和 node-sass 的区别
实现语言:
构建和编译:
功能和维护:
性能:
总结
gyp ERR! 和 node-sass 问题是由 node-sass 与 node 版本兼容引起的编译问题,推荐使用 sass 替代,如果老项目不方便改的话就采用降级 node 版本或升级 node-sass 的办法。
其实这种问题没太大必要刨根究底的,但是如果这次简单解决了下次遇到类似的问题还是懵逼,主要还是想培养自己解决问题的思路,再遇到类似天书一样的坑时不至于毫无头绪,浪费大量时间。