Skip to content

Commit

Permalink
esm: add import.meta.require
Browse files Browse the repository at this point in the history
  • Loading branch information
marco-ippolito committed Nov 5, 2024
1 parent 58a7b00 commit 8705725
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 1 deletion.
17 changes: 17 additions & 0 deletions doc/api/esm.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,22 @@ import { readFileSync } from 'node:fs';
const buffer = readFileSync(new URL('./data.proto', import.meta.url));
```
### `import.meta.require(filename)`
<!-- YAML
added:
- REPLACEME
-->
> Stability: 1.1 - Active development
* `filename` {string|URL} Filename to be used to construct the require
function. Must be a file URL object, file URL string, or absolute path
string.
* Returns: {any} The module exports.
Alias for [`module.createRequire(import.meta.url)(specifier)`][].
### `import.meta.resolve(specifier)`
<!-- YAML
Expand Down Expand Up @@ -1118,6 +1134,7 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][].
[`import.meta.url`]: #importmetaurl
[`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
[`module.createRequire()`]: module.md#modulecreaterequirefilename
[`module.createRequire(import.meta.url)(specifier)`]: module.md#modulecreaterequirefilename
[`module.syncBuiltinESMExports()`]: module.md#modulesyncbuiltinesmexports
[`package.json`]: packages.md#nodejs-packagejson-field-definitions
[`path.dirname()`]: path.md#pathdirnamepath
Expand Down
13 changes: 13 additions & 0 deletions lib/internal/modules/esm/initialize_import_meta.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const {
ObjectDefineProperty,
StringPrototypeStartsWith,
} = primordials;

Expand Down Expand Up @@ -71,6 +72,18 @@ function initializeImportMeta(meta, context, loader) {

meta.url = url;

ObjectDefineProperty(meta, 'require', {
__proto__: null,
enumerable: true,
configurable: true,
get() {
const { Module: { createRequire } } = require('internal/modules/cjs/loader');
const req = createRequire(url);
ObjectDefineProperty(this, 'require', { __proto__: null, value: req });
return this.require;
},
});

return meta;
}

Expand Down
13 changes: 12 additions & 1 deletion test/es-module/test-esm-import-meta.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@ import assert from 'assert';

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

const keys = ['dirname', 'filename', 'resolve', 'url'];
const keys = ['dirname', 'filename', 'resolve', 'url', 'require'];
assert.deepStrictEqual(Reflect.ownKeys(import.meta), keys);

{
const requireDescriptor = Object.getOwnPropertyDescriptor(import.meta, 'require');
assert.strictEqual(requireDescriptor.value, undefined);
assert.strictEqual(requireDescriptor.set, undefined);
assert.strictEqual(requireDescriptor.enumerable, true);
assert.strictEqual(requireDescriptor.writable, undefined);
assert.strictEqual(requireDescriptor.configurable, true);
}

delete import.meta.require; // Verified above.

const descriptors = Object.getOwnPropertyDescriptors(import.meta);
for (const descriptor of Object.values(descriptors)) {
delete descriptor.value; // Values are verified below.
Expand Down
30 changes: 30 additions & 0 deletions test/es-module/test-import-meta-require.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import '../common/index.mjs';
import assert from 'node:assert';

{
try {
import.meta.require('does-not-exist');
assert.fail();
} catch (e) {
assert.strictEqual(e.code, 'MODULE_NOT_FOUND');
}
}

{
// Require a built-in module
const requiredAssert = import.meta.require('node:assert');
assert.deepStrictEqual(assert, requiredAssert);
}

{
// Require a esm module
const { foo, bar } = import.meta.require('../fixtures/es-module-loaders/module-named-exports.mjs');
assert.strictEqual(foo, 'foo');
assert.strictEqual(bar, 'bar');
}

{
const { foo, bar } = import.meta.require('../fixtures/es-modules/cjs-module-exports.js');
assert.strictEqual(foo, 'foo');
assert.strictEqual(bar, 'bar');
}
4 changes: 4 additions & 0 deletions test/fixtures/es-modules/cjs-module-exports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
foo: 'foo',
bar: 'bar'
}

0 comments on commit 8705725

Please sign in to comment.