Skip to main content

Node.js 入口點判斷(require.main === module)

這是 Node.js 常見的入口點判斷寫法,用來區分「直接執行這個檔案」和「被其他檔案 import 引用」兩種情況。

這段程式碼在做什麼?

if (require.main === module) {
main();
}
  • module:目前這個檔案本身(例如 migrate.ts 編譯後的模組)
  • require.main:Node 程序啟動時載入的第一個模組,也就是你實際執行的入口檔

require.main === moduletrue 時,代表這個檔案是直接被執行的,例如:

npm run migrate:up
# 或
node dist/scripts/migrate.js up

這時才會呼叫 main(),開始跑 CLI 邏輯。

為什麼要這樣寫?

如果其他檔案 import 了同一支 script(或編譯後的 .js),例如:

import './migrate'; // 或 import { something } from './migrate'

此時 require.main !== module不會自動執行 main(),避免 import 時意外觸發 migration 或其他副作用。

實務範例

以 migration script 為例,main() 通常會:

  1. 讀取 process.argv 解析子指令
  2. 建立 MigrationRunner
  3. 執行 up / down / status / create 等操作

這段判斷確保只有在你刻意執行這個 script 時才會跑上述邏輯;被其他模組引用時,只會載入可匯出的函式或設定,不會啟動 CLI。


CommonJS 與 ES Module 對照

上述寫法屬於 CommonJS。若專案使用純 ES Module,常見的等價寫法如下:

import { pathToFileURL } from 'node:url';

if (import.meta.url === pathToFileURL(process.argv[1]).href) {
main();
}
模組系統判斷方式備註
CommonJSrequire.main === moduleTypeScript 編譯成 CJS 時的標準做法
ES Moduleimport.meta.url 與入口檔比對建議用 pathToFileURL,避免路徑格式差異

若專案編譯成 CommonJS,require.main === module 仍是標準且常見的做法。