Skip to content

Commit 78cc229

Browse files
esm: add import.meta.require
1 parent 58a7b00 commit 78cc229

File tree

5 files changed

+75
-1
lines changed

5 files changed

+75
-1
lines changed

doc/api/esm.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,20 @@ import { readFileSync } from 'node:fs';
384384
const buffer = readFileSync(new URL('./data.proto', import.meta.url));
385385
```
386386
387+
### `import.meta.require(id)`
388+
389+
<!-- YAML
390+
added:
391+
- REPLACEME
392+
-->
393+
394+
> Stability: 1.1 - Active development
395+
396+
* `id` {string} The module name or path.
397+
* Returns: {any} The module exports.
398+
399+
Alias for [`module.createRequire(import.meta.url)(specifier)`][].
400+
387401
### `import.meta.resolve(specifier)`
388402
389403
<!-- YAML
@@ -1118,6 +1132,7 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][].
11181132
[`import.meta.url`]: #importmetaurl
11191133
[`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
11201134
[`module.createRequire()`]: module.md#modulecreaterequirefilename
1135+
[`module.createRequire(import.meta.url)(specifier)`]: module.md#modulecreaterequirefilename
11211136
[`module.syncBuiltinESMExports()`]: module.md#modulesyncbuiltinesmexports
11221137
[`package.json`]: packages.md#nodejs-packagejson-field-definitions
11231138
[`path.dirname()`]: path.md#pathdirnamepath

lib/internal/modules/esm/initialize_import_meta.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const {
4+
ObjectDefineProperty,
45
StringPrototypeStartsWith,
56
} = primordials;
67

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

7273
meta.url = url;
7374

75+
ObjectDefineProperty(meta, 'require', {
76+
__proto__: null,
77+
enumerable: true,
78+
configurable: true,
79+
get() {
80+
const { Module: { createRequire } } = require('internal/modules/cjs/loader');
81+
const req = createRequire(url);
82+
ObjectDefineProperty(this, 'require', { __proto__: null, value: req });
83+
return this.require;
84+
},
85+
});
86+
7487
return meta;
7588
}
7689

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,20 @@ 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', 'require'];
77
assert.deepStrictEqual(Reflect.ownKeys(import.meta), keys);
88

9+
{
10+
const requireDescriptor = Object.getOwnPropertyDescriptor(import.meta, 'require');
11+
assert.strictEqual(requireDescriptor.value, undefined);
12+
assert.strictEqual(requireDescriptor.set, undefined);
13+
assert.strictEqual(requireDescriptor.enumerable, true);
14+
assert.strictEqual(requireDescriptor.writable, undefined);
15+
assert.strictEqual(requireDescriptor.configurable, true);
16+
}
17+
18+
delete import.meta.require; // Verified above.
19+
920
const descriptors = Object.getOwnPropertyDescriptors(import.meta);
1021
for (const descriptor of Object.values(descriptors)) {
1122
delete descriptor.value; // Values are verified below.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import '../common/index.mjs';
2+
import assert from 'node:assert';
3+
import { describe, it } from 'node:test';
4+
5+
describe('import.meta.require', () => {
6+
it('should require a built-in module', () => {
7+
const requiredAssert = import.meta.require('node:assert');
8+
assert.deepStrictEqual(assert, requiredAssert);
9+
});
10+
11+
it('should require a esm module', () => {
12+
const { foo, bar } = import.meta.require('../fixtures/es-module-loaders/module-named-exports.mjs');
13+
assert.strictEqual(foo, 'foo');
14+
assert.strictEqual(bar, 'bar');
15+
});
16+
17+
it('should require a cjs module', () => {
18+
const { foo, bar } = import.meta.require('../fixtures/es-modules/cjs-module-exports.js');
19+
assert.strictEqual(foo, 'foo');
20+
assert.strictEqual(bar, 'bar');
21+
});
22+
23+
it('should throw MODULE_NOT_FOUND', () => {
24+
try {
25+
import.meta.require('does-not-exist');
26+
assert.fail();
27+
} catch (e) {
28+
assert.strictEqual(e.code, 'MODULE_NOT_FOUND');
29+
}
30+
});
31+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
foo: 'foo',
3+
bar: 'bar'
4+
}

0 commit comments

Comments
 (0)