Skip to content

Commit 0be122b

Browse files
esm: add import.meta.require
1 parent 58a7b00 commit 0be122b

File tree

6 files changed

+84
-1
lines changed

6 files changed

+84
-1
lines changed

doc/api/esm.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,19 @@ 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: REPLACEME
391+
-->
392+
393+
> Stability: 1.1 - Active development
394+
395+
* `id` {string} The module name or path.
396+
* Returns: {any} The module exports.
397+
398+
Alias for [`module.createRequire(import.meta.url)(id)`][].
399+
387400
### `import.meta.resolve(specifier)`
388401
389402
<!-- YAML
@@ -1118,6 +1131,7 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][].
11181131
[`import.meta.url`]: #importmetaurl
11191132
[`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
11201133
[`module.createRequire()`]: module.md#modulecreaterequirefilename
1134+
[`module.createRequire(import.meta.url)(id)`]: module.md#modulecreaterequirefilename
11211135
[`module.syncBuiltinESMExports()`]: module.md#modulesyncbuiltinesmexports
11221136
[`package.json`]: packages.md#nodejs-packagejson-field-definitions
11231137
[`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: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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 require a json module', () => {
24+
const { foo, bar } = import.meta.require('../fixtures/es-modules/foobar.json');
25+
assert.strictEqual(foo, 'foo');
26+
assert.strictEqual(bar, 'bar');
27+
});
28+
29+
it('should throw MODULE_NOT_FOUND', () => {
30+
try {
31+
import.meta.require('does-not-exist');
32+
assert.fail();
33+
} catch (e) {
34+
assert.strictEqual(e.code, 'MODULE_NOT_FOUND');
35+
}
36+
});
37+
});
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+
}

test/fixtures/es-modules/foobar.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"foo": "foo",
3+
"bar": "bar"
4+
}

0 commit comments

Comments
 (0)