关于 code-review-nodejs
这组面向 Node.js 的代码审查检查项,供审查 JavaScript 和 TypeScript 执行路径的人员使用。内容涵盖运行时行为、安全、依赖和生命周期清理,并应配合通用审查原则使用。
主要功能
- 01同步 I/O 与事件循环检查
- 02流背压审查
- 03进程关闭与错误处理
- 04输入、Shell 和路径安全检查
- 05依赖与环境变量验证
- 06事件监听器生命周期清理
适用场景
- 01检查 Node.js 请求处理器中的阻塞 I/O
- 02审查高吞吐路径的流管道
- 03追踪用户输入进入 Shell 命令或文件路径
- 04审计环境验证和监听器清理
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jamie-bitflight/ claude_skills --skill code-review-nodejs安装后在 Claude Code 中输入/code-review-nodejs确认已加载。
详细介绍
Node.js 代码审查模式
当源代码、运行时入口或包脚本表明项目会在 Node.js 中执行时,加载这些检查,包括 JavaScript、TypeScript、CJS 和 MJS。相关时,同时应用 TypeScript 或 CLI 检查;仅凭 package.json 无法区分服务端代码和浏览器构建。
应用这些检查前,先加载 /dh:review-principles。
请求路径中的同步 I/O
- 跟踪
fs.readFileSync、fs.writeFileSync、execSync或spawnSync是否会在活跃的请求/事件循环路径中执行,并确认其阻塞后果或违反的延迟约定。 - 对于不得阻塞该路径的工作,使用异步变体或
fs/promises。不要仅仅因为隔离的启动/设置 I/O 出现在服务端文件中就报告问题。
// WRONG: blocks event loop
app.get("/config", (req, res) => {
const config = fs.readFileSync("./config.json", "utf8");
res.json(JSON.parse(config));
});
// RIGHT: non-blocking
app.get("/config", async (req, res) => {
const config = await fs.promises.readFile("./config.json", "utf8");
res.json(JSON.parse(config));
});
流背压
- 在高吞吐路径中,管道流却未处理背压属于阻断性问题。
readable.pipe(writable)会自动处理背压;优先使用它,而不要手动监听data事件。- 手动监听
data事件时,必须检查writable.write()的返回值;若返回false,则暂停可读流。
进程退出
- 将进程终止操作限制在负责关闭流程的应用/CLI 边界,包括启动失败时的处理。若库、路由或中间件意外终止无关工作,或绕过必要的清理,则报告该问题。
- 未处理的
process.on("uncaughtException")若在未记录错误的情况下调用process.exit(),属于阻断性问题。
安全性
- 跟踪动态执行(包括
eval())的输入来源及执行权限;报告执行不受信任代码的情况,或违反项目明确禁令的情况。 - 使用用户控制的
code调用new Function(code),属于阻断性问题。 - 跟踪用户输入是否进入 Shell 执行及命令/选项解析。区分 Shell 插值与独立的进程参数,并报告实际调用所允许的注入或未授权操作。
- 无需 Shell 行为时,优先使用带独立参数的
execFile。若有意使用 Shell,应检查插值和输入来源,而不是将受信任的常量命令视为用户输入注入。 - 将用户控制的路径限制在该操作获准访问的资源范围内;若约定要求强制限定允许的根目录,则验证相关机制,并跟踪路径遍历是否越过该边界。
// WRONG: shell injection vector
exec(`convert ${userInput} output.png`);
// RIGHT: no shell, explicit args
execFile("convert", [userInput, "output.png"]);
依赖管理
- 根据目标项目的依赖和发布策略检查版本范围;在认定通配符范围导致无法复现前,先跟踪实际的解析/安装行为。
- 确认所选包管理器的锁文件和 CI 安装模式能够保留所需的依赖解析结果。若项目使用其他受支持的包管理器,不要强制要求 npm/yarn 锁文件。
- 仅用于开发的依赖必须放在
devDependencies中,而非dependencies中。
事件发射器清理
- 在组件/连接生命周期中添加的
EventEmitter.on()监听器,必须在该生命周期结束时移除。 - 若事件发射器的生命周期长于监听器,缺少
removeListener或off()调用属于阻断性问题。 - 对只需触发一次的监听器,使用
EventEmitter.once(),以避免手动清理。
环境变量
- 在接受依赖相关配置的工作前,验证所选执行模式所需的配置。不要要求已禁用的可选功能提供凭据。
- 将
process.env.SOME_VAR!追踪到相关的验证和使用位置;若缺少必需值或存在不受支持的假设,则根据实际失败路径报告。 - 提供
.env.example文件,列出所有必需变量;该文件必须提交到代码库,且不得包含真实值。
反模式
// WRONG: missing error handling on EventEmitter
server.on("connection", (socket) => {
socket.on("data", handleData);
// missing: socket.on("end", cleanup) and removeListener
});
// WRONG: unvalidated env at use site
const apiKey = process.env.API_KEY;
fetch(url, { headers: { Authorization: apiKey } }); // null if unset
// RIGHT: validate at startup
if (!process.env.API_KEY) {
console.error("FATAL: API_KEY environment variable is required");
process.exit(1);
}
const apiKey = process.env.API_KEY;
评论
支持 Markdown