尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

node-sass安装失败全解析:renren-fast-vue项目排障与版本兼容指南

node-sass安装失败全解析:renren-fast-vue项目排障与版本兼容指南 做谷粒商城这个项目的人十个里有九个都被renren-fast-vue的node-sass折磨过。我当时卡在这一步整整一个晚上npm install 反复失败报错信息红彤彤一片看着就头大。后来把node-sass的版本机制、Node 版本兼容关系、安装原理摸了一遍才算彻底弄清楚问题出在哪。这篇就把这个坑从头到尾拆开讲明白包括我当时踩的每一个细节、试过的每个方案、最终怎么跑通的希望能帮你少走点弯路。1. 问题现场直击先看看这个坑到底长啥样1.1 一执行 npm install 就红屏谷粒商城的前端项目renren-fast-vue是基于 Vue 2 的拉下来代码之后第一件事就是装依赖。我在项目根目录下执行npm install前面几十个依赖都装得好好的进度条欢快地跑着结果到了node-sass这里突然开始报错。典型的错误长这样 node-sass4.14.1 install /Users/xxx/workspace/renren-fast-vue/node_modules/node-sass node scripts/install.js Downloading binary from https://github.com/sass/node-sass/releases/download/v4.14.1/darwin-x64-72_binding.node Cannot download https://github.com/sass/node-sass/releases/download/v4.14.1/darwin-x64-72_binding.node: HTTP request sent, awaiting response ... 404 Not Found ... gyp: Call to node -e require(nan) returned exit status 1 while in binding.gyp. while trying to load binding.gyp gyp ERR! configure error gyp ERR! stack Error: gyp failed with exit code: 1有的同学还会遇到另一种报错Module build failed: Error: Missing binding /Users/xxx/workspace/renren-fast-vue/node_modules/node-sass/vendor/darwin-x64-72/binding.node Node Sass could not find a binding for your current environment: Linux 64-bit with Node.js 12.x Found bindings for the following environments: - Linux 64-bit with Node.js 10.x这一派乱象看着吓人其实核心就是一件事node-sass下载的编译产物binding.node和当前 Node.js 版本对不上或者压根下载不下来。1.2 为什么这个坑几乎人人都踩renren-fast-vue这个前端脚手架是好多年前定型的它锁定的依赖版本都比较老。拿最常见的配置来说package.json里写的是node-sass: ^4.14.1甚至有的是node-sass: 4.9.0。而谷粒商城这套课程的受众是什么人呢基本都是像我一样的 Java 后端转全栈、或者刚入行没多久的新人很多人电脑上装的就是最新的 Node.js。2023 年之后官方 Node.js 版本都出到 18、20 甚至 21 了而node-sass 4.x最高也只能支持到 Node.js 14 左右。版本差得太大安装时node-sass就去 GitHub 下载对应的二进制文件结果发现官方压根没编译对应的版本直接 404这一下就卡死了。这个问题的本质是node-sass不是一个纯 JavaScript 包它是 C 写的libsass的 Node 封装。安装时要么下载官方预编译好的二进制要么在本地用 node-gyp 现场编译。两种路子都需要跟你当前的 Node 版本严格匹配。2. 扒一扒根因node-sass 和 Node.js 到底怎么兼容2.1 先搞懂 node-sass 的安装机制node-sass在安装阶段会执行一个install.js脚本这个脚本会做两件事第一根据当前的 Node.js 版本算出 ABI 版本号比如 Node.js 12 对应 ABI 72Node.js 14 对应 ABI 83。第二去 GitHub Releases 下载对应平台、对应 ABI 的binding.node文件。这个binding.node就是node-sass真正干活的 C 原生模块。Sass 源码要通过它调底层的libsass引擎编译成 CSS。如果你当前 Node 版本对应的 ABI 是 72也就是 Node 12下载的文件就叫darwin-x64-72_binding.node。如果你的 Node 是 16ABI 是 93官方没提供就会 404。这里有个非常关键的知识点binding.node是平台相关的。Windows、Linux、macOS 的二进制不能互相通用64 位和 32 位也不能通用。所以node-sass网站上下载的路径里一般会带上darwin-x64、linux-x64、win32-x64这样的标识。放到谷粒商城这个场景里就会遇到两个高频问题官方没给你这个 Node 版本的二进制直接 404 下载失败下载成功了但本地有多个 Node 版本切换后binding.node找不到了于是报Missing binding。2.2 版本对应关系速查表我整理了一份常用 Node.js 版本与node-sass版本的对应关系方便你对照排查Node.js 版本对应 ABI支持的 node-sass 版本Node.js 8.x57node-sass 4.9.x ~ 4.13.xNode.js 10.x64node-sass 4.13.x ~ 4.14.xNode.js 12.x72node-sass 4.14.xNode.js 14.x83node-sass 4.14.x / 5.0.xNode.js 16.x93node-sass 6.0.x / 7.0.xNode.js 18.x108sassdart-sass替代Node.js 20.x115sassdart-sass替代你注意看node-sass 4.14.1的官方支持上限就是 Node.js 12 和 14。如果你装了 Node 16 以上基本就告别node-sass 4.x了。而renren-fast-vue里面恰恰写死了4.14.1这就是坑的源头。2.3 网络环境的额外加成除了版本不匹配之外node-sass下载二进制文件走的是 GitHub Releases。在服务器上执行 npm install 时GitHub 的访问速度时快时慢经常是下载到一半连接超时。我当时在服务器上就遇到过一次Downloading binary from https://github.com/sass/node-sass/releases/download/v4.14.1/linux-x64-72_binding.node Download failed: getaddrinfo ENOTFOUND github.com这种网络层面的失败跟版本匹配是两码事但如果混在一起报错特别容易把人搞懵。很多人明明版本匹配正确还是装不上就是网络卡住了。3. 解决方案实操几条比较靠谱的路子3.1 方案一用 nvm 切换 Node 版本最省事如果你不介意用老版本的 Node.js这个方法是最快的。我个人的建议是使用nvm来管理 Node 版本。nvm 全称 Node Version Manager可以让你在同一台机器上装多个 Node 版本随时切换。安装好 nvm 之后执行# 安装 Node.js 12 nvm install 12.22.12 # 切换到 Node.js 12 nvm use 12.22.12 # 查看当前版本 node -v然后回到renren-fast-vue项目目录把node_modules删干净重新安装rm -rf node_modules package-lock.json npm install只要你网络没有大问题这一步基本能过。因为 Node.js 12 对应的是node-sass 4.14.1官方支持的 ABI 72它下载二进制文件不会 404。我当时为了验证这个方案专门用nvm切到12.22.12试了一次npm install确实能顺利装完后面npm run dev跑开发服务器也一切正常Node 12 上跑 webpack 4 的语法完全没问题。3.2 方案二使用国内镜像源下载二进制如果你不想切换 Node 版本但当前的 Node 版本又在node-sass支持范围内比如 Node 12 或 14那可以单独配置node-sass的二进制下载地址。node-sass提供了一个环境变量叫SASS_BINARY_SITE。只要它存在install.js就会优先从这个地址下载而不是去 GitHub。国内一般用淘宝镜像源npm config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/然后删掉node_modules重新安装rm -rf node_modules npm install如果你不想全局设置也可以在项目根目录写一个.npmrc文件内容只有一行sass_binary_sitehttps://npm.taobao.org/mirrors/node-sass/这个.npmrc是项目级的配置只对当前项目生效不会影响别的项目。个人比较推荐这种做法因为它是跟着项目走的哪怕是把这个项目复制到别的机器上配置也还在。3.3 方案三设置 SASS_BINARY_PATH 离线安装这个方案适合那种连npm install都执行不了、只能在其他机器上下载好二进制再拷贝过来的情况。先用一台网络顺畅的机器到node-sass的 Releases 页面下载你需要的binding.node文件。比如你在 Linux 64 位系统上用 Node.js 12文件就是linux-x64-72_binding.node。然后把文件拷贝到目标机器的某个目录比如/opt/sass_binary/linux-x64-72_binding.node再执行export SASS_BINARY_PATH/opt/sass_binary/linux-x64-72_binding.node npm installnode-sass的安装脚本检测到SASS_BINARY_PATH存在就不再走网络下载直接复制本地文件。这个方法看着麻烦但在内网部署的时候特别管用。很多公司的服务器是隔离网访问不了外部网络就只能这么干。3.4 方案四把 node-sass 换成 sassdart-sass这是长期来看最推荐的一条路也是我现在做 Vue 2 项目默认的配置思路。sass官方名称 dart-sass是 Sass 语言的官方实现纯 JavaScript 编写不需要下载平台相关的二进制文件安装起来比node-sass稳得多。而且在语法层面它完全兼容node-sass时代的 SCSS 写法。具体操作很简单先卸载node-sassnpm uninstall node-sass然后安装sass并指定版本npm install sass1.32.13 --save-dev这里版本有讲究。renren-fast-vue用的是 Vue 2 webpack 4sass-loader 是 8.x 左右。sass-loader 8 搭配sass1.32.x 验证过是没问题的。如果你盲目装最新版sass比如 1.70有可能会遇到一个警告说sass的新特性在旧版 sass-loader 下不生效但一般不影响编译。改完之后项目的 SCSS 文件直接就能编译因为你根本没改任何代码只是底层的编译引擎从node-sass换成了dart-sass对外接口都是一样的。3.5 方案五升级整个前端构建链这个方案工作量最大我不太建议新手一上来就这么干但如果你确实想在 Node 2x 上跑renren-fast-vue那就要动构建链了。具体来说就是把webpack从 3 升到 4sass-loader从 7/8 升到 12 以上vue-cli从 2.x 升到 4.x 或 5.x。这牵扯到配置文件的重写比如webpack.base.conf.js里的 loader 规则可能要改。而且 Vue 2.6 的编译器在某些新版本 webpack 下会有些小坑。如果只是跟着谷粒商城视频学习不建议走这一步。课程里后面的构建配置都是基于老版本的你升级了反而对不上。等到项目学完了想自己重构再考虑升级也不迟。4. 我的一次完整排障实录从报错到跑通4.1 先确认自己的环境我当时手上的环境是操作系统macOSNode.js 版本v14.17.0npm 版本6.14.13项目依赖node-sass: 4.14.1严格来说 Node.js 14 是支持node-sass 4.14.1的所以我的问题主要不是版本不匹配而是二进制下载失败。我当时的报错信息是Cannot download https://github.com/sass/node-sass/releases/download/v4.14.1/darwin-x64-83_binding.node:这个darwin-x64-83对应 Node 14按理说是存在的但下载连接一直超时。GitHub 的连接问题在国内环境很常见不展开细说反正思路就是不走 GitHub走镜像。4.2 按步骤处理第一步清理现场rm -rf node_modules package-lock.json第二步配置项目级.npmrcsass_binary_sitehttps://npm.taobao.org/mirrors/node-sass/第三步重新安装npm install这次明显能看到下载速度变了很快就到了node-sass的安装阶段日志显示 node-sass4.14.1 install /Users/xxx/workspace/renren-fast-vue/node_modules/node-sass node scripts/install.js Downloading binary from https://npm.taobao.org/mirrors/node-sass/v4.14.1/darwin-x64-83_binding.node Download complete Binary saved to /Users/xxx/workspace/renren-fast-vue/node_modules/node-sass/vendor/darwin-x64-83/binding.node Caching binary to /Users/xxx/.npm/node-sass/4.14.1/darwin-x64-83_binding.node看到Download complete和Binary saved这两行的时候我的心就放下了大半。后面继续跑完整个依赖树的安装没有再报错。第四步启动前端工程npm run dev编译器顺利启动页面在localhost:8001renren-fast-vue 默认端口正常打开登录页渲染无误。到这一步问题就算彻底解决了。4.3 换个思路直接锁定 sass后来我在另一个系统上重新部署这套代码学乖了直接就把node-sass给换成了sass。操作流程是这样的rm -rf node_modules package-lock.json npm uninstall node-sass --save-dev npm install sass1.32.13 --save-dev然后启动项目一切正常。而且因为是纯 JS 实现没有原生二进制依赖后续不管是在 CI 上构建还是换台机器克隆都少了很多幺蛾子。我的实际体会是如果这个项目你打算长期维护与其每次都跟node-sass的二进制斗智斗勇不如一次性换成sass。成本很低收益是每次npm install都变得非常干净。5. 常见报错与排查方法速查5.1 错误一Missing binding报错长这样Error: Missing binding /path/to/node_modules/node-sass/vendor/darwin-x64-72/binding.node Node Sass could not find a binding for your current environment这个报错的意思是本地的binding.node跟你当前 Node 版本不匹配或者压根没下载下来。最常见的出现场景是你切换了 Node 版本。比如第一次用 Node 12 装了依赖后来切到 Node 14node-sass一启动发现找不到对应darwin-x64-83的 binding。解决办法有两个。第一个是重新执行npm rebuild node-sass让它根据当前 Node 版本重新下载二进制。第二个是干脆删掉node_modules重新npm install。个人推荐第二个简单粗暴管用。顺便提供一个神奇的状况有时候npm rebuild不起作用是因为有一个缓存目录。你可以在项目目录下手动清理npm cache clean --force rm -rf node_modules package-lock.json npm install5.2 错误二安装卡在 Downloading binary 很久然后失败这个几乎没有悬念就是网络问题。node-sass默认从 GitHub 下载而有些环境下 GitHub 的连接极不稳定。解法就是前面说的配置sass_binary_site。建议直接在项目根目录放一个.npmrc一劳永逸。还有一点就是把 npm 的仓库地址也换成镜像源这样npm install本身下载依赖包也会快很多registryhttps://registry.npmmirror.com sass_binary_sitehttps://npmmirror.com/mirrors/node-sass/注意不同时期的淘宝镜像域名可能调整如果你发现老的npm.taobao.org不好用了可以换成registry.npmmirror.com。5.3 错误三node-gyp 编译报错如果你在安装过程中看到大段 gyp 相关的报错说明官方没有提供当前平台或版本的预编译二进制于是node-sass尝试在本地用node-gyp编译源码。编译libsass需要 C 构建工具链Windows 上需要安装 Visual Studio Build ToolsmacOS 上需要 Xcode Command Line Tools执行xcode-select --installLinuxUbuntu/Debian需要build-essential和python2但不建议跟它死磕大概率就是你 Node 版本太新超出支持范围。老老实实切换 Node 版本或者替换成sass才是正道。5.4 错误四SyntaxError: Unexpected token .这个报错通常出现在你用了特别新的 Node.js而项目里某个老的前端工具链无法解析。比如 Node 18 跑 webpack 4 在某些情况下会报SyntaxError: Unexpected token .这也是renren-fast-vue另一个坑的来源。如果你遇到这种问题最直接的方案还是切回老版本 Node。做谷粒商城这类课程项目最省心的 Node 版本就是12.22.12或14.x。6. 把 node-sass 一次性装明白的后续建议踩完这个坑之后我给自己定了一个规矩只要是克隆别人老项目第一步先看package.json里有没有node-sass。有的话先确认 Node 版本不对马上用nvm切不走弯路。如果你跟着谷粒商城课程学强烈建议你在项目根目录补上.npmrc把镜像源和二进制源固定死。这样不光你现在省心以后课程里其他同学问起来你也可以直接甩给他们。另外顺手给大家安利一个操作在package.json里加上engines字段声明这个项目需要的 Node 版本engines: { node: 12 15 }这样万一哪天有新人把你的代码 clone 到别的环境运行npm install的时候会提醒 Node 版本不匹配省得他一脸懵地踩进同一个坑。最后再分享一点个人体会。很多新手遇到这种依赖安装错误特别容易慌总觉得是自己把环境搞坏了。其实node-sass的问题特别好认它的报错信息十有八九是“下载失败”“没有 binding”“找不到对应版本”。遇到它先稳住按我们上面说的顺序排查先看 Node 版本再配镜像最后考虑换sass。绝大多数情况十分钟之内就能解决。别在这个地方磨太久后面的路由、Vuex、权限控制、以及各种后端联调才是更值得投入精力的地方。
返回列表