Skip to content

Commit 135a7a1

Browse files
committed
esm: implement import.meta.main
Boolean value to check if an ES Module is the entrypoint of the current process. Implements: #57226
1 parent ada4abf commit 135a7a1

File tree

7 files changed

+46
-4
lines changed

7 files changed

+46
-4
lines changed

doc/api/esm.md

+28
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,29 @@ import { readFileSync } from 'node:fs';
391391
const buffer = readFileSync(new URL('./data.proto', import.meta.url));
392392
```
393393
394+
### `import.meta.main`
395+
396+
<!-- YAML
397+
added:
398+
- REPLACEME
399+
-->
400+
401+
> Stability: 1.2 - Release candidate <!-- TODO: is this correct? -->
402+
403+
* {boolean} `true` when the current module is the entry point of the current process; `false` otherwise.
404+
* Equivalent to `require.main === module` in CommonJS. <!-- TODO: Is this still accurate? -->
405+
* Analogous to Python's `__name__ == "__main__"`.
406+
407+
[`import.meta.resolve`][]
408+
409+
```js
410+
function main() {
411+
console.log('Hello, world!');
412+
}
413+
414+
if (import.meta.main) main();
415+
```
416+
394417
### `import.meta.resolve(specifier)`
395418
396419
<!-- YAML
@@ -607,6 +630,10 @@ These CommonJS variables are not available in ES modules.
607630
They can instead be loaded with [`module.createRequire()`][] or
608631
[`process.dlopen`][].
609632
633+
#### No `require.main`
634+
635+
To replace `require.main === module`, there is the [`import.meta.main`][] API.
636+
610637
#### No `require.resolve`
611638
612639
Relative resolution can be handled via `new URL('./local', import.meta.url)`.
@@ -1167,6 +1194,7 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][].
11671194
[`import()`]: #import-expressions
11681195
[`import.meta.dirname`]: #importmetadirname
11691196
[`import.meta.filename`]: #importmetafilename
1197+
[`import.meta.main`]: #importmetamain
11701198
[`import.meta.resolve`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve
11711199
[`import.meta.url`]: #importmetaurl
11721200
[`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

lib/internal/modules/esm/initialize_import_meta.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ function createImportMetaResolve(defaultParentURL, loader, allowParentURL) {
4949
/**
5050
* Create the `import.meta` object for a module.
5151
* @param {object} meta
52-
* @param {{url: string}} context
52+
* @param {{url: string, isMain?: boolean}} context
5353
* @param {typeof import('./loader.js').ModuleLoader} loader Reference to the current module loader
5454
* @returns {{dirname?: string, filename?: string, url: string, resolve?: Function}}
5555
*/
5656
function initializeImportMeta(meta, context, loader) {
57-
const { url } = context;
57+
const { url, isMain } = context;
5858

5959
// Alphabetical
6060
if (StringPrototypeStartsWith(url, 'file:') === true) {
@@ -70,6 +70,7 @@ function initializeImportMeta(meta, context, loader) {
7070
}
7171

7272
meta.url = url;
73+
meta.main = !!isMain;
7374

7475
return meta;
7576
}

lib/internal/modules/esm/translators.js

+1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ translators.set('module', function moduleStrategy(url, source, isMain) {
104104
debug(`Translating StandardModule ${url}`);
105105
const { compileSourceTextModule } = require('internal/modules/esm/utils');
106106
const module = compileSourceTextModule(url, source, this);
107+
if (isMain) module.isMain = true; // todo: is this fine?
107108
return module;
108109
});
109110

lib/internal/modules/esm/utils.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ function registerModule(referrer, registry) {
188188
*/
189189
function defaultInitializeImportMetaForModule(meta, wrap) {
190190
const cascadedLoader = require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
191-
return cascadedLoader.importMetaInitialize(meta, { url: wrap.url });
191+
return cascadedLoader.importMetaInitialize(meta, { url: wrap.url, isMain: wrap.isMain });
192192
}
193193

194194
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { mustCall } from '../common/index.mjs';
2+
import fixtures from '../common/fixtures.js';
3+
import assert from 'assert';
4+
5+
assert.strictEqual(import.meta.main, true);
6+
7+
import(fixtures.path('/es-modules/import-meta-main.mjs')).then(
8+
mustCall(({ isMain }) => {
9+
assert.strictEqual(isMain, false);
10+
})
11+
);

test/es-module/test-esm-import-meta.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import assert from 'assert';
33

44
assert.strictEqual(Object.getPrototypeOf(import.meta), null);
55

6-
const keys = ['dirname', 'filename', 'resolve', 'url'];
6+
const keys = ['dirname', 'filename', 'resolve', 'url', 'main'];
77
assert.deepStrictEqual(Reflect.ownKeys(import.meta), keys);
88

99
const descriptors = Object.getOwnPropertyDescriptors(import.meta);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const isMain = import.meta.main;

0 commit comments

Comments
 (0)