news 2026/10/2 12:50:51

Yarn安装卡死Building fresh packages?三步定位+六种解法全解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Yarn安装卡死Building fresh packages?三步定位+六种解法全解

接手一个老项目,习惯性敲下yarn install后就去倒水,回来一看,终端还停在Building fresh packages...那一行,光标在闪,进度条纹丝不动。这种"装了等于没装、等了等于白等"的体验,我过去几年里前前后后踩了不下五六次,周围同事也频繁中招。网上关于这个问题的帖子零零散散,多数就是复制一句"改个淘宝镜像",但真正卡死的原因往往不是换源就能解决的。这篇文章按我实际排查的顺序,把Building fresh packages卡死的定位思路、根治方法和常见坑一次性讲完,让下次遇到的人能少走两个小时弯路。

1. 先别慌:搞清 "Building fresh packages" 到底在干嘛

1.1 这行提示的真实含义

Yarn 1.x 安装依赖的流程大致分五步:Resolving packages(解析依赖树)、Fetching packages(下载包)、Linking dependencies(把包链接进 node_modules)、Building fresh packages(构建"新鲜"的包)、最后Done。多数人只知道前两步,所以一看到Building fresh packages就以为是在安装依赖,其实这里重点在做两件事。

第一件事是执行依赖包里声明的生命周期脚本,最常见的是postinstall、install、preinstall。很多 npm 包是通过这些钩子来做下载二进制、打补丁、生成配置文件等工作的,比如node-sass的install.js、esbuild的postinstall、sharp的二进制下载。第二件事是编译原生模块,Yarn 发现某些包不是纯 JavaScript 源码,而是 C/C++ 扩展的时候,会调用node-gyp现场编译产出.node文件,典型的就是bcrypt、sqlite3、canvas这一类。

可以把这个阶段理解成买宜家家具。纯 JS 依赖相当于已经组装好的成品,搬进 node_modules 就能用;原生模块则是拆成散板的半成品,需要你现场拿电钻拧螺丝。Building fresh packages卡住,本质就是"拧螺丝"或"等材料"的过程卡住了,而且卡得没进度提示,非常难受。

1.2 为什么只有你卡,别人不卡

同一份代码,为什么有人yarn install三分钟搞定,有人等半小时都没反应?我总结了四个高频差异点。

第一个是网络环境。Building fresh packages阶段很多动作不是从 npm registry 下载代码包,而是从各自的官方地址拉二进制,比如node-sass会去 GitHub releases 下载编译好的 binding 文件,sharp有自己独立的 libvips 下载源。部分网络环境访问这些海外 CDN 很不稳定,常常是 TCP 连接建立了,但数据迟迟不来,客户端也不报错,就这么一直悬着。

第二个是系统环境。原生模块的编译依赖一整套本机工具链:Windows 上需要 Visual Studio Build Tools 和 Python,macOS 上需要 Command Line Tools,Linux 上需要build-essential和python3。缺任何一个,node-gyp就会卡在编译阶段,或者半路报错,而有些老版本的包在报错前会长时间无输出。

第三个是依赖版本。依赖里如果锁着node-sass@4.14这种"化石级"包,又跑在 Node.js 高版本上,它的二进制下载和编译逻辑与现代工具链的兼容性都很差,卡住的概率远高于新版依赖。

第四个是 Yarn 自身版本。如果你还在用 Yarn 1.x 的某个旧版本,配合新的 Node.js 版本,也会出现各种离奇挂起。这个问题我在 3.5 节会专门展开。

2. 定位卡死点:三步判断是网络还是编译

遇到卡久不动的第一反应很重要,千万不要毫无头绪地反复yarn install,更不要想都不想就删 node_modules。下面这套三步定位法我用了很久,基本五分钟内能搞清楚问题方向。

2.1 第一步:开启 verbose 和加长超时再跑一次

先看它到底卡在哪个包。直接重新执行安装,加上--verbose参数,同时把网络超时调大:

yarn install --verbose --network-timeout 600000

加超时的原因是很多"等待"其实是网络超时阈值太小导致的误判,调大到十分钟可以先排除这个变量。--verbose会把当前正在构建的包名打出来,比如Building fresh packages... [node-sass],如果没有显示具体包名,说明构建队列还卡在前一个包上,就需要把终端窗口拉宽,或者去日志里找。

