diff --git a/doc/api/esm.md b/doc/api/esm.md index 40cb34ee90899b..fba5d32187b099 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -266,6 +266,44 @@ modules it can be used to load ES modules. The `import.meta` meta property is an `Object` that contains the following properties. +### `import.meta.__dirname` + +> Stability: 3 - Legacy: Use `import.meta.url` instead. + +* {string} A convenience shortcut that provides the equivalent of the CommonJS + `__dirname` pseudo-global. Specifically, it returns the result of converting + the `import.meta.url` into a file path then returning the directory portion. + +The property is only available when `import.meta.url` specifies a `file://` +URL. + +```mjs +const { __dirname } = import.meta; +``` + +The `import.meta.__dirname` is provided as a convenience to help ease the +transition from existing CommonJS code to ESM. New ESM code should use the +`import.meta.url` property directly. + +### `import.meta.__filename` + +> Stability: 3 - Legacy: Use `import.meta.url` instead. + +* {string} A convenience shortcut that provides the equivalent of the CommonJS + `__filename` pseudo-global. Specifically, it returns the result of converting + the `import.meta.url` into a file path. + +The property is only available when `import.meta.url` specifies a `file://` +URL. + +```mjs +const { __filename } = import.meta; +``` + +The `import.meta.__filename` is provided as a convenience to help ease the +transition from existing CommonJS code to ESM. New ESM code should use the +`import.meta.url` property directly. + ### `import.meta.url` * {string} The absolute `file:` URL of the module. diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 6d295089e42c70..fbcfcc48c467c0 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -5,6 +5,7 @@ const { ArrayPrototypeMap, Boolean, JSONParse, + ObjectDefineProperties, ObjectGetPrototypeOf, ObjectPrototypeHasOwnProperty, ObjectKeys, @@ -39,6 +40,7 @@ const { cjsParseCache } = require('internal/modules/cjs/loader'); const internalURLModule = require('internal/url'); +const internalPathModule = require('path'); const { defaultGetSource } = require( 'internal/modules/esm/get_source'); const { defaultTransformSource } = require( @@ -129,6 +131,11 @@ function createImportMetaResolve(defaultParentUrl) { function initializeImportMeta(meta, { url }) { // Alphabetical + if (StringPrototypeStartsWith(url, 'file:')) { + meta.__filename = internalURLModule.fileURLToPath(new URL(url)); + meta.__dirname = internalPathModule.dirname(meta.__filename); + } + if (experimentalImportMetaResolve) meta.resolve = createImportMetaResolve(url); meta.url = url; diff --git a/test/es-module/test-esm-import-meta.mjs b/test/es-module/test-esm-import-meta.mjs index 0151177b21c302..698083c09cc99b 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 = ['__filename', '__dirname', 'url']; assert.deepStrictEqual(Reflect.ownKeys(import.meta), keys); const descriptors = Object.getOwnPropertyDescriptors(import.meta); @@ -18,3 +18,9 @@ for (const descriptor of Object.values(descriptors)) { const urlReg = /^file:\/\/\/.*\/test\/es-module\/test-esm-import-meta\.mjs$/; assert(import.meta.url.match(urlReg)); + +const filenameReg = /^\/.*\/test\/es-module\/test-esm-import-meta\.mjs$/; +assert(import.meta.__filename.match(filenameReg)); + +const dirnameReg = /^\/.*\/test\/es-module$/; +assert(import.meta.__dirname.match(dirnameReg));