+173
-12
lines changedFilter options
+173
-12
lines changed Original file line number Diff line number Diff line change
@@ -396,6 +396,35 @@ import { readFileSync } from 'node:fs';
396
396
const buffer = readFileSync(new URL('./data.proto', import.meta.url));
397
397
```
398
398
399
+
### `import.meta.main`
400
+
401
+
<!-- YAML
402
+
added:
403
+
- REPLACEME
404
+
-->
405
+
406
+
> Stability: 1.0 - Early development
407
+
408
+
* {boolean} `true` when the current module is the entry point of the current process; `false` otherwise.
409
+
410
+
Equivalent to `require.main === module` in CommonJS.
411
+
412
+
Analogous to Python's `__name__ == "__main__"`.
413
+
414
+
```js
415
+
export function foo() {
416
+
return 'Hello, world';
417
+
}
418
+
419
+
function main() {
420
+
const message = foo();
421
+
console.log(message);
422
+
}
423
+
424
+
if (import.meta.main) main();
425
+
// `foo` can be imported from another module without possible side-effects from `main`
426
+
```
427
+
399
428
### `import.meta.resolve(specifier)`
400
429
401
430
<!-- YAML
@@ -612,6 +641,10 @@ These CommonJS variables are not available in ES modules.
612
641
They can instead be loaded with [`module.createRequire()`][] or
613
642
[`process.dlopen`][].
614
643
644
+
#### No `require.main`
645
+
646
+
To replace `require.main === module`, there is the [`import.meta.main`][] API.
647
+
615
648
#### No `require.resolve`
616
649
617
650
Relative resolution can be handled via `new URL('./local', import.meta.url)`.
@@ -1177,6 +1210,7 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][].
1177
1210
[`import()`]: #import-expressions
1178
1211
[`import.meta.dirname`]: #importmetadirname
1179
1212
[`import.meta.filename`]: #importmetafilename
1213
+
[`import.meta.main`]: #importmetamain
1180
1214
[`import.meta.resolve`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve
1181
1215
[`import.meta.url`]: #importmetaurl
1182
1216
[`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Original file line number Diff line number Diff line change
@@ -203,6 +203,20 @@ port.on('message', (message) => {
203
203
break;
204
204
}
205
205
206
+
case 'data-url': {
207
+
const { runEntryPointWithESMLoader } = require('internal/modules/run_main');
208
+
209
+
RegExpPrototypeExec(/^/, ''); // Necessary to reset RegExp statics before user code runs.
210
+
const promise = runEntryPointWithESMLoader((cascadedLoader) => {
211
+
return cascadedLoader.import(filename, undefined, { __proto__: null }, undefined, true);
212
+
});
213
+
214
+
PromisePrototypeThen(promise, undefined, (e) => {
215
+
workerOnGlobalUncaughtException(e, true);
216
+
});
217
+
break;
218
+
}
219
+
206
220
default: {
207
221
// script filename
208
222
// runMain here might be monkey-patched by users in --require.
Original file line number Diff line number Diff line change
@@ -51,12 +51,12 @@ function createImportMetaResolve(defaultParentURL, loader, allowParentURL) {
51
51
/**
52
52
* Create the `import.meta` object for a module.
53
53
* @param {object} meta
54
-
* @param {{url: string}} context
54
+
* @param {{url: string, isMain?: boolean}} context
55
55
* @param {typeof import('./loader.js').ModuleLoader} loader Reference to the current module loader
56
56
* @returns {{dirname?: string, filename?: string, url: string, resolve?: Function}}
57
57
*/
58
58
function initializeImportMeta(meta, context, loader) {
59
-
const { url } = context;
59
+
const { url, isMain } = context;
60
60
61
61
// Alphabetical
62
62
if (StringPrototypeStartsWith(url, 'file:') === true) {
@@ -65,6 +65,8 @@ function initializeImportMeta(meta, context, loader) {
65
65
setLazyPathHelpers(meta, url);
66
66
}
67
67
68
+
meta.main = !!isMain;
69
+
68
70
if (!loader || loader.allowImportMetaResolve) {
69
71
meta.resolve = createImportMetaResolve(url, loader, experimentalImportMetaResolve);
70
72
}
Original file line number Diff line number Diff line change
@@ -248,10 +248,11 @@ class ModuleLoader {
248
248
*
249
249
* @param {string} source Source code of the module.
250
250
* @param {string} url URL of the module.
251
+
* @param {{ isMain?: boolean }|undefined} context - context object containing module metadata.
251
252
* @returns {object} The module wrap object.
252
253
*/
253
-
createModuleWrap(source, url) {
254
-
return compileSourceTextModule(url, source, this);
254
+
createModuleWrap(source, url, context = kEmptyObject) {
255
+
return compileSourceTextModule(url, source, this, context);
255
256
}
256
257
257
258
/**
@@ -289,7 +290,8 @@ class ModuleLoader {
289
290
* @returns {Promise<object>} The module object.
290
291
*/
291
292
eval(source, url, isEntryPoint = false) {
292
-
const wrap = this.createModuleWrap(source, url);
293
+
const context = isEntryPoint ? { isMain: true } : undefined;
294
+
const wrap = this.createModuleWrap(source, url, context);
293
295
return this.executeModuleJob(url, wrap, isEntryPoint);
294
296
}
295
297
Original file line number Diff line number Diff line change
@@ -103,7 +103,8 @@ translators.set('module', function moduleStrategy(url, source, isMain) {
103
103
source = stringify(source);
104
104
debug(`Translating StandardModule ${url}`);
105
105
const { compileSourceTextModule } = require('internal/modules/esm/utils');
106
-
const module = compileSourceTextModule(url, source, this);
106
+
const context = isMain ? { isMain } : undefined;
107
+
const module = compileSourceTextModule(url, source, this, context);
107
108
return module;
108
109
});
109
110
Original file line number Diff line number Diff line change
@@ -42,6 +42,7 @@ const {
42
42
const {
43
43
emitExperimentalWarning,
44
44
getCWDURL,
45
+
kEmptyObject,
45
46
} = require('internal/util');
46
47
const assert = require('internal/assert');
47
48
const {
@@ -188,7 +189,7 @@ function registerModule(referrer, registry) {
188
189
*/
189
190
function defaultInitializeImportMetaForModule(meta, wrap) {
190
191
const cascadedLoader = require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
191
-
return cascadedLoader.importMetaInitialize(meta, { url: wrap.url });
192
+
return cascadedLoader.importMetaInitialize(meta, { url: wrap.url, isMain: wrap.isMain });
192
193
}
193
194
194
195
/**
@@ -342,15 +343,22 @@ async function initializeHooks() {
342
343
* @param {string} source Source code of the module.
343
344
* @param {typeof import('./loader.js').ModuleLoader|undefined} cascadedLoader If provided,
344
345
* register the module for default handling.
346
+
* @param {{ isMain?: boolean }|undefined} context - context object containing module metadata.
345
347
* @returns {ModuleWrap}
346
348
*/
347
-
function compileSourceTextModule(url, source, cascadedLoader) {
349
+
function compileSourceTextModule(url, source, cascadedLoader, context = kEmptyObject) {
348
350
const hostDefinedOption = cascadedLoader ? source_text_module_default_hdo : undefined;
349
351
const wrap = new ModuleWrap(url, undefined, source, 0, 0, hostDefinedOption);
350
352
351
353
if (!cascadedLoader) {
352
354
return wrap;
353
355
}
356
+
357
+
const { isMain } = context;
358
+
if (isMain) {
359
+
wrap.isMain = true;
360
+
}
361
+
354
362
// Cache the source map for the module if present.
355
363
if (wrap.sourceMapURL) {
356
364
maybeCacheSourceMap(url, source, wrap, false, undefined, wrap.sourceMapURL);
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@ const {
7
7
AtomicsAdd,
8
8
Float64Array,
9
9
FunctionPrototypeBind,
10
-
JSONStringify,
11
10
MathMax,
12
11
ObjectEntries,
13
12
Promise,
@@ -167,8 +166,8 @@ class Worker extends EventEmitter {
167
166
doEval = 'classic';
168
167
} else if (isURL(filename) && filename.protocol === 'data:') {
169
168
url = null;
170
-
doEval = 'module';
171
-
filename = `import ${JSONStringify(`${filename}`)}`;
169
+
doEval = 'data-url';
170
+
filename = `${filename}`;
172
171
} else {
173
172
doEval = false;
174
173
if (isURL(filename)) {
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
1
+
import { spawnPromisified } from '../common/index.mjs';
2
+
import * as fixtures from '../common/fixtures.js';
3
+
import assert from 'node:assert/strict';
4
+
import { describe, it } from 'node:test';
5
+
6
+
const importMetaMainScript = `
7
+
import assert from 'node:assert/strict';
8
+
9
+
assert.strictEqual(import.meta.main, true, 'import.meta.main should evaluate true in main module');
10
+
11
+
const { isMain: importedModuleIsMain } = await import(
12
+
${JSON.stringify(fixtures.fileURL('es-modules/import-meta-main.mjs'))}
13
+
);
14
+
assert.strictEqual(importedModuleIsMain, false, 'import.meta.main should evaluate false in imported module');
15
+
`;
16
+
17
+
function wrapScriptInEvalWorker(script) {
18
+
return `
19
+
import { Worker } from 'node:worker_threads';
20
+
new Worker(${JSON.stringify(script)}, { eval: true });
21
+
`;
22
+
}
23
+
24
+
function convertScriptSourceToDataUrl(script) {
25
+
return new URL(`data:text/javascript,${encodeURIComponent(script)}`);
26
+
}
27
+
28
+
function wrapScriptInUrlWorker(script) {
29
+
return `
30
+
import { Worker } from 'node:worker_threads';
31
+
new Worker(new URL(${JSON.stringify(convertScriptSourceToDataUrl(script))}));
32
+
`;
33
+
}
34
+
35
+
describe('import.meta.main in evaluated scripts', () => {
36
+
it('should evaluate true in evaluated script', async () => {
37
+
const result = await spawnPromisified(
38
+
process.execPath,
39
+
['--input-type=module', '--eval', importMetaMainScript],
40
+
);
41
+
assert.deepStrictEqual(result, {
42
+
stderr: '',
43
+
stdout: '',
44
+
code: 0,
45
+
signal: null,
46
+
});
47
+
});
48
+
49
+
it('should evaluate true in worker instantiated with module source by evaluated script', async () => {
50
+
const result = await spawnPromisified(
51
+
process.execPath,
52
+
['--input-type=module', '--eval', wrapScriptInEvalWorker(importMetaMainScript)],
53
+
);
54
+
assert.deepStrictEqual(result, {
55
+
stderr: '',
56
+
stdout: '',
57
+
code: 0,
58
+
signal: null,
59
+
});
60
+
});
61
+
62
+
it('should evaluate true in worker instantiated with `data:` URL by evaluated script', async () => {
63
+
const result = await spawnPromisified(
64
+
process.execPath,
65
+
['--input-type=module', '--eval', wrapScriptInUrlWorker(importMetaMainScript)],
66
+
);
67
+
assert.deepStrictEqual(result, {
68
+
stderr: '',
69
+
stdout: '',
70
+
code: 0,
71
+
signal: null,
72
+
});
73
+
});
74
+
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
1
+
import '../common/index.mjs';
2
+
import assert from 'node:assert/strict';
3
+
import { Worker } from 'node:worker_threads';
4
+
5
+
function get_environment() {
6
+
if (process.env.HAS_STARTED_WORKER) return 'in worker thread started by ES Module';
7
+
return 'in ES Module';
8
+
}
9
+
10
+
assert.strictEqual(
11
+
import.meta.main,
12
+
true,
13
+
`\`import.meta.main\` at top-level module ${get_environment()} should evaluate \`true\``
14
+
);
15
+
16
+
const { isMain: importedModuleIsMain } = await import('../fixtures/es-modules/import-meta-main.mjs');
17
+
assert.strictEqual(
18
+
importedModuleIsMain,
19
+
false,
20
+
`\`import.meta.main\` at dynamically imported module ${get_environment()} should evaluate \`false\``
21
+
);
22
+
23
+
if (!process.env.HAS_STARTED_WORKER) {
24
+
process.env.HAS_STARTED_WORKER = 1;
25
+
new Worker(import.meta.filename);
26
+
}
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ import assert from 'assert';
3
3
4
4
assert.strictEqual(Object.getPrototypeOf(import.meta), null);
5
5
6
-
const keys = ['dirname', 'filename', 'resolve', 'url'];
6
+
const keys = ['dirname', 'filename', 'main', 'resolve', 'url'];
7
7
assert.deepStrictEqual(Reflect.ownKeys(import.meta), keys);
8
8
9
9
const descriptors = Object.getOwnPropertyDescriptors(import.meta);
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4