这一步最关键的是要有耐心,等足够长的时间,比如三到五分钟。有些包下载虽然慢,但没有断,如果你只等三十秒就Ctrl+C,反而看不到真实卡点。

2.2 第二步:看进程和网络连接

在项目终端保持yarn install运行的同时,另开一个终端窗口,观察系统里的进程和网络连接。

Windows 上可以用:

tasklist | findstr node

正常下载阶段会看到一两个 node 进程;如果看到node-gyp或node-pre-gyp字样,且 CPU 占用率很高,说明正在编译,不是假死。再配合:

netstat -ano | findstr :443

看有没有大量ESTABLISHED状态的连接挂在 GitHub 或国外 IP 上。如果连接建立但久久没有数据流量变化,基本可以断定是网络下载等待。

macOS / Linux 下对应命令是:

ps aux | grep node lsof -i:443

我的判断标准很简单:有node-gyp子进程且 CPU 在动,是编译问题,给它时间或补工具链;没有编译子进程但有大量对外ESTABLISHED连接不动,是网络问题,重点去配镜像和调超时。

2.3 第三步:查日志找关键词

Yarn 1.x 会在项目根目录生成yarn-error.log和yarn-debug.log,很多情况下终端没输出的错误细节,日志里都有。打开日志搜索error、EAI_AGAIN、ETIMEDOUT、ECONNRESET、gyp这些关键词。

我来举一个从日志里看到的典型片段:

error Error: https://github.com/sass/node-sass/releases/download/v4.14.1/win32-x64-83_binding.node: connect ETIMEDOUT

这行日志的含义非常明确:node-sass在下载 Windows 平台对应的二进制文件,连接 GitHub 超时。这就是纯网络问题,解决方案见我后面 3.3 的镜像配置。

如果日志里大量出现gyp ERR!、C++、VCBuild、MSB之类的词,则说明进入了编译阶段但工具链有问题。比如MSB8036是找不到 Windows SDK,gyp: No Python是缺 Python。同样是Building fresh packages卡住,日志指向的方向完全不同,这也是我不建议上来盲目换源的原因。

3. 对症下药:六种解法按顺序试用

定位清楚之后,解决方法就要对症。下面六种方案我按从省事到彻底的顺序排列,你可以从第一个开始试。

3.1 先加超时时间(最省事)

Yarn 1.x 默认的network-timeout是 30000 毫秒,也就是 30 秒。如果某个下载在 30 秒内没有任何数据,就会被判断为超时,但实际表现往往是"挂起很久之后才报错"或者"一直 wait"。把超时时间拉大,很多假死现象会直接消失。

yarn config set network-timeout 600000 -g

-g表示写入全局配置,对当前用户的所有项目生效。我建议设成 600000 毫秒(10 分钟),这个数值不影响正常安装速度,只影响极端网络情况下的容错率。

同时可以把网络并发数也降一点,避免连接池被大量慢请求占满:

yarn config set network-concurrency 4

默认并发数是 8,当同一批下载里有几个慢连接时,很容易把队列堵死,降并发反而更稳。这一步对所有场景都适用,属于低成本高收益的基础配置。

3.2 换镜像源

如果问题出在Fetching packages阶段,也就是下载 npm 包本体时速度慢、经常超时,那就需要换 registry。目前国内最常用的 public 镜像地址已经迁移到:

yarn config set registry https://registry.npmmirror.com

换完可以查看确认:

yarn config get registry

注意一个细节:项目里如果有yarn.lock文件,锁定的下载地址可能是官方源https://registry.yarnpkg.com之类,但 Yarn 安装时仍会遵循当前配置的 registry 去替换请求。实测下来,锁定文件里的版本解析不会变,但实际下载会走新镜像,所以不需要担心锁文件失效。

3.3 配置特定包的二进制镜像(node-sass / sharp / esbuild 这一类)

这节是很多人没做到位的地方。前面说过,Building fresh packages阶段很多二进制不是从 npm registry 下载的,而是从包的官方地址下载。以node-sass@4.x为例,它的install.js脚本默认从https://github.com/sass/node-sass/releases/download/...拉文件,这个地址无论是换镜像源还是调超时都管不到,因为它根本没有走 npm registry。

对应解法是为这些特定包单独配二进制下载地址:

