该条目用于编写和审查 Node.js 代码,重点在单线程事件循环这一约束下的取舍:engines.node 决定可以写什么,API 的稳定性索引决定能否依赖,加依赖前先查标准库。
版本与稳定性:应读 package.json 的 engines.node 作为下限,运行时并不强制(npm 仅在 engine-strict=true 时检查)。版本支持窗口及逐版本特性(require(esm)、node --run、fs.glob、WebSocket、权限模型、node:sqlite、类型剥离、--env-file、Temporal 等)在条目中按 20/22/24/26 列出;奇数版本不作为下限。API 稳定性分 2 Stable、1 Experimental(1.2/1.1/1.0)、3 Legacy、0 Deprecated,实验性 API 可无弃用周期直接被删除,不应出现在已发布库的公开接口。
模块与包:建议每个 package.json 声明 type;.mjs/.cjs 覆盖 type;解析器不做扩展名搜索与目录索引;内置模块通过 node: 导入;import.meta.dirname/filename 仅对 file: 模块有效;assert 导入属性形式在 22.0.0 移除。exports 会封闭包,条件顺序即匹配顺序,default 放最后、types 放最前,target 必须以 ./ 开头;跨 require/import 可用 module-sync 代替双构建;imports 键以 # 开头。
TypeScript:Node 只做类型语法擦除,不编译、不类型检查、不读 tsconfig.json,应保留 tsc --noEmit;类型导入必须用 import type;说明符要写真实扩展名;enum、带运行时代码的 namespace、参数属性、导入别名会抛 ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX;装饰器报 SyntaxError;node_modules 下的 .ts 一律不加载。
阻塞与流:请求路径上避免同步文件、进程、加密调用;解析前限制输入大小;避免回溯正则、递归 nextTick;长同步循环用 setImmediate 分块或移到 worker。流用 stream/promises 的 pipeline 组合,处理 write() 返回值,出错时 destroy,未处理的 error 会崩溃;readable 的 map/filter 等仍为实验性。
错误与退出:用 process.exitCode 让事件循环自然结束;匹配 error.code;用 cause 链;uncaughtException 后不应继续;未处理拒绝默认致命;exit 监听器只同步执行;取消用 AbortSignal,注意 AbortError 与 TimeoutError 的差异;设置 requestTimeout 与 keepAliveTimeout。此外还涉及 AsyncLocalStorage、diagnostics_channel、事件循环延迟测量、HTTP 客户端(undici 需消费或取消响应体,fetch 不因非 2xx 拒绝、无总超时、忽略代理环境变量)等。各主题引用的参考文件(versions/node-NN.md、conventions/ 下的 modules、typescript-execution、concurrency、streams、lifecycle、observability 等)为技能内部资料。