CommonJS本身不支持动态按顺序引入并执行模块的原生机制,因其require()是同步阻塞的,模块加载在运行时发生且依赖树解析已确定;但可通过手动控制require调用时机、导出可执行函数、按数组顺序遍历加载并执行来模拟该行为,广泛用于CLI工具与部署脚本。

CommonJS 本身不支持“动态按顺序引入并执行模块”的原生机制,因为 require() 是同步阻塞的,且模块加载发生在运行时、解析时已确定依赖树。但你在自动化脚本(如 Node.js CLI 工具、构建脚本、部署脚本)中想实现“按指定顺序动态加载多个模块并依次执行”,可以通过控制 require 的调用时机和路径来模拟这种行为。
明确模块执行顺序的关键:手动控制 require 调用时机
CommonJS 的 require() 是同步的,每次调用都会立即加载、执行模块并返回其 module.exports。所以“顺序执行”本质就是按数组或列表顺序逐个调用 require,且确保前一个模块执行完再触发下一个。
- 模块本身应设计为“执行即生效”(例如导出一个函数,调用时才运行逻辑)
- 避免在模块顶层写副作用代码(如直接发起 HTTP 请求),否则
require时就会执行,难以控制节奏 - 推荐模块导出一个可调用函数(如
run()或execute()),由主脚本统一调度
用数组 + for 循环实现顺序加载与执行
最直接的方式:把模块路径存入数组,遍历并依次 require + 执行导出函数。
const steps = [
'./migrations/001-init.js',
'./migrations/002-add-user-index.js',
'./migrations/003-seed-admin.js'
];
for (const path of steps) {
console.log(`Executing ${path}...`);
const mod = require(path); // 同步加载
if (typeof mod.run === 'function') {
await mod.run(); // 如果是异步,用 await;同步则直接 mod.run()
}
}
注意:若模块内部有 async 操作,导出的 run 必须是 async 函数,主脚本需在 async 上下文中运行(如 (async () => { ... })())。
立即学习“Java免费学习笔记(深入)”;
支持条件跳过与错误中断的健壮流程
自动化脚本常需容错和跳过逻辑(比如某模块已执行过、环境不匹配)。可在每步前加判断,并统一捕获异常:
const runStep = async (path, options = {}) => {
try {
const mod = require(path);
if (mod.shouldSkip && await mod.shouldSkip(options)) {
console.log(`Skipped ${path}`);
return;
}
console.log(`Running ${path}`);
await mod.run(options);
} catch (err) {
console.error(`Failed at ${path}:`, err.message);
throw err; // 中断后续,或改为 continue 实现“尽力执行”
}
};
// 顺序执行
for (const step of steps) {
await runStep(step, { env: 'prod' });
}
配合配置文件动态生成执行列表
把执行顺序从硬编码移到 JSON/YAML 配置中,更易维护和复用:
// config/steps.json
[
{ "path": "./tasks/backup-db.js", "env": ["prod"] },
{ "path": "./tasks/migrate.js", "env": ["prod", "staging"] },
{ "path": "./tasks/deploy.js", "env": ["prod"] }
]
主脚本读取后过滤环境匹配项,再按序执行:
const config = JSON.parse(fs.readFileSync('./config/steps.json'));
const currentEnv = process.env.NODE_ENV || 'dev';
const validSteps = config.filter(s => s.env?.includes(currentEnv));
for (const step of validSteps) {
await require(step.path).run();
}
CommonJS 的模块加载本质是同步过程,所谓“动态顺序执行”,核心在于你主动组织 require 和函数调用的流程,而不是依赖模块系统自动排序。只要模块接口清晰、副作用可控,这种方式稳定可靠,广泛用于 CLI 工具、数据库迁移、部署流水线等场景。


