# node-sass yarn config set sass_binary_site https://npmmirror.com/mirrors/node-sass/ # sharp 老版本(0.28 - 0.30 左右) yarn config set sharp_binary_host https://npmmirror.com/mirrors/sharp yarn config set sharp_libvips_binary_host https://npmmirror.com/mirrors/sharp-libvips

配置完以后,再看一下当前包名对应的镜像是否生效:

yarn config get sass_binary_site

我遇到过一个项目,卡在node-sass超过二十分钟,配置sass_binary_site之后,yarn install三十秒内完成。原因就是二进制文件从 GitHub 拉取失败后,node-sass老版本会反复重试且不给出有效日志,让人误以为完全没进展。如果你的项目用的是比较新的sass(dart-sass)而不是node-sass,就不存在这个问题,新版sass是纯 JS 实现,不需要下二进制。同理,新版sharp@0.32+也已经自动预编译并走标准 registry,默认情况下不需要额外配置,但如果你的版本较老还是建议配上。

3.4 补齐编译工具链

如果日志明确显示卡在node-gyp编译阶段,那就不是网络的问题,而是本机缺少编译工具。node-gyp两步依赖:Python 和 C++ 编译器。

Windows 上最常见的方案是安装 windows-build-tools:

yarn global add windows-build-tools

这个包会去安装 Python 和 Visual Studio Build Tools,但因为它本身也依赖网络,有时候装起来很慢。更稳妥的方式是去 Visual Studio Installer 里手动安装"使用 C++ 的桌面开发"工作负载,同时勾选 Windows 10/11 SDK。安装完成后需要重启终端,让新环境变量生效。

macOS 上执行:

xcode-select --install

Linux 上(Debian / Ubuntu 系):

sudo apt-get install build-essential python3

一个容易被忽视的坑是 Python 版本匹配。node-gyp较老版本对 Python 2.7 有强依赖,新版本支持 Python 3.x。如果你的机器上同时有多个 Python,需要显式指定:

npm config set python /usr/bin/python3

Windows 上有些人只装了 Python 没装 C++ 编译器,有些人只装了编译器没装 Python,缺一不可,这是编译卡死最常见的原因。如果安装了 windows-build-tools 后仍然卡住,先去系统“应用和功能”里确认 Build Tools 是否真的装全了。

3.5 清缓存、换 Yarn 版本

如果你排除了网络和编译问题,仍然卡在Building fresh packages,可以考虑本地缓存损坏。Yarn 1.x 把下载好的包放在本地 cache 目录(Windows 一般在%LOCALAPPDATA%\Yarn\Cache,macOS/Linux 一般在~/.cache/yarn),缓存里的 tarball 可能因为各种原因损坏,导致解压、链接时无限等待。

yarn cache clean

但我不建议上来就清缓存。先想一下,清缓存意味着所有依赖要重新下载一次,如果网络环境本来就差,反而可能把五分钟的卡顿放大成半小时的全量重下。比较好的做法是:记下项目里依赖的规模,如果依赖很多、网络又不好,先做 3.1 到 3.3 的配置,最后再清缓存。

另一个和缓存并列的坑是 Yarn 版本。Yarn 1.x 的最终版本是 1.22.19,2020 年后基本停止功能更新,对比较新的 Node.js 版本兼容性欠佳。如果项目没有特殊原因锁定 Yarn 1.x,可以切换到 Corepack 托管的新版 Yarn(Berry):

corepack enable corepack prepare yarn@stable --activate

切换之后,新版的yarn安装流程和输出都和老版不同,很多老版挂起的问题会自然消失。需要注意的是,Berry 默认启用 PnP 模式,不生成 node_modules 目录,如果项目里的构建工具(webpack 的老配置、jest、Electron 等)依赖 node_modules 目录,需要额外加 nodeLinker 配置,不是无脑切换。

3.6 终极方案:用 npm 或其他包管理器

如果上面方法都试过,项目还是卡在Building fresh packages,我建议直接换 npm 跑一次试试:

npm install

npm 在同样的网络问题下,错误提示往往比 Yarn 1.x 更明确。虽然两者底层都是 npm registry,但 npm 对超时、重试、日志打印的处理方式更成熟,很多 Yarn 卡死不报错的场景,用 npm 会直接打出ETIMEDOUT或gyp ERR的原因。

