From 382d66c92b0d04c96ea804991dd27d71039ad1f2 Mon Sep 17 00:00:00 2001 From: Antoine du HAMEL Date: Sun, 8 Mar 2020 23:28:23 +0100 Subject: [PATCH] esm: implement import.meta.main Boolean value to check if a module is run as entry point of the current process. Fixes: https://gtihub.com/nodejs/modules/issues/274 --- doc/api/esm.md | 7 ++++++- lib/internal/modules/esm/translators.js | 9 +++++++-- test/es-module/test-esm-import-meta-main.mjs | 11 +++++++++++ test/es-module/test-esm-import-meta.mjs | 2 +- test/fixtures/es-modules/import-meta-main.mjs | 1 + 5 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 test/es-module/test-esm-import-meta-main.mjs create mode 100644 test/fixtures/es-modules/import-meta-main.mjs diff --git a/doc/api/esm.md b/doc/api/esm.md index 3215cc100df651..598f748d236c6d 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -784,8 +784,10 @@ import _ from 'data:application/json,"world!"'; * {Object} The `import.meta` metaproperty is an `Object` that contains the following -property: +properties: +* `main` {boolean} `true` when the current module is the entry point of + the current process. * `url` {string} The absolute `file:` URL of the module. ## Differences Between ES Modules and CommonJS @@ -820,6 +822,8 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); ``` +Equivalent of `require.main === module` is [`import.meta.main`][]. + ### No `require.resolve` Former use cases relying on `require.resolve` to determine the resolved path @@ -1694,6 +1698,7 @@ success! [`getFormat` hook]: #esm_code_getformat_code_hook [`import()`]: #esm_import-expressions [`import.meta.url`]: #esm_import_meta +[`import.meta.main`]: #esm_import_meta [`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import [`module.createRequire()`]: modules.html#modules_module_createrequire_filename [`module.syncBuiltinESMExports()`]: modules.html#modules_module_syncbuiltinesmexports diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 497f90ed94475b..b416a5180131ed 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -3,6 +3,8 @@ /* global WebAssembly */ const { + Boolean, + FunctionPrototypeBind, JSONParse, ObjectKeys, SafeMap, @@ -66,11 +68,12 @@ function initializeImportMeta(meta, { url }) { // Alphabetical if (experimentalImportMetaResolve) meta.resolve = createImportMetaResolve(url); + meta.main = Boolean(this?.isMain); meta.url = url; } // Strategy for loading a standard JavaScript module -translators.set('module', async function moduleStrategy(url) { +translators.set('module', async function moduleStrategy(url, isMain) { let { source } = await this._getSource( url, { format: 'module' }, defaultGetSource); source = `${source}`; @@ -80,7 +83,9 @@ translators.set('module', async function moduleStrategy(url) { debug(`Translating StandardModule ${url}`); const module = new ModuleWrap(url, undefined, source, 0, 0); moduleWrap.callbackMap.set(module, { - initializeImportMeta, + initializeImportMeta: isMain ? + FunctionPrototypeBind(initializeImportMeta, { isMain }) : + initializeImportMeta, importModuleDynamically, }); return module; diff --git a/test/es-module/test-esm-import-meta-main.mjs b/test/es-module/test-esm-import-meta-main.mjs new file mode 100644 index 00000000000000..bd079ec2364e26 --- /dev/null +++ b/test/es-module/test-esm-import-meta-main.mjs @@ -0,0 +1,11 @@ +import { mustCall } from '../common/index.mjs'; +import fixtures from '../common/fixtures.js'; +import assert from 'assert'; + +assert.strictEqual(import.meta.main, true); + +import(fixtures.path('/es-modules/import-meta-main.mjs')).then( + mustCall(({ isMain }) => { + assert.strictEqual(isMain, false); + }) +); diff --git a/test/es-module/test-esm-import-meta.mjs b/test/es-module/test-esm-import-meta.mjs index 0151177b21c302..4d3fc9f357baec 100644 --- a/test/es-module/test-esm-import-meta.mjs +++ b/test/es-module/test-esm-import-meta.mjs @@ -3,7 +3,7 @@ import assert from 'assert'; assert.strictEqual(Object.getPrototypeOf(import.meta), null); -const keys = ['url']; +const keys = ['main', 'url']; assert.deepStrictEqual(Reflect.ownKeys(import.meta), keys); const descriptors = Object.getOwnPropertyDescriptors(import.meta); diff --git a/test/fixtures/es-modules/import-meta-main.mjs b/test/fixtures/es-modules/import-meta-main.mjs new file mode 100644 index 00000000000000..bee2c8e2651335 --- /dev/null +++ b/test/fixtures/es-modules/import-meta-main.mjs @@ -0,0 +1 @@ +export const isMain = import.meta.main;