Node.js v16.12.0(Current)发布全解析:实验性 ESM Loader Hooks 整合与发行资产解读
【免费下载链接】nodejs.orgThe Node.js® Website项目地址: https://gitcode.com/GitHub_Trending/no/nodejs.org
Node.js v16.12.0 是发布于 2021 年 10 月 20 日的 Current 版本,其最核心的技术变化是实验性 ESM Loader Hooks API 的整合——将原有分散的 hooks 收敛为resolve与load两个阶段,为未来 loader 链式组合(loader chaining)铺平道路;同时该版本还随附 npm 8.1.0 升级、vm模块对动态导入 import assertions 的支持等多项变更。阅读本文,你将完整掌握 v16.12.0 的变更清单、发行资产与 SHA-256 校验方式,并了解这类发布公告在 nodejs.org 仓库中是如何被自动生成、索引与渲染上线的。
本文以仓库中的原始发布公告 apps/site/pages/en/blog/release/v16.12.0.md 为主体展开,并结合仓库内发布脚本与博客渲染链路源码进行纵深解读。
版本概况与定位
该公告的 Frontmatter 明确记录了版本的基本元信息:
| 字段 | 值 | 说明 |
|---|---|---|
date | 2021-10-20T14:44:30.011Z | 发布公告的 UTC 时间戳 |
category | release | 博客分类,对应/blog/release路由 |
title | Node.js 16.12.0 (Current) | 版本与发行线状态 |
layout | blog-post | 决定渲染时使用的布局组件 |
author | Richard Lau | 本次发布的发布负责人 |
"Current" 意味着该版本处于当前的常规发布通道(而非 LTS 维护通道),适合希望跟进最新特性的开发者尝鲜使用。从仓库结构看,这类发布公告统一存放在pages/en/blog/release/目录下,同一目录共存有 800 余个历史版本的公告,构成了完整的版本发布档案。
核心亮点:实验性 ESM Loader Hooks API 整合
v16.12.0 最重要的技术变更是 ESM Loader Hooks(加载器钩子)的整合(consolidation)。其动机是让每个 hook 精确对应加载流程中的一个步骤,从而支撑未来的 loader 链式组合。整合后的映射关系如下:
resolve:由原resolve+getFormat合并而成;load:由原getFormat+getSource+transformSource合并而成。
同时,为了命名一致,getGlobalPreloadCode被重命名为globalPreload。
这一调整对自定义 ESM loader 的作者影响直接:
- 旧 hook 名将触发弃用警告:如果一个 loader 导出了已废弃的 hook(例如
getSource、transformSource、getGlobalPreloadCode),Node.js 会针对该 loader 触发一次统一的弃用警告(per-loader),并在警告中列出所有"违规"的 hook,便于一次性修复,而不是每个 hook 各警告一次; - 行为上兼容过渡:整合后的
resolve与load承担了原先多个 hook 的职责,旧式导出会在警告后继续按兼容路径工作,给生态迁移留出窗口。
该变更由 Jacob Smith、Geoffrey Booth 与 Bradley Farias 共同贡献,对应 Node.js 主仓库 PR #37468,属于(SEMVER-MINOR)级变更——即向后兼容的新特性,这也是它能进入 Current 小版本而非等待大版本的原因。同期提交中还有一条doc: correct ESM load hook table header(PR #40234),说明文档中 ESM load hook 表格的表头也随之修正,体现了"代码变更 + 文档同步"的发布纪律。
其他值得关注的变化
除 Loader Hooks 外,公告的 "Other Notable Changes" 部分还列出了三项对开发者有感知的变化:
| 变更 | 类型 | 说明 |
|---|---|---|
| 升级 npm 至 8.1.0(PR #40463) | deps | 随 Node.js 分发的包管理器从 npm 7 系升入 8.1.0 |
| 弃用(仅文档)http abort 相关 API(PR #36670) | doc | 对 http 模块中 abort 相关接口进行doc-only弃用标记,即只更新文档标注、不改动运行时行为 |
vm模块:动态导入支持 import assertions(PR #40249) | vm(SEMVER-MINOR) | import()动态导入可携带 import assertions 参数,配合vm.SourceTextModule等能力使用 |
需要特别说明的是 "doc-only" 弃用的含义:它只在文档层面标记某 API 为 deprecated,不会触发运行时的DeprecationWarning,也不改变现有代码行为,主要目的是提前告知生态该 API 未来可能移除,属于低风险的渐进式弃用策略。
此外,从完整提交清单中还可以看到几项对日常开发有影响的变化:
- Corepack 升级至 0.10(PR #40374):内置的包管理器协调工具 Corepack 随版本更新;
- stream 修复
fromAsyncGen(PR #40499):修复异步生成器转换流的相关缺陷; - net 模块重构(PR #40344):对
Socket的对象模式(objectMode)判断、undefined选项检查等进行了多处重构与错误处理加固; - tools 升级 ESLint 至 8.0.0(PR #40394):Node.js 自身构建工具链中的 ESLint 主版本升级,并同步清理了多个 Babel 语法插件。
提交清单全览(按模块归类)
公告的 Commits 部分共收录 59 条提交。为便于检索,下表按模块归类完整罗列(保留原始提交哈希、作者与 PR 编号):
| 模块 | 提交哈希 | 内容 | 作者 | PR |
|---|---|---|---|---|
| build | 8bb3951e41 | remove duplicate check for authors.yml | Rich Trott | #40393 |
| build | 2de57edced | make scripts in gyp run with right python | Cheng Zhao | #39730 |
| crypto | a8926d199d | remove incorrect constructor invocation | gc | #40300 |
| deps | 8fdabcb918 | upgrade npm to 8.1.0 | npm team | #40463 |
| deps | dca5ac1539 | suppress zlib compiler warnings | Daniel Bevenius | #40343 |
| deps | 91c3bf6a7f | upgrade Corepack to 0.10 | Maël Nison | #40374 |
| dgram | 7e02124a06 | addnreadassertion toUDPWrap::OnRecv | Darshan Sen | #40295 |
| dns | 2d409ed29e | refactor and use validators | Voltrex | #40022 |
| doc | dc7291dab8 | remove ESLint comments breaking CJS/ESM toggles | Mark Skelton | #40408 |
| doc | 85b7385115 | add pronouns for tniessen to README | Tobias Nießen | #40412 |
| doc | 1d5857c9f4 | format changelogs | Rich Trott | #40388 |
| doc | 5eb9402b50 | fix missing variable in deepStrictEqual example | OliverOdo | #40396 |
| doc | 6f77d1a1d5 | fix asyncLocalStorage.run() description | Constantine Kim | #40381 |
| doc | 93a48e02dc | fix typos in n-api docs | Ignacio Carbajo | #40402 |
| doc | fb7afb91c2 | format doc/guides using format-md task | Rich Trott | #40358 |
| doc | 6c091c7878 | improve phrasing in fs.md | Arslan Ali | #40255 |
| doc | 38d81380ac | add link to core promises tracking issue | Michael Dawson | #40355 |
| doc | 71a94aa82a | correct ESM load hook table header | Jacob Smith | #40234 |
| doc | 5b074affb4 | fix typo in esm.md | Mason Malone | #40273 |
| doc | 3b3aaa0a37 | fix typo in ESM example | Tobias Nießen | #40275 |
| doc | f848553fb8 | assign missing deprecation number | Michaël Zasso | #40324 |
| doc | d1d9f2de30 | deprecate (doc-only) http abort related | dr-js | #36670 |
| doc | 1ef2cf8413 | anchor link parity between markdown and html-generated docs | foxxyz | #39304 |
| esm | 3743406b0a | (SEMVER-MINOR)consolidate ESM loader hooks | Jacob Smith | #37468 |
| lib | 168020e1c8 | refactor to use let | gdccwxx | #40364 |
| meta | bcd59d70bb | consolidate AUTHORS entries for gabrielschulhof | Rich Trott | #40420 |
| meta | 80b4245db8 | consolidate AUTHORS information for geirha | Rich Trott | #40406 |
| meta | 93cecb4700 | consolidate duplicate AUTHORS entries for hassaanp | Rich Trott | #40391 |
| meta | fff3135909 | update AUTHORS | Node.js GitHub Bot | #40392 |
| meta | 122481713d | consolidate AUTHORS entry for thw0rted | Rich Trott | #40387 |
| meta | 7f50313fcc | update label-pr-config | Mestery | #40199 |
| meta | 5668182665 | use .mailmap to consolidate AUTHORS entries for ide | Rich Trott | #40367 |
| net | bc86084a3e | check if option is undefined | Daijiro Wachi | #40344 |
| net | 4564a93e5e | remove unused ObjectKeys | Daijiro Wachi | #40344 |
| net | dbb2e6f429 | check objectMode first and then readble || writable | Daijiro Wachi | #40344 |
| net | a672be57c8 | throw error to object mode in Socket | Daijiro Wachi | #40344 |
| src | faf9e28c36 | remove usage ofAllocatedBufferfromstream_* | Darshan Sen | #40293 |
| src | 857af2ba99 | add missing initialization | Michael Dawson | #40370 |
| stream | 2bfa87edbc | fix fromAsyncGen | Robert Nagy | #40499 |
| test | 1e15137e71 | replace common port with specific number | Daijiro Wachi | #40344 |
| test | 6f6b99c302 | fix typos in whatwg-webstreams explanations | Tobias Nießen | #40389 |
| test | 641b1bb052 | add test for readStream.path when fd is specified | Qingyu Deng | #40359 |
| test | 07dae7ff50 | replace .then chains with await | gdccwxx | #40348 |
| test | d8a36ee1de | fix "test/common/debugger" identify async function | gdccwxx | #40348 |
| test | 13d6a56c7d | improve test coverage offs.ReadStreamwithFileHandle | Antoine du Hamel | #40018 |
| tools | 50f91ab059 | udpate @babel/eslint-parser | Rich Trott | #40394 |
| tools | 3611073145 | remove @babel/plugin-syntax-import-assertions | Rich Trott | #40394 |
| tools | b72d693a3a | remove @bable/plugin-syntax-class-properties | Rich Trott | #40394 |
| tools | d6a99b77da | remove @babel/plugin-syntax-top-level-await | Rich Trott | #40394 |
| tools | d9157aa5fe | update ESLint to 8.0.0 | Rich Trott | #40394 |
| tools | 43b97c7984 | prepare ESLint rules for 8.0.0 requirements | Rich Trott | #40394 |
| tools | 282b6eb4b0 | fix ESLint update scripts | Rich Trott | #40394 |
| tools | c3a744f7bf | warn about duplicates when generating AUTHORS file | Rich Trott | #40304 |
| typings | 7733b5e55d | define types for os binding | Michaël Zasso | #40222 |
| typings | ca9a854877 | add missing types to options and util bindings | Michaël Zasso | #40222 |
| typings | c3a7a0bd59 | define types for timers binding | Michaël Zasso | #40222 |
| typings | 65b51d05fa | fix declaration of primordials | Michaël Zasso | #40222 |
| v8 | 5f3f3a5128 | remove --harmony-top-level-await | Geoffrey Booth | #40226 |
| vm | 4116b6c907 | (SEMVER-MINOR)add support for import assertions in dynamic imports | Antoine du Hamel | #40249 |
从这份清单可以观察到发布的质量信号:test与doc类提交占比很高,说明该版本在功能之外同步进行了大量测试补充与文档修订;tools与typings类提交则体现了 Node.js 自举(self-hosting)工具链的持续演进——例如v8模块移除--harmony-top-level-await标志,是因为 Top-Level Await 已默认启用,不再需要 harmony 开关。
发行资产:各平台安装包与二进制
v16.12.0 为全平台发布了发行产物,覆盖 Windows、macOS、Linux、AIX 与源码包,具体清单如下(文件名为发布目录中的实际名称):
| 平台 / 用途 | 发行文件 |
|---|---|
| Windows 32 位安装器 | node-v16.12.0-x86.msi |
| Windows 64 位安装器 | node-v16.12.0-x64.msi |
| Windows 32 位二进制 | win-x86/node.exe |
| Windows 64 位二进制 | win-x64/node.exe |
| macOS 64 位安装器 | node-v16.12.0.pkg |
| macOS Apple Silicon 二进制 | node-v16.12.0-darwin-arm64.tar.gz |
| macOS Intel 64 位二进制 | node-v16.12.0-darwin-x64.tar.gz |
| Linux 64 位二进制 | node-v16.12.0-linux-x64.tar.xz |
| Linux PPC LE 64 位二进制 | node-v16.12.0-linux-ppc64le.tar.xz |
| Linux s390x 64 位二进制 | node-v16.12.0-linux-s390x.tar.xz |
| AIX 64 位二进制 | node-v16.12.0-aix-ppc64.tar.gz |
| ARMv7 32 位二进制 | node-v16.12.0-linux-armv7l.tar.xz |
| ARMv8 64 位二进制 | node-v16.12.0-linux-arm64.tar.xz |
| 源码包 | node-v16.12.0.tar.gz(另提供.tar.xz) |
| 头文件包 | node-v16.12.0-headers.tar.gz/.tar.xz |
| 完整发行目录 | 包含上述全部文件及其他补充文件 |
| API 文档 | v16.12.0 对应的在线 API 文档 |
发布目录中还包含 Windows 平台的node_pdb调试符号包(.7z/.zip)、node.lib导入库、以及win-x64.zip/win-x86.zip等压缩格式,供需要调试本机代码或做免安装分发的场景使用。
安全校验:SHASUMS 与 PGP 签名
发布公告末尾附带了由 Node.js 发布密钥签名的SHASUMS256.txt.asc全文(PGP 签名消息,Hash: SHA256),用于对上述所有发行文件进行完整性校验:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 d45cc55607bdc730aa6b930be4a067bc56568ff92162608f0f5983879024cd5b node-v16.12.0-aix-ppc64.tar.gz 1d681c528205f56531084a09e9648586f91e68726ee73851c8e4b1098df2f603 node-v16.12.0-darwin-arm64.tar.gz 16446b03ce381d396ae14fb821084f4a253545667f233a8857a58195b540b49a node-v16.12.0-darwin-arm64.tar.xz 35ee05c9392742f934a3058fa64837b14e184b26aa9bd621ec499a83f9fdfe67 node-v16.12.0-darwin-x64.tar.gz 260db12cb00b8daf845577e9ba66b9f7f191e9038f2688689d9b188dfdabfc61 node-v16.12.0-darwin-x64.tar.xz 8e42d46d4382cbc1b2eb11bdbc609667569b55da3690b8dbeb64caa95d2a2b5a node-v16.12.0-headers.tar.gz af34cd2110b02a2709882d6196a4e96eedd64a3d6049bc5751d755c8d742a605 node-v16.12.0-headers.tar.xz 2abb224a6d9880d459ed64a02876b5843ca891978b072e7516431b15142a472c node-v16.12.0-linux-arm64.tar.gz b5d6b2e70e4556866e4015997d0915d0eca19576f011e6e8463711da151ed7bd node-v16.12.0-linux-arm64.tar.xz 18dc901dc9c585360fc0dd1ac023eaac61eeb46464a59e821b2171c487a46a0e node-v16.12.0-linux-armv7l.tar.gz a9409df88c328726842f523308014371b603cfa7afdd446a6ad02d464f40c790 node-v16.12.0-linux-armv7l.tar.xz 48c5f2fdaf9938d49e24248727249fbcd4faedbdc9d5e3948cfd00ffb14ba47d node-v16.12.0-linux-ppc64le.tar.gz 9ec2b8d44827dbd1f4f7542c61f169ee4288da1c5a2150249bf38a0e9d330bd3 node-v16.12.0-linux-ppc64le.tar.xz 5313dd3023d53405fcb272af8dba24893d2102ec928bcc817e2a4c571be62fe2 node-v16.12.0-linux-s390x.tar.gz 0b0dc48f1e160006dfd56bf32333102044b1548f0b7a86e5a9378764f574c67c node-v16.12.0-linux-s390x.tar.xz 1f41d5b68ca39eb2e76dad4e5beb8de8b0a1498773e3e53b80c03e42202969fb node-v16.12.0-linux-x64.tar.gz e0e1a54b34db95ca49bb8561ad736750222f54a41aad2c876b9355cacff42ba0 node-v16.12.0-linux-x64.tar.xz 0f777eda63df1f6bc176edd98f3b25252f096a4cf8d52001c1ee1b06d0c6f3b9 node-v16.12.0.pkg bceb8098e276c6bb6b3e88223ed378a6c786491b6a3f6b22ae3fd8774724a9cb node-v16.12.0.tar.gz 5f620a6a400901a6565aa0c07309cde3aab3dbaa765cecb934241de520d36bac node-v16.12.0.tar.xz 3f19469ea095173d998d8a11b3726b04629b02e3e608790475515175d29573b4 node-v16.12.0-win-x64.7z 433206b42522e65ed6c0f30f1d665f336c2bdcfd200286da639c4e91ea602870 node-v16.12.0-win-x64.zip b45d0f934bc6afd4716cf048538df2550de39024ac6e522a15af36bf2114105f node-v16.12.0-win-x86.7z ef2ff38ce68acf8d930bc8cbbc1be82405fa1ac85490a7f92a1ddeba00fa67a6 node-v16.12.0-win-x86.zip d269299d5feb29bc9d5713e9b87f0154ff857bbe6510c76a553568a1bc22badc node-v16.12.0-x64.msi adc0b407f5b856fad4e36ac7b22def93cf01b6f7576404da7c5b6a3992a82236 node-v16.12.0-x86.msi 75e88894b274d91f98bbd2109dd1acfea6f658cfd2045f066dca7145ad745427 win-x64/node.exe 7c94657df6918a77dc8edefaf3b5415dbfb9eb83a88c17d216a48c8c36fcc58d win-x64/node.lib 1edef4e0323fbe13b4c0b97d20fac39a3fcf6b3137933edea0d16caf78c68cec win-x64/node_pdb.7z ee65351b06218b3390e639ff9a5ea51048bcd97d719c52806455d635f77ea10e win-x64/node_pdb.zip d6fd4b983a0f61bd2297d07881241c2629f8326c7445e5d151a09a3fb960f039 win-x86/node.exe 8090f51a19ff2d5e765920262a4367203be2e69e64ac3725e4e14dd034c98443 win-x86/node.lib 188d915991ab21e101a9e321dad7628e6b9acf2be0b1874ae6450225e9ad2d24 win-x86/node_pdb.7z eab8b47522fdeb6ab3a46e26eda7ae5c51729875b0b42f11e0d24d632626a779 win-x86/node_pdb.zip -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEyC+jrhy+3Gvka5NgxDzsRcF6uTwFAmFwKrgACgkQxDzsRcF6 uTyvHw/8D4tGIxl7mccgF17epMxwULXWQVq43A0oonFXPb9LzWXAVzMkJ70YCGzZ EkP2YMjIW/mf/jcE3UoI14loHMR8Y2vk10x8/Y2I5o5D3naWjWEOLyAXb7W8476J LZEWZacS0vQOoCT+qEiRQSDjbJeY+4cBsNsslh5UjdvMs9j1zpU8mPkDLSRMPc/L l9i/lXKnSx+Surb3taRMphgkTGf8EreBoTjg73u283CR3pRlRj0LVE+a+umXcgFf EMDWm+hwN7j8zv6Rm3W0Rw9RCTTZUT7jyuV5bjqoBgkCbyy+V/Za8X8yCOGX9kK4 BV8opcAq1fIatfCUQsHjWGbIN8T1NjtNfjND9sjEfV9SWT7EFue3DaPnbS4Wh4P2 pfERePBMyHI47Ltug6XbNvFmr7huzpe/FUj0pvsxaL27XnQNPmiBQnWNDevPG0vg IKZ2op/4KtnLKDi5cWfNyvs0FL1XxV5jeB3aFDilOCMhUEt+KCrT7C0DTrgDrotT VjgkkNmLtUZR93hMrSkfhqn2VEUui3YyeGtazerSetTfbKII19cvWsOEBSQL9Vsa WD29bsanXhEHL04c8qwb0Wct5tjBbV1Ol7jQewigOJoOAYSDtH4hx/1MZ00MVad3 mfZx8vFjmzg87i26ZV/bTyxjCyaz0IFc4ghuum4OWHrod7cOPAg= =NJOg -----END PGP SIGNATURE-----校验方法建议:下载发行文件后,使用 SHA-256 工具计算本地文件的哈希并与上表对应条目比对。例如在 Linux 或 macOS 上可执行shasum -a 256 node-v16.12.0-linux-x64.tar.xz(Linux 亦可使用sha256sum),确认输出的 64 位十六进制摘要与公告中记录的值完全一致;进一步地,可通过gpg --verify验证上述 PGP 签名块,确保公告内容本身由 Node.js 官方发布密钥签发、未被篡改。
深入仓库:发布公告的生产与渲染链路
理解了公告内容后,再来看这份公告在 nodejs.org 仓库中是如何"诞生"与"上线"的,有助于理解整个版本发布流程的自动化程度。
1. 发布公告的自动生成脚本
仓库中的 apps/site/scripts/release-post/index.mjs 是一个专门用于生成发布公告的命令行工具,其用法为node index.mjs [version]:若不传版本号,脚本会从 Node.js 发行索引中自动选取最新版本(见 index.mjs 的findLatestVersion)。其流水线如下:
fetchDocs(index.mjs):并行获取五个数据源——变更日志正文(changelog body)、发布负责人(author)、版本策略(version policy)、SHASUMS 校验和、以及各平台下载文件的可用性;fetchChangelog(index.mjs):从主仓库的 CHANGELOG 中按<a id="v16.12.0"></a>锚点正则截取对应版本的完整提交段,并自动将*列表项转换为-列表(fetchChangelogBody);fetchVersionPolicy(index.mjs):通过正则^## ?\d{4}-\d{2}-\d{2}, Version ...\(([^)]+)\)从 changelog 标题中提取 "Current"/"LTS" 等版本策略;renderPost与formatPost(index.mjs):将上述数据灌入 Handlebars 模板后,再用 Prettier 按 markdown 语法格式化;writeToFile(index.mjs):写入pages/en/blog/release/v16.12.0.md;若文件已存在且未加--force参数则拒绝覆盖,防止重复发布。
而公告的骨架正是由模板 apps/site/scripts/release-post/template.hbs 定义的:它先输出包含date、category: release、title、layout: blog-post、author的 Frontmatter,再依次拼接 changelog 正文、各平台下载文件清单(每行以\结尾)、以及带 PGP 签名的 SHASUMS 代码块。对照 v16.12.0.md 的正文结构,可以一一对应上模板中的每一段——也就是说,本文解读的这份公告就是该模板的一次真实产物。
2. 博客数据的索引生成
发布公告写入仓库后,apps/site/scripts/blog-data/generate.mjs 会在构建期扫描pages/en/blog下所有 Markdown 文件,仅读取每个文件的 Frontmatter 部分(通过 readline 逐行读取、遇到第二个---分隔符即关闭流,见 generate.mjs),并利用 gray-matter 解析出元信息:
- 分类体系:每篇文章被同时归入三个分类——实际分类(如
release)、发布年份分类(如year-2021)与all(见 generate.mjs); - 文章 slug:由
category与文件名拼接而成(如/blog/release/v16.12.0,见 generate.mjs)。
随后 apps/site/util/blog.ts 提供按分类取文章与分页的能力:getBlogPosts按分类过滤并计算总页数(blog.ts),paginateBlogPosts处理页码边界与前后页(blog.ts)。
3. 公告页面的渲染
当访问/en/blog/release/v16.12.0时,由 apps/site/app/[locale]/blog/[...path]/page.tsx 接管路由:它通过getMarkdownContext定位到对应 Markdown 文件并编译为 MDX 内容(page.tsx),根据 Frontmatter 中的layout: blog-post字段选择布局,该路由被标记为force-static并设置revalidate = 300秒(page.tsx),即页面静态渲染且周期性失效刷新。
具体的博客正文布局由 apps/site/layouts/Post.tsx 提供:从客户端上下文读取frontmatter,渲染文章标题<h1>、作者头像组与作者名(Post.tsx),然后渲染公告正文(即"Notable Changes / Commits / SHASUMS"等内容)。而在/blog/release分类列表页中,每篇公告则通过 apps/site/components/Blog/BlogPostCard/index.tsx 以卡片形式展示标题、分类、简介、作者与日期(BlogPostCard/index.tsx)。
总结
Node.js v16.12.0 作为 Current 通道的一个小版本,其价值集中体现在三点:
- 实验性 ESM Loader Hooks API 整合:
resolve与load两阶段模型替代了原先五个分散 hook,getGlobalPreloadCode更名为globalPreload,并以"每个 loader 一次弃用警告"的方式为生态迁移提供缓冲,为后续 loader chaining 奠定基础; - 依赖与工具链的同步升级:npm 升至 8.1.0、Corepack 升至 0.10,配合
vm动态导入 import assertions 支持与 http abort 的 doc-only 弃用; - 规范化的发布流程:从 release-post 生成脚本 到 博客数据索引,再到 blog-post 布局渲染,整个发布公告实现了"一次发布、自动成文、静态上线",并为每个发行文件提供了可验证的 SHA-256 校验和与 PGP 签名。
对于关注 ESM loader 生态或需要维护自定义加载器的开发者,v16.12.0 是理解 Node.js ESM 模块加载机制演进的关键里程碑版本。
【免费下载链接】nodejs.orgThe Node.js® Website项目地址: https://gitcode.com/GitHub_Trending/no/nodejs.org
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考