Node.js 大变天:26 转 LTS、一年一版时代开启,node 直接跑 TypeScript,但升级有坑
2026/11/14
Read This Article in English前言
“我们什么都没改,早上一开电脑 CI 全红了。”
10 月 28 日之后,不少团队陆续踩中同一个坑:Dockerfile 里钉着浮动 node:lts 标签,Node 26 接棒 LTS 当天,构建环境一夜从 24 跳到 26,原生插件编译不过、老 API 直接报错。

这不是偶然,而是两件事撞在了一起:Node 26 接棒 LTS,以及 Node.js 十年来最大的一次发布规则改版。
今天这篇文章,我把这次大版本更新彻底讲透:到底发生了什么、新特性怎么用、升级前必须避开哪些坑。文中所有关键事实都经过官方信源逐一核实,可以直接抄作业。
一、到底发生了什么
1. Node 26 接棒 LTS
先看现役版本格局(截至 2026-11-14):
| 版本 | 代号 | 状态 | 关键节点 |
|---|---|---|---|
| 26.x | Lithium | Active LTS | 2026-05-05 发布 v26.0.0;2026-10-28 转 LTS;EOL 2029-04-30 |
| 24.x | Krypton | Maintenance | 2026-10-20 进入维护期;EOL 2028-04-30 |
| 22.x | Jod | Maintenance | EOL 2027-04-30 |
| 27.x | — | Alpha | 2026-10-28 起预发布;计划 2027-04-22 正式发布 |
Node 26(代号 Lithium)在 2026-10-28 发布 v26.13.0 正式进入 Active LTS,最新版 v26.13.1(2026-11-10,内置 npm 11.20.0)。同时 Node 24 进入维护期,只修安全 bug 不加新特性了。
2. 十年奇偶双轨制,终结
更大的新闻是官方同日落地的发布节奏改版,公告原文说得直白:自 27 起,从半年一个大版本改为一年一个。
新节奏是这样转的:
- 每年 10 月:从 main 切出新版本线,先做 6 个月 Alpha(允许破坏性变更)
- 次年 4 月:发布 x.0.0 进入 Current
- 当年 10 月:转入 LTS,支持到第三年 4 月
也就是说,每个大版本都会转 LTS——过去”奇数版尝鲜、偶数版求稳”的十年老规矩作废了。官方给的理由也很实在:奇数版本采用率极低,四五条活跃线同时做安全维护,扛不住。
官方公告地址: https://nodejs.org/en/blog/announcements/evolving-the-nodejs-release-schedule
3. 一个魔幻的现状:历史上第一次没有 Current
按旧节奏,Node 27 本该在 10 月下旬发布为 Current。但这次你去 nodejs.org 首页看,只有两个下载标签:Latest LTS(v26.13.1)和 Latest Alpha。
Node 27 目前只有两个 Alpha 预发布(最新 v27.0.0-alpha.0.1.0,已内置 npm 12.x),正式版要等到 2027-04-22。当下不存在任何处于 Current 阶段的版本——这是改制过渡期的特殊现象,看到”Node 27 已发布”的说法一律是错的。
二、最值得上手的新特性
以下代码全部在 v26.13.1 官方二进制上实测通过,零 flag。
1. node 直接跑 TypeScript,彻底转正
这是 Node 26 最出圈的特性。演进路线走了两年:
- v22.6.0:
--experimental-strip-types实验引入 - v23.6.0:默认开启
- v25.2.0 / v24.12.0:标记 Stable
- v26.0.0:连
--experimental-transform-types都移除了,只保留稳定的类型剥离
// app.ts —— Node 26 直接运行:node app.ts
interface User { id: number; name: string }
const u: User = { id: 1, name: 'fish' };
console.log(process.features.typescript); // → "strip"
注意它做的是类型剥离(strip),不是编译。所以 enum、带运行时代码的 namespace、参数属性这类需要代码生成的语法会直接抛 ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX——官方的迁移建议是用 tsx 这类第三方加载器。
2. Temporal 日期时间 API 默认启用
被吐槽了十几年的 Date,终于有官方继任者了。v26 起 Temporal 全局默认可用:
new Temporal.PlainDate(2026, 11, 14).toString(); // → "2026-11-14"
Temporal.Now.plainDateISO().toString(); // → 今天
时区、日历、不可变对象、精确到纳秒,都是 Date 的痛点。社区好评归好评,两个槽点也很统一:和 Temporal.io 的工作流 SDK 撞了名字;Safari 是唯一还没支持的浏览器,全端使用还差一口气。
3. Permission Model 转正,还多了个审计模式
--permission 沙箱不再是实验特性,权限覆盖 fs、net、child-process、worker、addons、wasi、ffi、openssl-store 八类。
更实用的是 v25.8.0 新增的审计模式:只上报不拦截,先摸清你的应用到底要哪些权限,再收紧:
# 第一步:审计模式,只记录不拦截
node --permission-audit app.js
# 控制台会输出类似:{ "permission": "FileSystemRead", "resource": "target.txt" }
# 第二步:按审计结果收紧
node --permission --allow-fs-read=./ app.js
# 越权访问直接抛 ERR_ACCESS_DENIED
4. V8 升到 14.6,新语法开箱即用
Node 26 内置 V8 14.6.202(对应 Chromium 146),几个新语法默认可用:
const m = new Map([['a', 1]]);
m.getOrInsert('b', 42); // → 42,Upsert 提案
Iterator.concat([1], [2]).toArray(); // → [1, 2]
另外 node:sqlite 升到 Release Candidate(Stability 1.2),无需任何 flag:
const { DatabaseSync } = require('node:sqlite');
const db = new DatabaseSync(':memory:');
db.exec('CREATE TABLE t(v TEXT)');
db.prepare('INSERT INTO t VALUES (?)').run('hi');
console.log(db.prepare('SELECT v FROM t').get()); // → { v: 'hi' }
小工具们也都稳了:node:test 测试运行器 Stable、--watch 稳定、Undici 升到 8.x。
三、升级前必须知道的坑
1. 原生插件 ABI 从 137 跳到 147
V8 大版本升级导致 NODE_MODULE_VERSION 从 137 跳到 147。所有用 NODE_MODULE 宏直接对接 V8 的原生 C++ 插件,在 Node 26 下 require 直接报错,必须重编译。
好消息:走 Node-API 的插件实测不受影响,这也是现在写原生插件的正确姿势。自查一行命令:
node -p "process.versions.modules" # Node 24 → 137,Node 26 → 147
社区还有人提醒:原生插件的预编译适配通常滞后 LTS 标签几周,别在接棒当天就冲。
2. —experimental-transform-types 整个没了
v26 执行这个 flag 直接 bad option。如果你的项目靠它跑 enum 这类需要代码生成的 TS 语法,升级就挂。方案很明确:换 tsx。
3. 一批 API 硬移除,GCM 短标签直接抛错
http.ServerResponse.prototype.writeHeader()(少个 d 的那个老 API)已移除,改用writeHead()- 全部
_stream_*内部流模块报ERR_UNKNOWN_BUILTIN_MODULE - GCM 加密注意:DEP0182 转 End-of-Life,
setAuthTag()不再接受短于 16 字节的认证标签,除非显式声明:
const { createDecipheriv } = require('node:crypto');
// 修复:短标签必须显式传 authTagLength
const d = createDecipheriv('aes-256-gcm', key, iv, { authTagLength: 8 });
- corepack 不再随 Node 出货,pnpm/yarn 要自己装了——这是 HN 上情绪最强烈的不满
type: "module"包里require()无扩展名文件的旧例外取消,按 ESM 解析,依赖旧写法的包(如 yargs v17)会响亮报错
📌 Docker 用户重点:把 FROM node:lts 改成钉精确版本 FROM node:26.13.1,再用 Renovate/Dependabot 走 PR 升级——LTS 接棒当天的翻车帖,几乎全是浮动标签惹的祸。
四、社区吵什么
性能叙事是分裂的。一份开源可复现的社区基准(对比 24.15.0 / 25.9.0 / 26.2.0)显示:合成真实应用里 Node 26 双优,p95 延迟 1.65ms 三者最低、峰值内存 273MB 也最低;但定向微基准有输面——HTTP GET 吞吐比 24 低约 7%,字符串拼接跌 32%;而整数循环快了约 9.5 倍,这是 V8 升级的红利。
Bun 在后面猛追。Bun 1.4 直接拿 Node v26.3.0 官方测试套件对表,新增 1517 项通过,自测数据里启动速度 5.1ms vs 27.2ms、安装依赖 1.41s vs 18.1s——当然对比口径是 Bun 自己定的,看个热闹。
生态跟进很快:Vercel 已把 26.x 设为新项目默认运行时;Vite 8 和 Next.js 16 的最低要求都还停在 Node 20/22,不升 26 也能用。
基本盘还在涨:2026 年前 7 个月 Node.js 下载量 46.1 亿次,已超 2025 全年。
总结
这次大版本更新,一句话概括:Node 26 接棒 LTS,同时 Node.js 进入一年一版的新纪元。
给你的行动清单:
- 生产环境:钉精确版本号,别用浮动
node:lts标签 - 升级 Node 26 前:跑一遍
process.versions.modules自查原生插件,GCM 短标签代码先改 - 本地开发:现在就装 Node 26,
node app.ts直接跑 TypeScript 的体验值得立刻上手 - 明年 4 月 22 日:Node 27.0.0 正式发布,那就是一年一版新节奏的第一个成品
版本规则改了,但方向是好的——更少的维护线、更长的支持期、更稳定的预期。这波不亏。
欢迎关注公众号 FishTech Notes,一块交流使用心得!