解决 Next.js build 完成后卡住的问题

最近一段时间，我在执行 Next.js 项目的 npm run build 之后总是卡住，表现为在完成 Finalizing page optimization，显示完所有 route 之后，bash 的 prompt 一直没有出现，只能手动 Ctrl + C 打断构建流程。但此时的构建结果可以正常被 npm run start 使用，在 Vercel 上构建也不会出现卡顿问题。通过使用 strace 和 ss 命令，我找到了原因。

方法

执行 npx next telemetry disable 退出 Next.js 的 Telemetry。

如果不使用 npm，可以参考官方文档。

分析过程

通过执行 strace npx next build，我得以看到 Next.js 编译过程中所执行的系统调用。为了能将 strace 的输出和 Next.js 的输出分开，可以使用 mkfifo log 命令建立命名管道，然后执行 strace npx next build 2>log 将 stderr 重定向到管道，使用 cat < log 输出系统调用信息。

strace npx next build 最终卡在以下部分：

+ First Load JS shared by all 87 kB
├ chunks/23-b022cbf28d88ae21.js 31.4 kB
├ chunks/fd9d1056-e3489de6ce1f07f6.js 53.7 kB
└ other shared chunks (total) 1.94 kB

○ (Static) prerendered as static content
● (SSG) prerendered as static HTML (uses getStaticProps)

而 cat < log 则输出：

epoll_pwait(17, [{events=EPOLLIN, data={u32=22, u64=22}}], 1024, 0, NULL, 8) = 1
read(22, "\1\0\0\0\0\0\0\0", 1024) = 8
epoll_pwait(17, [], 1024, 0, NULL, 8) = 0
epoll_pwait(17,

epoll 系统调用通常用于网络上，因此大概是遇到了网络问题。

另外打开一个终端，输入 ss -tn，可以看到许多 Vercel IP 段的 TCP 连接：

ESTAB 0 2384 10.20.244.49:60724 76.76.21.22:443
ESTAB 0 1675 10.20.244.49:60970 76.76.21.241:443
FIN-WAIT-1 0 2015 10.20.244.49:60750 76.76.21.142:443
ESTAB 0 4851 10.20.244.49:60844 76.76.21.22:443

结合之前 Vercel 在中国大陆被阻断的事件，我大约感觉出了原因。HTTP_PROXY 和 HTTPS_PROXY 似乎对 Next.js 无效，因此需要借助 TUN 或者 WireGuard 等全局联网方式才能解决。

当然，最简单的方法就是退出 Next.js 的 Telemetry。

后记

怪不得我在 StackOverflow 上找不到解决方法，因为世界上大部分国家的程序员都不会遇到这种问题。

但 Vercel 也应该给 Telemetry 加个 timeout 的措施才是。

参考资料

Telemetry | Next.js by Vercel - The React Framework

原文：解决 Next.js build 完成后卡住的问题