From dc8e9f9921c94eda3a780ab76ab267c160afb4ad Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Sat, 1 Aug 2026 10:17:55 +0200 Subject: [PATCH 1/2] module: add module.entrypoint Add `module.entrypoint`, a property exposing the resolved URL of the entry point of the current thread. Unlike `require.main`, it works regardless of whether the entry point is a CommonJS or an ECMAScript module, and inside worker threads it reflects the entry point of the worker itself, matching the semantics of `require.main` and `import.meta.main`. Refs: https://github.com/nodejs/node/issues/51840 Refs: https://github.com/nodejs/node/pull/64800 Signed-off-by: Matteo Collina --- doc/api/module.md | 50 +++++++++++++ lib/internal/main/worker_thread.js | 1 + lib/internal/modules/helpers.js | 14 ++++ lib/internal/modules/run_main.js | 6 +- lib/module.js | 12 +++ test/fixtures/module-entrypoint/main.cjs | 8 ++ test/fixtures/module-entrypoint/main.mjs | 6 ++ test/fixtures/module-entrypoint/noext.js | 3 + .../module-entrypoint/worker-main.mjs | 28 +++++++ test/fixtures/module-entrypoint/worker.cjs | 6 ++ test/parallel/test-module-entrypoint.js | 73 +++++++++++++++++++ 11 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/module-entrypoint/main.cjs create mode 100644 test/fixtures/module-entrypoint/main.mjs create mode 100644 test/fixtures/module-entrypoint/noext.js create mode 100644 test/fixtures/module-entrypoint/worker-main.mjs create mode 100644 test/fixtures/module-entrypoint/worker.cjs create mode 100644 test/parallel/test-module-entrypoint.js diff --git a/doc/api/module.md b/doc/api/module.md index f86167e8d44f..c10f3ef1086d 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -70,6 +70,53 @@ const require = createRequire(import.meta.url); const siblingModule = require('./sibling-module'); ``` +## `module.entrypoint` + + + +* Type: {string|undefined} + +The resolved URL of the entry point of the current thread, or `undefined` when +Node.js was started without an entry point script (`--eval`, the REPL, or code +piped via STDIN). It works regardless of whether the entry point is a +CommonJS or an ECMAScript module. + +Inside a [worker thread][], `module.entrypoint` is the URL of the script the +worker was started with, matching the semantics of `require.main` and +[`import.meta.main`][], rather than the entry point of the process. Workers +created with `eval: true` have an `undefined` entrypoint. + +Unlike `process.argv[1]`, the value is fully resolved: extension searching is +applied, and symlinks are followed unless [`--preserve-symlinks-main`][] is +set. This makes it consistent with the `require.main.filename` of a CommonJS +entry point and the `import.meta.url` of an ECMAScript module entry point. + +The value is `undefined` in code that runs before the entry point has been +resolved, such as modules preloaded with `--require`. + +Unlike [`import.meta.main`][], which only returns a boolean, `module.entrypoint` +returns the resolved URL string of the entry point. It can be used as a base +for resolving paths relative to the entry point, regardless of whether the +entry point is a CommonJS or an ECMAScript module: + +```mjs +import { entrypoint } from 'node:module'; + +// Use the entry point's URL as a base for resolving sibling modules. +const base = new URL('./', entrypoint); +``` + +In CommonJS, the equivalent is: + +```cjs +const { entrypoint } = require('node:module'); + +// Use the entry point's URL as a base for resolving sibling modules. +const base = new URL('./', entrypoint); +``` + ## `module.findPackageJSON(specifier[, base])`