关于 nodejs-core
面向 Node.js 内部机制与核心代码贡献者的技能,涵盖子系统指南以及构建、代码检查、测试和提交要求。
主要功能
- 01V8、libuv 与核心机制指南
- 02原生插件开发与调试
- 03构建、测试和代码检查流程
- 04Node.js 贡献与评审指南
适用场景
- 01排查 V8 性能或反优化问题
- 02调试原生插件崩溃或内存泄漏
- 03构建和测试 Node.js 核心改动
- 04准备核心代码提交或拉取请求
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mcollina/ skills --skill nodejs-core安装后在 Claude Code 中输入/nodejs-core确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
tile.jsonrules/build-and-test-workflow.mdbuild-system.mdchild-process-internals.mdcli-options.mdcommit-and-pr-guideline.mdconfigure.mdcontributing.mdcrypto-internals.mddebugging-native.mddocumentation.mdfs-internals.mdlibuv-async-io.mdlibuv-event-loop.mdlibuv-thread-pool.mdmemory-debugging.mdnapi.mdnative-memory.mdnet-internals.mdnode-addon-api.mdpre-commit-lint.mdprimordials.mdprofiling-v8.mdreviewing-prs.mdstreams-internals.mdv8-garbage-collection.mdv8-hidden-classes.mdv8-jit-compilation.mdworker-threads-internals.md详细介绍
适用场景
在需要深入了解 Node.js 内部机制时使用此技能,包括:
- C++ 插件开发
- V8 引擎调试
- libuv 事件循环问题
- 构建系统问题
- 编译失败
- 引擎级性能优化
- 理解 Node.js 核心架构
- 编写或审阅
nodejs/node提交及拉取请求描述
使用方法
阅读各个规则文件,了解详细说明和代码示例:
V8 引擎
- rules/v8-garbage-collection.md - Scavenger、Mark-Sweep、Mark-Compact、分代 GC
- rules/v8-hidden-classes.md - 隐藏类、内联缓存、优化
- rules/v8-jit-compilation.md - TurboFan、优化/反优化模式
libuv
- rules/libuv-event-loop.md - 事件循环阶段、定时器、I/O、空闲、检查、关闭
- rules/libuv-thread-pool.md - 线程池大小、阻塞操作、UV_THREADPOOL_SIZE
- rules/libuv-async-io.md - 异步 I/O 模式、句柄、请求
原生插件
- rules/napi.md - N-API 开发、ABI 稳定性、异步工作线程
- rules/node-addon-api.md - C++ 封装模式、最佳实践
- rules/native-memory.md - 缓冲区处理、外部内存、防止内存泄漏
核心模块内部机制
- rules/streams-internals.md - Node.js 流在 C++ 层的工作方式
- rules/net-internals.md - TCP/UDP 实现、套接字处理
- rules/fs-internals.md - libuv 文件系统操作、同步与异步
- rules/crypto-internals.md - OpenSSL 集成、性能考量
- rules/child-process-internals.md - IPC、spawn、fork 实现
- rules/worker-threads-internals.md - SharedArrayBuffer、Atomics、MessageChannel
JavaScript 内部机制
- rules/primordials.md - 使用 primordials 防止原型污染(
lib/internal/必须遵守)
构建与贡献
- rules/build-and-test-workflow.md - 编辑-构建-代码检查-测试循环(从这里开始)
- rules/pre-commit-lint.md - 每次提交都必须通过代码检查、格式化和
core-validate-commit门禁,确保 CI 首次运行即通过 - rules/configure.md - 用于调试构建、ASan、Ninja 等的
./configure标志 - rules/build-system.md - gyp、ninja、make、跨平台编译
- rules/cli-options.md - 添加 CLI 选项并控制实验性模块的启用
- rules/contributing.md - 如何为 Node.js 核心做贡献及相关流程
- rules/commit-and-pr-guideline.md - 提交消息和 PR 描述的风格、尾注、DCO 签署及验证
- rules/reviewing-prs.md - 从正确性、清晰度和贡献质量等方面审阅 PR
文档
- rules/documentation.md - 更新 doc/api/*.md 文件:结构、链接排序、错误文档、代码示例限制
调试与性能分析
- rules/debugging-native.md - gdb、lldb、调试 C++ 插件
- rules/profiling-v8.md - --prof、--trace-opt、--trace-deopt、火焰图
- rules/memory-debugging.md - 堆快照、内存泄漏检测
说明
Node.js 贡献内容撰写
撰写 nodejs/node 提交说明或拉取请求时,请阅读
rules/commit-and-pr-guideline.md。
标题应简洁,并带有子系统前缀;正文应平实、客观。开头说明具体行为,解释更改原因,并省略夸张表述、套用的标题、逐文件叙述和缺乏依据的主张。请附上贡献者的 DCO 签署声明,切勿添加 PR-URL: 或 Reviewed-By:——这些内容会在更改合入时添加。请在 nodejs/node 检出目录中运行
npx core-validate-commit --no-validate-metadata <sha> 验证结果。
强制要求:测试前重新构建
Node.js 会在编译时通过 js2c 将 lib/ JavaScript 文件嵌入二进制文件。**对 src/ 或 lib/ 做出任何更改后,都必须先重新构建,再运行测试。**如果不重新构建,测试使用的就是过时代码,结果没有意义。
edit src/ or lib/ → make -j$(nproc) → make lint → then test
绝不可跳过重新构建步骤。编辑后未先构建,绝不可运行 ./node test/...。
开始工作前,请向用户询问其构建配置(Make 还是 Ninja、debug 还是 release、使用哪些 configure 标志)。不要假设特定配置。多数情况下,已经运行过 ./configure,只需运行 make -j$(nproc) 重新构建。
强制要求:每次提交前都要检查代码和格式
Node.js 会对每个非草稿拉取请求运行 Linters CI 工作流;在 Unix 上,make test 不会运行任何代码检查工具。每次执行 git commit 前都要运行 make lint——如果更改涉及 C++,还要运行 make format-cpp——这样代码检查任务才能在首次 CI 运行时通过,避免因强制推送而再经历一轮完整流程。
make -j$(nproc) # rebuild first
make lint # JS, C++, MD, docs, YAML
# C++ changes only — use the merge-base form, which is what CI checks:
CLANG_FORMAT_START="$(git merge-base HEAD upstream/main)" make format-cpp
git --no-pager diff --exit-code # must be empty
git add -A && git commit -s # -s is mandatory
npx core-validate-commit --no-validate-metadata HEAD
即使更改看起来很简单,也绝不可跳过任何步骤;绝不可用“之后会修复代码检查问题”作为提交理由。
**仅运行 make format-cpp 还不够。**它默认使用
CLANG_FORMAT_START=HEAD,只会格式化已暂存的更改;而 format-cpp CI 任务会从合并基点开始格式化所有内容,并在产生任何差异时失败——因此,在当前分支较早提交的未格式化代码可能在本地通过,却在 CI 中失败。请务必传入上文所示的合并基点形式。
每次提交都必须使用 git commit -s 创建。-s 标志会添加 Signed-off-by: 结尾行,用于证明符合 Developer Certificate of Origin。若未添加,该提交会因 core-validate-commit 的 signed-off-by 规则检查失败,拉取请求也无法合入。签署声明必须使用人类贡献者本人的姓名和电子邮件地址——绝不可使用工具或 AI 的身份签署,也绝不可伪造他人的信息。如果忘记添加,请使用 git commit --amend --signoff 修正提交。
make lint 会运行 lint-js、lint-cpp、lint-addon-docs、lint-md 和
lint-yaml——但并未涵盖所有 CI 代码检查任务。Python(make lint-py)、
shell(tools/lint-sh.mjs .)、C++ 格式检查和提交说明验证都是独立任务。完整的检查门槛以及 CI 任务与命令的对应关系,请参阅 rules/pre-commit-lint.md。
请使用 core-validate-commit 验证每条提交说明,并始终传入
--no-validate-metadata——默认会进行元数据验证,并要求添加只有在更改合入后才会存在的结尾行。绝不可在自己创建的提交中添加 PR-URL: 或
Reviewed-By:;合入流程会添加这些内容。
完整工作流(包括 configure 标志、代码检查目标和测试命令),请参阅 rules/build-and-test-workflow.md。
核心知识领域
在以下领域运用对 Node.js 内部机制的深入了解:
- 核心架构:Node.js 核心模块及其 C++ 实现、V8 GC 和 JIT、libuv 事件循环机制、线程池行为、启动/模块加载生命周期
- 原生开发:N-API、node-addon-api 和 NAN 插件开发;V8 C++ API 句柄管理;内存安全;使用 gdb/lldb 进行原生调试
- 构建系统:node-gyp、gyp、ninja、make;跨平台编译;链接器错误;依赖问题;平台特定注意事项(Windows、macOS、Linux、嵌入式)
- 性能与调试:事件循环分析、检测 JS 和原生代码中的内存泄漏、CPU 火焰图、V8 优化/反优化跟踪
调试命令速查
V8 优化跟踪:
node --trace-opt --trace-deopt script.js
# Checkpoint: confirm no unexpected deoptimization warnings before proceeding to profiling
node --prof script.js && node --prof-process isolate-*.log > processed.txt
事件循环延迟检测:
node --trace-event-categories v8,node,node.async_hooks script.js
原生插件调试(gdb):
gdb --args node --napi-modules ./build/Release/addon.node
# Inside gdb:
run
bt # backtrace on crash
# Checkpoint: verify backtrace shows the expected call site before applying a fix
内存泄漏的堆快照:
node --inspect script.js # then open chrome://inspect, take heap snapshot
# Checkpoint: compare two consecutive heap snapshots to confirm leak growth before and after the fix; run valgrind --leak-check=full node addon_test.js to confirm no native leaks remain
Node.js 专用诊断决策树
原生插件中的段错误/崩溃:
- 使用
node --napi-modules能否复现崩溃?→ 运行gdb,捕获bt bt是否指向 V8 句柄作用域问题?→ 检查插件中HandleScope/EscapableHandleScope的用法- 是否指向 libuv 回调?→ 检查异步句柄的生命周期和
uv_close()调用顺序 - 没有明确的 C++ 栈帧?→ 检查传入原生绑定的 JS 端类型是否不匹配
V8 反优化/性能回归:
- 运行
--trace-opt --trace-deopt→ 找出发生反优化的函数及原因(例如,“not a Smi”“wrong map”) - 检查点:确认同一函数在多次运行中都会发生反优化
- 检查隐藏类转换(
--trace-ic),并修正属性添加顺序或类型不一致问题 - 重新运行
--trace-opt,确认该函数现在已优化
构建失败(node-gyp / binding.gyp):
- 缺少头文件?→ 检查
binding.gyp中的include_dirs和 Node.js 头文件安装情况 - 链接器错误?→ 检查
libraries和link_settings条目;确认 ABI 兼容性 - 是否为平台特定问题?→ 查阅
rules/build-system.md,了解 Windows/macOS/Linux 之间的差异
始终同时考虑 JavaScript 层和原生层的原因,说明性能影响和权衡,并指出所讨论的实验性功能的稳定性状态。代码示例应展示 Node.js 内部机制的使用模式,达到可用于生产环境的要求,并考虑开发者通常容易忽略的边缘情况。