资讯中心

Node.js 12.17.0(LTS)发布深度解读:ESM 去标志、AsyncLocalStorage 与 REPL 全面增强

📅 2026/9/18 16:23:27
Node.js 12.17.0(LTS)发布深度解读:ESM 去标志、AsyncLocalStorage 与 REPL 全面增强
Node.js 12.17.0LTS发布深度解读ESM 去标志、AsyncLocalStorage 与 REPL 全面增强【免费下载链接】nodejs.orgThe Node.js® Website项目地址: https://gitcode.com/GitHub_Trending/no/nodejs.org本指南基于 nodejs.org 仓库收录的官方发布说明v12.17.0.md系统梳理 Node.js 12.17.0LTS的核心变更--experimental-modules标志的移除、AsyncLocalStorage异步上下文 API、REPL 的三项交互增强、错误监控新机制、文件系统与调试工具改进以及 N-API 6 与诊断报告的稳定性升级。读完本文你将理解这些 API 的适用场景与用法并能直接复用文中的可运行代码示例。发布背景与版本定位Node.js 12.17.0 由 Michaël Zasso 于 2020 年 5 月 26 日发布属于 Node.js 12 LTS长期支持系列的常规更新发布说明中将其归类为release类别对应本仓库中 apps/site/pages/en/blog/release/ 目录下的官方发布记录。该版本在语义化版本上包含大量semver-minor向后兼容的新特性与semver-patch缺陷修复提交并升级了关键依赖libuv 升至 1.37.0、ICU 升至 67.1同时切换为 Chromium 维护的 zlib 实现。在 nodejs.org 网站仓库中这类发布说明以 Markdown 源文件 YAML frontmatter 的形式维护date、category、title、layout: blog-post、author等字段由 scripts/blog-data/generate.mjs 通过gray-matter解析出标题、作者、日期与分类并生成/blog/{category}/{文件名}形式的 slug见该文件第 21-48 行最终通过 layouts/Post.tsx 的blog-post布局渲染为博客页面——这解释了为什么你看到的发布说明 URL 总是形如/blog/release/v12.17.0。ECMAScript Modules移除--experimental-modules标志自 12.17.0 起使用 ESM 不再需要--experimental-modules标志。这是一个重要的里程碑此前必须以node --experimental-modules app.mjs启动程序现在直接运行node app.mjs即可。但请注意以下关键边界实现仍是实验性的。按 Node.js 稳定性指数Stability Index的约定该特性不受语义化版本规则约束未来任何版本都可能出现不向后兼容的变更或被移除。生产环境使用需谨慎。运行时警告仍会输出。与 Node.js 14 不同在 12.x 中只要 ESM 模块作为应用入口被使用或首次调用动态import()就会打印一条实验性警告ExperimentalWarning。官方预期在 2020 年晚些时候可能 10 月底即 Node.js 14 转正为 LTS 时移除该警告。与转译工作流的差异。Node.js 原生 ESM 的实现目标有两个规范符合性Spec Compliance与Web 兼容性Web Compatibility。因此它并不支持大多数转译工具链中习以为常的能力例如从 CommonJS 模块导入具名导出named exports from CJS省略文件扩展名extensionless importsJSON 模块导入。这意味着从 Babel/TypeScript/打包器生态迁移过来的模块大概率需要一定程度的重构才能直接在 Node.js 中运行。官方认为当前实现为编写 ESM 模块提供了面向未来的模型是通往 Universal JavaScript 的关键一步。相关核心提交为 esm: unflag --experimental-modulesPR #29866。AsyncLocalStorage跨异步操作携带上下文async_hooks模块新增了实验性的AsyncLocalStorage类允许在异步操作链中保持上下文。典型场景为每个进入服务器的 HTTP 请求存一个序列 ID之后无需访问请求对象即可取回该 ID。发布说明给出了完整示例const http require(http); const { AsyncLocalStorage } require(async_hooks); const asyncLocalStorage new AsyncLocalStorage(); function logWithId(msg) { const id asyncLocalStorage.getStore(); console.log(${id ! undefined ? id : -}: , msg); } let idSeq 0; http .createServer((req, res) { asyncLocalStorage.run(idSeq, () { logWithId(start); // Imagine any chain of async operations here. setImmediate(() { logWithId(finish); res.end(); }); }); }) .listen(8080);在上例中即使有多个请求并行处理logWithId也始终能知道当前请求的 IDrun(store, callback)在回调及其触发的所有异步后继中注入存储值getStore()在任意深度异步代码中取回它。这正是分布式追踪、请求级日志串联的基础能力。典型使用场景日志为每个请求关联 request-id贯穿整条异步调用链用户身份识别中间件内写入用户上下文业务代码中直接读取性能追踪记录每次操作的耗时与归属请求错误追踪与处理异常发生时仍能定位到产生它的原始上下文以及其他一切隐式传递上下文的需求。该版本同时引入了一批配套的 semver-minor 提交来完善这一 API新增同步的enterWith()PR #31945、合并run/exit方法PR #31950、防止存储同步方法退出外层上下文、新增executionAsyncResourcePR #30959并修复了嵌套 ALS 调用后上下文丢失的问题PR #32085。注意该 API 仍是实验性的部分方法可能在后续版本中变化后续 Node.js 版本也确实将其演进了稳定 API。首个实现由 Vladimir de Turckheim 贡献PR #26540。REPL 交互体验的三项升级输入预览previewsREPL 现在支持类似 Chrome DevTools 控制台的预览当后续输入可预测时会插入一条建议作为预览可按TAB或RIGHT光标位于输入末尾时接受建议输入变量名或调用无副作用的函数时还会预览其输出值。要亲自体验只需在终端直接运行node不带任何参数进入 REPL。相关提交包括支持 eager evaluation 的预览PR #30811与补全预览PR #30907并附带大量补丁修复长行、光标位置、粘贴时不应预览等边界情况如 PR #31293、#31315、#32154。双向反向搜索reverse-i-searchREPL 支持类似 Zsh 的双向反向搜索ctrl R向后搜索历史ctrl S向前搜索历史按下任何与反向搜索无关的按键即接受当前条目按escape或ctrl C取消切换方向会立即从当前位置按新方向继续搜索下一条匹配。该功能由 readline/repl 的底层重构支撑PR #31006配套提交还包括改进 Unicode 支持与 Tab 补全PR #31288。基于子串的历史搜索现在可以快速访问历史条目输入曾经输入过的代码的开头几个字符再按UP或DOWN即可在以这些字符开头的历史条目中导航行为类似 Fish Shell 的子串历史搜索PR #31112。该提交还顺带让 readline 跳过与当前行完全相同的历史条目、改进宽度计算与 Unicode 支持。错误监控只观察、不消费EventEmitter.errorMonitor在 EventEmitter 上可以用符号EventEmitter.errorMonitor安装监听器观察error事件而不消费它——即不会改变未处理 error 会抛出并崩溃进程的默认语义const myEmitter new MyEmitter(); myEmitter.on(EventEmitter.errorMonitor, err { MyMonitoringTool.log(err); }); myEmitter.emit(error, new Error(whoops!)); // Still throws and crashes Node.js这对 APM、日志类工具极其有价值可以在不改变应用错误处理语义的前提下静默采集所有 error 事件。相关提交为 events: allow monitoring error eventsPR #30932并将errorMonitor从符号转换为普通属性以保持可序列化等特性PR #31848。process.on(uncaughtExceptionMonitor)同理现在可以监听uncaughtExceptionMonitor事件来监视未捕获异常同时不覆盖进程退出的默认行为process.on(uncaughtExceptionMonitor, (err, origin) { MyMonitoringTool.logSync(err, origin); }); // Intentionally cause an exception, but do not catch it. nonexistentFunc(); // Still crashes Node.js回调收到(err, origin)两个参数其中origin标明异常的来源如uncaughtException或unhandledRejection。相关提交为 process: allow monitoring uncaughtExceptionPR #31257。文件系统 API 增强新增fs.readv新增fs.readv()及其同步、Promise 版本接收一个ArrayBufferView数组将读到的数据按顺序依次写入这些缓冲区即一次系统调用读入多个不连续缓冲区scatter read由 Sk Sajidul Kadir 贡献PR #32356const { readv } require(fs/promises); const buffers [Buffer.alloc(10), Buffer.alloc(20)]; const { bytesRead } await readv(fd, buffers);fs.read参数可选化fs.read及其同步、Promise 版本新增重载允许可选地省略offset、length、position中的任意参数PR #31402同步版本见 PR #32460并修复了传入null值的边界问题PR #32479。Console 与 util 调试能力改进Console的groupIndentation选项console.Console构造函数现在支持自定义分组缩进宽度默认是 2 个空格当需要其他分组宽度时非常有用const { Console } require(console); const customConsole new Console({ stdout: process.stdout, stderr: process.stderr, groupIndentation: 10, }); customConsole.log(foo); // foo customConsole.group(); customConsole.log(foo); // foo相关提交为 console: support console constructor groupIndentation optionPR #32964。util.inspect()的maxStringLength选项util.inspect()现在支持通过maxStringLength限制被检查对象中字符串的显示长度避免超大字符串刷屏const { inspect } require(util); const string inspect([a.repeat(1e8)], { maxStringLength: 10 }); console.log(string); // [ aaaaaaaaaa... 99999990 more characters ]注意在提交记录中该选项曾以maxStrLength名称引入PR #32392最终对外文档化为maxStringLength。稳定性升级N-API 6 与诊断报告N-API 6 转为稳定以下 N-API 特性随 N-API 6 发布正式稳定对原生插件作者而言意味着 ABI 层面的长期承诺相关提交为 n-api: define release 6PR #32058napi_set_instance_data/napi_get_instance_data在模块实例上存取任意数据napi_key_collection_mode、napi_key_filter、napi_key_conversion对象属性枚举的键控选项napi_create_bigint_int64、napi_create_bigint_uint64、napi_create_bigint_words从不同整数形式创建 BigIntnapi_get_value_bigint_int64、napi_get_value_bigint_uint64、napi_get_value_bigint_words读取 BigInt 值napi_get_all_property_names获取对象全部属性名PR #30006。诊断报告Diagnostic Report稳定化诊断报告功能正式转正为稳定特性并新增--report-compact标志可将报告写成紧凑的单行 JSON比默认的、面向人类阅读的多行格式更便于日志处理系统消费。同时--report-on-fatalerror移入稳定范畴PR #32496--experimental-report成为 no-op--without-report构建选项同样不再生效PR #32242——这标志着诊断报告从实验走向生产可依赖。默认超时与安全默认值调整server.headersTimeout默认值提升至 60 秒http与https服务器的server.headersTimeout默认值从4000040 秒提升至6000060 秒以适配 AWS ELB 等负载均衡器 60 秒超时的场景PR #30071。同时修复了当该值被显式设为0时仍会进行检查的问题PR #33307。对部署在云负载均衡后方的服务这一调整可减少健康检查与慢客户端场景下的连接中断。其他值得关注的变更cli新增--trace-sigint标志按下 CtrlC 时打印当前执行栈PR #29207--huge-max-old-generation-size现在可放入NODE_OPTIONS环境变量PR #32251。crypto多个 crypto API 支持 Diffie-Hellman 秘密包括新增的crypto.diffieHellman()以及generateKeyPair对dh密钥类型的支持PR #31178。dns新增dns.ALL标志可与dns.V4MAPPED一起传给dns.lookup()同时返回解析出的 IPv6 地址与 IPv4 映射的 IPv6 地址PR #32183。module新增实验性 API 用于交互 Source Map V3 数据PR #31132并从 Chromium 移植了 source map 排序逻辑PR #31927。workerWorker构造函数支持同时传入transferList与workerDataPR #32278、支持 URL 形式的工作脚本PR #31664并可从父线程触发堆快照PR #31569。perf_hooksGCPerformanceEntry新增属性标志PR #29547processmemoryUsage()报告 ArrayBuffer 内存PR #31550。vmSourceTextModule支持 code cachePR #31278wasi新增returnOnExit选项PR #32101。lib新增选项可在某些对象上禁用__proto__PR #32279esm改进模块未找到时对 CommonJS 的提示PR #31906。发布物与完整性校验v12.17.0 提供了覆盖 Windowsx86/x64 安装包与二进制、macOSpkg 安装包与 darwin-x64 二进制、Linuxx64、PPC LE、s390x、ARMv7、ARMv8、AIX、SmartOS 的全平台发布物并附带了 PGP 签名的 SHASUMS 清单SHA-256。实践建议下载后务必用官方公钥校验 PGP 签名并核对 SHA-256 校验和确保二进制未被篡改。从发布说明到网站内容nodejs.org 的发布博客机制本文所解读的发布说明本身就是 nodejs.org 网站的内容即代码实践每篇 release 博文都是 apps/site/pages/en/blog/release/ 下的 Markdown 文件通过 generate.mjs 流式读取并解析 frontmatterdate、category、title、author自动归类到release、year-2020、all三个分类下参与博客列表与分页渲染层则由 layouts/Post.tsx 完成展示标题、作者头像组WithAvatarGroup与元信息栏WithMetaBarBlogPostCard 则在列表页以卡片形式呈现。若希望从源码层面追踪某一特性的演进可以在该目录下对比后续版本如 v12.18.1、v13.10.1的发布说明观察同一 API 的稳定性变化轨迹。【免费下载链接】nodejs.orgThe Node.js® Website项目地址: https://gitcode.com/GitHub_Trending/no/nodejs.org创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案