-r(或 --require)用于在执行主脚本前预加载指定模块,常用于注入全局行为、启用编译器(如 ts-node)、修改内置对象或设置运行时环境,但不适用于直接导出函数供 REPL 使用。
`-r`(或 `--require`)用于在执行主脚本前预加载指定模块,常用于注入全局行为、启用编译器(如 ts-node)、修改内置对象或设置运行时环境,但不适用于直接导出函数供 repl 使用。
-r 是 Node.js 提供的一个强大而常被误解的 CLI 选项。它的核心语义是:在用户代码(即你传入的入口脚本或 REPL 环境)执行之前,同步加载并执行指定的模块。该模块的导出内容不会自动挂载到全局作用域,也不会“暴露”给后续脚本——它只负责完成自身的初始化逻辑。
✅ 正确用法:预加载 + 副作用驱动
最典型的场景是通过副作用(side effect)修改运行时环境。例如,下面这个 hook.js 会劫持 console.log:
// hook.js
const originalLog = console.log;
console.log = (...args) => originalLog('[HOOKED]', ...args);
再创建一个普通脚本 app.js:
// app.js
console.log('Hello from app.js!');
执行命令:
node -r ./hook.js app.js
输出为:
[HOOKED] Hello from app.js!
注意:app.js 完全无需 require('./hook.js') —— -r 已确保它在 app.js 执行前完成加载和执行。
❌ 错误用法:期望“导出即可用”
回到你的 circle.js 示例:
根据 package.json 中的 engines 字段自动检测 Node.js 版本需求,未安装 nvm 时自动安装并切换至对应版本。支持 Windows、macOS、Linux。适用于 Node.js 项目开发、版本切换和环境配置。
#! /opt/node-v20.6.0-linux-x64/bin/node
'use strict';
function areaOfCircle(circleRadius) {
return Math.PI * circleRadius ** 2;
}
export areaOfCircle; // ES module 语法
当你运行:
node -r ${XDG_RUNTIME_DIR}/circle.js
Node 启动的是交互式 REPL(因为没指定主脚本),此时:
- circle.js 被加载并执行;
- 但由于它是 ES 模块(含 export),且未被任何上下文 import,其内部声明的 areaOfCircle 不会自动提升至全局作用域;
- REPL 中自然无法访问 areaOfCircle,报错 ReferenceError: areaOfCircle is not defined。
✅ 正确做法有二:
-
若需在 REPL 中使用:改用 CommonJS 并显式挂载到 global:
// circle.cjs function areaOfCircle(circleRadius) { return Math.PI * circleRadius ** 2; } global.areaOfCircle = areaOfCircle; // 显式暴露然后:
node -r ./circle.cjs > areaOfCircle(5) // ✅ 78.53981633974483
-
若需作为模块复用:直接运行脚本(非 -r):
node circle.js # ❌ 不推荐(ESM 无默认导出入口) # 更好:新建 main.js 导入它
// main.js import { areaOfCircle } from './circle.js'; console.log(areaOfCircle(3)); // ✅node main.js
? 实际工程场景示例
| 场景 | 命令 | 说明 |
|---|---|---|
| 启用 TypeScript 运行 | node -r ts-node/register src/index.ts | ts-node/register 劫持 .ts 文件加载逻辑 |
| 启用 dotenv 配置 | node -r dotenv/config src/server.js dotenv_config_path=.env | 自动加载环境变量,无需在代码中 require('dotenv').config() |
| 启用源码映射(sourcemap)调试 | node -r source-map-support/register app.js | 让错误堆栈指向原始 TypeScript/ES6 源码行 |
⚠️ 注意事项
- -r 加载的模块必须能被 Node.js 正常解析(路径正确、格式兼容);
- ES 模块(.mjs 或含 "type": "module" 的 .js)在 -r 中需 Node ≥ v12 且启用 --experimental-modules(旧版本);现代推荐统一用 .cjs 或通过 --loader 配合 ESM;
- 多个 -r 可叠加,按从左到右顺序执行:node -r a.js -r b.js app.js → 先 a.js,再 b.js,最后 app.js;
- 在 package.json 的 scripts 中可安全使用:"dev": "node -r dotenv/config -r ts-node/register src/index.ts"。
掌握 -r 的本质——“提前执行、依赖副作用、不自动导出”——就能避开常见陷阱,将其转化为提升开发体验的利器。










