mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
esm: add import.meta.dirname and import.meta.filename
PR-URL: https://github.com/nodejs/node/pull/48740 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
This commit is contained in:
parent
2a49973703
commit
3daa0a6c04
3
benchmark/fixtures/esm-dir-file.mjs
Normal file
3
benchmark/fixtures/esm-dir-file.mjs
Normal file
@ -0,0 +1,3 @@
|
||||
import assert from 'assert';
|
||||
assert.ok(import.meta.dirname);
|
||||
assert.ok(import.meta.filename);
|
5
benchmark/fixtures/load-esm-dir-file.js
Normal file
5
benchmark/fixtures/load-esm-dir-file.js
Normal file
@ -0,0 +1,5 @@
|
||||
(async function () {
|
||||
for (let i = 0; i < 1000; i += 1) {
|
||||
await import(`./esm-dir-file.mjs?i=${i}`);
|
||||
}
|
||||
}());
|
@ -9,6 +9,7 @@ const bench = common.createBenchmark(main, {
|
||||
script: [
|
||||
'benchmark/fixtures/require-builtins',
|
||||
'test/fixtures/semicolon',
|
||||
'benchmark/fixtures/load-esm-dir-file',
|
||||
],
|
||||
mode: ['process', 'worker'],
|
||||
count: [30],
|
||||
|
@ -332,6 +332,35 @@ 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`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1.2 - Release candidate
|
||||
|
||||
* {string} The directory name of the current module. This is the same as the
|
||||
[`path.dirname()`][] of the [`import.meta.filename`][].
|
||||
|
||||
> **Caveat**: only present on `file:` modules.
|
||||
|
||||
### `import.meta.filename`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1.2 - Release candidate
|
||||
|
||||
* {string} The full absolute path and filename of the current module, with
|
||||
* symlinks resolved.
|
||||
* This is the same as the [`url.fileURLToPath()`][] of the
|
||||
* [`import.meta.url`][].
|
||||
|
||||
> **Caveat** only local modules support this property. Modules not using the
|
||||
> `file:` protocol will not provide it.
|
||||
|
||||
### `import.meta.url`
|
||||
|
||||
* {string} The absolute `file:` URL of the module.
|
||||
@ -526,7 +555,7 @@ If needed, a `require` function can be constructed within an ES module using
|
||||
These CommonJS variables are not available in ES modules.
|
||||
|
||||
`__filename` and `__dirname` use cases can be replicated via
|
||||
[`import.meta.url`][].
|
||||
[`import.meta.filename`][] and [`import.meta.dirname`][].
|
||||
|
||||
#### No Addon Loading
|
||||
|
||||
@ -1107,13 +1136,17 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][].
|
||||
[`data:` URLs]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
|
||||
[`export`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
|
||||
[`import()`]: #import-expressions
|
||||
[`import.meta.dirname`]: #importmetadirname
|
||||
[`import.meta.filename`]: #importmetafilename
|
||||
[`import.meta.resolve`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve
|
||||
[`import.meta.url`]: #importmetaurl
|
||||
[`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
|
||||
[`module.createRequire()`]: module.md#modulecreaterequirefilename
|
||||
[`module.syncBuiltinESMExports()`]: module.md#modulesyncbuiltinesmexports
|
||||
[`package.json`]: packages.md#nodejs-packagejson-field-definitions
|
||||
[`path.dirname()`]: path.md#pathdirnamepath
|
||||
[`process.dlopen`]: process.md#processdlopenmodule-filename-flags
|
||||
[`url.fileURLToPath()`]: url.md#urlfileurltopathurl
|
||||
[cjs-module-lexer]: https://github.com/nodejs/cjs-module-lexer/tree/1.2.2
|
||||
[commonjs-extension-resolution-loader]: https://github.com/nodejs/loaders-test/tree/main/commonjs-extension-resolution-loader
|
||||
[custom https loader]: module.md#import-from-https
|
||||
|
@ -1,6 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
const { StringPrototypeStartsWith } = primordials;
|
||||
const { getOptionValue } = require('internal/options');
|
||||
const { fileURLToPath } = require('internal/url');
|
||||
const { dirname } = require('path');
|
||||
const experimentalImportMetaResolve = getOptionValue('--experimental-import-meta-resolve');
|
||||
|
||||
/**
|
||||
@ -45,12 +48,20 @@ function createImportMetaResolve(defaultParentURL, loader, allowParentURL) {
|
||||
* @param {object} meta
|
||||
* @param {{url: string}} context
|
||||
* @param {typeof import('./loader.js').ModuleLoader} loader Reference to the current module loader
|
||||
* @returns {{url: string, resolve?: Function}}
|
||||
* @returns {{dirname?: string, filename?: string, url: string, resolve?: Function}}
|
||||
*/
|
||||
function initializeImportMeta(meta, context, loader) {
|
||||
const { url } = context;
|
||||
|
||||
// Alphabetical
|
||||
if (StringPrototypeStartsWith(url, 'file:') === true) {
|
||||
// These only make sense for locally loaded modules,
|
||||
// i.e. network modules are not supported.
|
||||
const filePath = fileURLToPath(url);
|
||||
meta.dirname = dirname(filePath);
|
||||
meta.filename = filePath;
|
||||
}
|
||||
|
||||
if (!loader || loader.allowImportMetaResolve) {
|
||||
meta.resolve = createImportMetaResolve(url, loader, experimentalImportMetaResolve);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import assert from 'assert';
|
||||
|
||||
assert.strictEqual(Object.getPrototypeOf(import.meta), null);
|
||||
|
||||
const keys = ['resolve', 'url'];
|
||||
const keys = ['dirname', 'filename', 'resolve', 'url'];
|
||||
assert.deepStrictEqual(Reflect.ownKeys(import.meta), keys);
|
||||
|
||||
const descriptors = Object.getOwnPropertyDescriptors(import.meta);
|
||||
@ -18,3 +18,17 @@ for (const descriptor of Object.values(descriptors)) {
|
||||
|
||||
const urlReg = /^file:\/\/\/.*\/test\/es-module\/test-esm-import-meta\.mjs$/;
|
||||
assert(import.meta.url.match(urlReg));
|
||||
|
||||
// Match *nix paths: `/some/path/test/es-module`
|
||||
// Match Windows paths: `d:\\some\\path\\test\\es-module`
|
||||
const dirReg = /^(\/|\w:\\).*(\/|\\)test(\/|\\)es-module$/;
|
||||
assert.match(import.meta.dirname, dirReg);
|
||||
|
||||
// Match *nix paths: `/some/path/test/es-module/test-esm-import-meta.mjs`
|
||||
// Match Windows paths: `d:\\some\\path\\test\\es-module\\test-esm-import-meta.js`
|
||||
const fileReg = /^(\/|\w:\\).*(\/|\\)test(\/|\\)es-module(\/|\\)test-esm-import-meta\.mjs$/;
|
||||
assert.match(import.meta.filename, fileReg);
|
||||
|
||||
// Verify that `data:` imports do not behave like `file:` imports.
|
||||
import dataDirname from 'data:text/javascript,export default "dirname" in import.meta';
|
||||
assert.strictEqual(dataDirname, false);
|
||||
|
7
test/js-native-api/test_cannot_run_js/entry_point.c
Normal file
7
test/js-native-api/test_cannot_run_js/entry_point.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <node_api.h>
|
||||
|
||||
EXTERN_C_START
|
||||
napi_value Init(napi_env env, napi_value exports);
|
||||
EXTERN_C_END
|
||||
|
||||
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
|
Loading…
Reference in New Issue
Block a user