Node.js 22/23 新特性盘点:原生技能树又点亮了不少
年初把服务器的 Node 从 18 升到了 22 LTS。升级过程中把这两个版本的 changelog 完整翻了一遍,发现不少"以前要装包,现在原生就有"的特性。挑值得关注的整理一篇。
require() 可以加载 ESM 了
CommonJS 和 ESM 双轨制折磨了社区五年。Node 22 迈出了历史性的一步:
// 以前:CJS 里 require ESM 模块直接报错
// ERR_REQUIRE_ESM: require() of ES Module ... not supported
// Node 22:可以了!(模块里没有顶级 await 的前提下)
const lodash = require('lodash-es')
对库作者意义更大:以后可以只发 ESM 一份产物,CJS 用户也能用。双构建(.cjs + .mjs)的时代终于看到了终结的曙光。
内置 WebSocket 客户端
以前 Node 里连 WebSocket 要装 ws 库,现在原生全局可用,API 和浏览器一致:
// 不用 npm install ws
const socket = new WebSocket('wss://example.com/feed')
socket.addEventListener('open', () => {
socket.send(JSON.stringify({ type: 'subscribe', channel: 'prices' }))
})
socket.addEventListener('message', (event) => {
console.log('收到:', JSON.parse(event.data))
})
注意这是客户端能力。做 WebSocket 服务端还是要用 ws 库。对写实时数据订阅脚本、跨服务推送的消费者来说,少一个依赖。
内置 SQLite:node:sqlite
Node 22.5 加入的实验性内置数据库:
const { DatabaseSync } = require('node:sqlite')
const db = new DatabaseSync(':memory:')
db.exec(`
CREATE TABLE todos (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
done INTEGER DEFAULT 0
)
``)
const insert = db.prepare('INSERT INTO todos (title) VALUES (?)')
insert.run('写一篇 Node 22 盘点')
const rows = db.prepare('SELECT * FROM todos').all()
console.log(rows) // [ { id: 1, title: '写一篇 Node 22 盘点', done: 0 } ]
写 CLI 工具、本地脚本、单元测试需要个轻量存储时,不用再装 sqlite3(那个原生编译的坑装过的人都懂)。目前还是实验特性(要 --experimental-sqlite),生产慎用,但方向很明确。
其他实用更新速览
glob 原生支持(fs.glob,22.0):
const { glob } = require('node:fs/promises')
// 以前要装 glob 或 fast-glob
for await (const file of glob('src/**/*.test.js')) {
console.log(file)
}
ArrayBuffer 转移与更多 V8 新语法:Node 22 内置 V8 12.4,Array.fromAsync、Object.groupBy、Promise.withResolvers 全都稳定可用:
// Promise.withResolvers:在外部控制 promise 的 resolve/reject
const { promise, resolve, reject } = Promise.withResolvers()
setTimeout(() => resolve('搞定'), 1000)
await promise
// Object.groupBy:按条件分组,以前靠 lodash
const todos = [
{ title: '写文', done: true },
{ title: '健身', done: false },
{ title: '读书', done: true },
]
Object.groupBy(todos, (t) => (t.done ? 'done' : 'pending'))
// { done: [...], pending: [...] }
watch 模式稳定(22.0):node --watch server.js 文件变化自动重启,开发小项目连 nodemon 都省了。配合之前版本的 --env-file、--test(内置测试 runner),Node 的"原生技能树"越来越全。
Node 23 的非 LTS 尝鲜
23 是奇数版本(不会转 LTS),主要是给 24 预演:
require(esm)默认开启(22 里要 flag)- 移除了 32 位 Windows 支持等历史包袱
生产环境别追奇数版,等今年 10 月的 Node 24 LTS 即可。
升级建议
- 生产项目:18 → 22 LTS,别跳奇数版
- 升级前跑一遍测试,重点查原生模块(bcrypt、sharp 这类要重新编译)
- 本地开发可以开始用
--watch和原生--env-file替代 nodemon + dotenv - 库里还在双构建的作者,可以关注 require(esm) 的普及度,时机成熟就砍 CJS 产物
小结
- require 加载 ESM 是历史性和解,双构建时代进入倒计时
- 原生 WebSocket 客户端、内置 SQLite、fs.glob,三个"少装一个包"
Promise.withResolvers、Object.groupBy等 V8 新语法已稳定- 生产升 22 LTS,奇数版只用来尝鲜
Node 这几年的方向很清晰:把社区验证过的刚需能力一个个收编进原生。对开发者来说,最直观的好处就是 package.json 越来越短了。
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~