另一个可选项是pnpm。pnpm 对依赖的下载和链接逻辑不一样,硬链接方式在安装大依赖树时更快。但要注意 pnpm 的 node_modules 结构是符号链接,如果你的项目里有非常老的工具链或自定义脚本,可能存在兼容问题。

我要强调一点,这招不是"投降",而是工程上的务实选择。团队协作时,保证所有成员稳定安装依赖,比固守某个包管理器更重要。如果 npm 能跑通,就在文档里写明"建议使用 npm install",避免团队内工具链不统一导致的一串问题。

4. 实操记录:一个老项目的完整修复过程

前面讲的是方法论,这节我拿一个实际修复过程完整走一遍。这个案例很有代表性,因为它同时踩了网络下载和二级镜像两个坑,也是网上帖子很少讲透的组合场景。

4.1 现场日志还原

项目背景:Windows 10 电脑,Node 14,Yarn 1.22.19,项目依赖里有node-sass@4.14.1和sharp@0.28.3。同事反馈说新的同学拉取代码后,执行yarn install卡在Building fresh packages超过半小时。

为了复现,我清掉 node_modules 后重新执行:

yarn install --verbose --network-timeout 600000

输出大概是这样:

[1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... success Saved lockfile.

看起来[4/4]之前都成功了,最后一步开始就没了动静。等了十分钟,光标还在闪,没有任何报错。这里的success Saved lockfile很有迷惑性,项目本地明明没有 node_modules,却说 lockfile 保存成功,其实 lockfile 早就生成好了,这个输出只是安装流程的副产品。

4.2 逐层排查路径

我按第二节的三步定位法走了一遍。

开启第二个终端后执行tasklist | findstr node,发现有几个 node 进程在跑,但看不到 node-gyp 相关进程,CPU 占用也不高。再执行netstat -ano | findstr :443,发现大量ESTABLISHED连接,外部 IP 指向明显的 GitHub 地址段。这说明不是编译,是网络下载等待。

打开yarn-error.log,在日志尾部看到重复出现的下载地址,分别是:

  • https://github.com/sass/node-sass/releases/download/v4.14.1/win32-x64-83_binding.node
  • https://github.com/lovell/sharp-libvips/releases/download/v8.11.3/libvips-8.11.3-win32-x64.tar.br

两个都是老包从 GitHub release 拉二进制的常见地址。到这里定位器基本完成:网络可以连通 GitHub,但下载速度极慢,又没有超时反馈,所以表现为无限等待。

4.3 最终配置清单

定位到我之后,处理就非常简单。在项目根目录新建.yarnrc,写入固定的配置:

registry "https://registry.npmmirror.com" sass_binary_site "https://npmmirror.com/mirrors/node-sass/" sharp_binary_host "https://npmmirror.com/mirrors/sharp" sharp_libvips_binary_host "https://npmmirror.com/mirrors/sharp-libvips" network-timeout "600000"

这里选择把配置写进项目的.yarnrc而不是全局配置,原因是团队协作时新同学 clone 下来就会自动生效,不用每个人都手动配。之后重新执行:

yarn cache clean yarn install

整个过程大约 2 分钟跑完,Building fresh packages阶段一闪而过。顺便说一句,这两包的老版本实际都是下载预编译二进制,只要下载地址通了,所谓"fresh packages"并不会真的现场编译,这也解释了为什么修复后安装速度极快。

5. 卡住对照速查表与避坑清单

这节是把零散经验汇总成表格和清单,方便你下次直接查。

5.1 卡住位置对照行情表

现象可能原因首选解法
Building fresh packages后长时间无输出,无编译进程二进制文件下载卡住配置对应镜像(sass_binary_site 等)
输出中有node-gyp相关进程,CPU 高缺少编译工具链或 Python安装 Build Tools / Command Line Tools
日志中有ETIMEDOUT/EAI_AGAINregistry 或二进制源连接超时调大 network-timeout,换 npmmirror
卡在Fetching packages不停registry 下载 tarball 慢换 registry;降低 network-concurrency
缓存清理前的安装异常比清理后好本地缓存损坏yarn cache clean后重装
老依赖 + 新版 Node 环境卡住兼容性问题换 Yarn Berry 或升级依赖 / 换包管理器
公司代理/安全软件环境下卡住请求被拦截或代理异常检查代理配置,调整 npm 代理设置

5.2 几条不容易记得住的经验

第一,不要在没看日志前就删 node_modules。删除重装会重新触全量下载,碰上慢网络等于雪上加霜。我见过不少同事卡了以后先删目录再装,结果问题依旧,时间还白搭了。

第二,不要盲目yarn install --ignore-scripts。这个参数会跳过所有生命周期脚本,可能让安装流程"看起来很顺利",但装完的包等于半成品,运行时必然报错。它适合做问题归因,不适合当长期方案。如果你用--ignore-scripts能装完但运行报模块找不到,说明问题出在构建/下载脚本,而不是依赖关系本身。

第三,团队协作时,把镜像配置和超时配置放进.yarnrc进版本库,比在群里发命令更有效。这不只是给"新同学"看的,也是为了你们公司 CI 环境有统一行为。CI 里执行安装时的日志更容易暴露问题,因为环境干净,没有本机各种代理和缓存干扰。

第四,注意二进制下载地址也会失效。sass_binary_site这种配置本质上是指向镜像站的目录,如果项目降级或升级依赖版本,镜像里不一定有对应版本的文件,比如win32-x64-83_binding.node就和 Node 14 的 ABI 对应。升级 Node 后node-sass还要重新下载对应 ABI 的二进制,这个坑在升级 Node 大版本时特别容易踩。

5.3 预防以后再卡住

想以后彻底少踩这个坑,我建议做三件事。

首先是依赖体检。如果项目还在用node-sass,考虑迁移到sass(dart-sass),后者是纯 JS 实现,不涉及二进制下载,这一条就能消灭一个最大的卡点。如果项目用了sharp,尽量升到新版本,新版预编译和下载机制都更健壮,不再依赖独立的二进制镜像地址。

其次是在项目初始化时就把网络配置固化下来。我在团队里会让新项目统一带一个.yarnrc,内容就是前面那几行,这样从源头规避问题。已有项目也可以补上,不会有副作用。

最后是安装验证。执行yarn install后,用yarn check或者直接跑一遍node -e "require('目标包名')"验证关键原生模块是否真正可用。很多时候Building fresh packages显示Done了,但原生模块因为构建不完整,运行时才报错,等写完代码才发现会很难排查。

我个人在实际操作里的另一个习惯是,把yarn install的日志输出落地保存一份:

yarn install > install.log 2>&1

卡住的时候直接看日志尾部,比在终端里翻屏幕方便得多。这个习惯救了我不少次,尤其是终端缓冲区不够长、关键错误被提前刷掉的情况。

这篇文章里的思路反过来用也成立:以后不管什么包管理器卡住,先判断是"网络等数据"还是"本机在干活",再决定是等、是配镜像、还是补编译环境。思路对了,手法都是小事。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 12:50:29

Faiss向量检索性能调优与评估实践:从原理到参数配置

做过向量检索的朋友,一定绕不开Faiss(Facebook AI Similarity Search)这个名字。我之前在公司内部搭建过一套基于Faiss封装的服务,也就是后来我们内部叫“Easy-VectorDB”的轻量级向量数据库,专门用来处理商品特征向量…

作者头像 李华
网站建设 2026/10/2 12:49:58

通达信短线突击

短线:(CLOSE-MA(CLOSE,13))/MA(CLOSE,13)*20,LINETHICK0,COLORWHITE; 中线:(CLOSE-MA(CLOSE,4))/MA(CLOSE,4)*20,LINETHICK0,COLORYELLOW; VAR200:(CLOSE-LLV(LOW,20))/(HHV(HIGH,20)-LLV(LOW,20))*100; VAR300:SMA(SMA(VAR200,3,1),3,1)/28.57; VAR400:EMA(VAR300,5); 操盘:3*…

作者头像 李华
网站建设 2026/10/2 12:49:06

R语言向量语法的详细教程

在R语言中,向量(Vector)是最基础、最核心的数据结构。R语言中的几乎所有标量(单个数字或字符)在底层都是作为长度为1的向量存在的。理解向量的运作机制,是精通R语言的关键。 以下是R语言向量语法的详细教程…

作者头像 李华
网站建设 2026/10/2 12:47:28

MoveIt2

1,概述专门用来适配ROS2的机器人机械手或机械臂的运动规划软件框架,功能包括:运动规划(生成可顺利通过杂乱环境的高自由度轨迹);机械臂操纵(通过抓取生成对机器人环境进行分析,并与环境进行交互…

作者头像 李华