| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1a6e945 commit eb12158
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -512,9 +512,18 @@ of `--enable-source-maps`. | |||
| 512 | 512 | added: | |
| 513 | 513 | - v13.9.0 | |
| 514 | 514 | - v12.16.2 | |
| 515 | + changes: | ||
| 516 | + - version: REPLACEME | ||
| 517 | + pr-url: https://github.com/nodejs/node/pull/49028 | ||
| 518 | + description: synchronous import.meta.resolve made available by default, with | ||
| 519 | + the flag retained for enabling the experimental second argument | ||
| 520 | + as previously supported. | ||
| 515 | 521 | --> | |
| 516 | 522 | ||
| 517 | - Enable experimental `import.meta.resolve()` support. | ||
| 523 | + Enable experimental `import.meta.resolve()` parent URL support, which allows | ||
| 524 | + passing a second `parentURL` argument for contextual resolution. | ||
| 525 | + | ||
| 526 | + Previously gated the entire `import.meta.resolve` feature. | ||
| 518 | 527 | ||
| 519 | 528 | ### `--experimental-loader=module` | |
| 520 | 529 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -322,7 +322,7 @@ import { readFileSync } from 'node:fs'; | |||
| 322 | 322 | const buffer = readFileSync(new URL('./data.proto', import.meta.url)); | |
| 323 | 323 | ``` | |
| 324 | 324 | ||
| 325 | - ### `import.meta.resolve(specifier[, parent])` | ||
| 325 | + ### `import.meta.resolve(specifier)` | ||
| 326 | 326 | ||
| 327 | 327 | <!-- | |
| 328 | 328 | added: | |
@@ -337,36 +337,45 @@ changes: | |||
| 337 | 337 | - v14.18.0 | |
| 338 | 338 | pr-url: https://github.com/nodejs/node/pull/38587 | |
| 339 | 339 | description: Add support for WHATWG `URL` object to `parentURL` parameter. | |
| 340 | + - version: | ||
| 341 | + - REPLACEME | ||
| 342 | + pr-url: https://github.com/nodejs/node/pull/49028 | ||
| 343 | + description: Unflag import.meta.resolve, with `parentURL` parameter still | ||
| 344 | + flagged. | ||
| 340 | 345 | --> | |
| 341 | 346 | ||
| 342 | - > Stability: 1 - Experimental | ||
| 343 | - | ||
| 344 | - This feature is only available with the `--experimental-import-meta-resolve` | ||
| 345 | - command flag enabled. | ||
| 347 | + > Stability: 1.2 - Release candidate | ||
| 346 | 348 | ||
| 347 | - * `specifier` {string} The module specifier to resolve relative to `parent`. | ||
| 348 | - * `parent` {string|URL} The absolute parent module URL to resolve from. If none | ||
| 349 | - is specified, the value of `import.meta.url` is used as the default. | ||
| 350 | - * Returns: {string} | ||
| 349 | + * `specifier` {string} The module specifier to resolve relative to the | ||
| 350 | + current module. | ||
| 351 | + * Returns: {string} The absolute (`file:`) URL string for the resolved module. | ||
| 351 | 352 | ||
| 352 | - Provides a module-relative resolution function scoped to each module, returning | ||
| 353 | - the URL string. In alignment with browser behavior, this now returns | ||
| 354 | - synchronously. | ||
| 355 | - | ||
| 356 | - > **Caveat** This can result in synchronous file-system operations, which | ||
| 357 | - > can impact performance similarly to `require.resolve`. | ||
| 353 | + [`import.meta.resolve`][] is a module-relative resolution function scoped to | ||
| 354 | + each module, returning the URL string. | ||
| 358 | 355 | ||
| 359 | 356 | ```js | |
| 360 | 357 | const dependencyAsset = import.meta.resolve('component-lib/asset.css'); | |
| 358 | + // file:///app/node_modules/component-lib/asset.css | ||
| 361 | 359 | ``` | |
| 362 | 360 | ||
| 363 | - `import.meta.resolve` also accepts a second argument which is the parent module | ||
| 364 | - from which to resolve: | ||
| 361 | + All features of the Node.js module resolution are supported. Dependency | ||
| 362 | + resolutions are subject to the permitted exports resolutions within the package. | ||
| 365 | 363 | ||
| 366 | 364 | ```js | |
| 367 | 365 | import.meta.resolve('./dep', import.meta.url); | |
| 366 | + // file:///app/dep | ||
| 368 | 367 | ``` | |
| 369 | 368 | ||
| 369 | + > **Caveat** This can result in synchronous file-system operations, which | ||
| 370 | + > can impact performance similarly to `require.resolve`. | ||
| 371 | + | ||
| 372 | + Previously, Node.js implemented an asynchronous resolver which also permitted | ||
| 373 | + a second contextual argument. The implementation has since been updated to be | ||
| 374 | + synchronous, with the second contextual `parent` argument still accessible | ||
| 375 | + behind the `--experimental-import-meta-resolve` flag: | ||
| 376 | + | ||
| 377 | + * `parent` {string|URL} An optional absolute parent module URL to resolve from. | ||
| 378 | + | ||
| 370 | 379 | ## Interoperability with CommonJS | |
| 371 | 380 | ||
| 372 | 381 | ### `import` statements | |
@@ -501,8 +510,8 @@ They can instead be loaded with [`module.createRequire()`][] or | |||
| 501 | 510 | ||
| 502 | 511 | Relative resolution can be handled via `new URL('./local', import.meta.url)`. | |
| 503 | 512 | ||
| 504 | - For a complete `require.resolve` replacement, there is a flagged experimental | ||
| 505 | - [`import.meta.resolve`][] API. | ||
| 513 | + For a complete `require.resolve` replacement, there is the | ||
| 514 | + [import.meta.resolve][] API. | ||
| 506 | 515 | ||
| 507 | 516 | Alternatively `module.createRequire()` can be used. | |
| 508 | 517 | ||
@@ -1698,7 +1707,7 @@ for ESM specifiers is [commonjs-extension-resolution-loader][]. | |||
| 1698 | 1707 | [`data:` URLs]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs | |
| 1699 | 1708 | [`export`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export | |
| 1700 | 1709 | [`import()`]: #import-expressions | |
| 1701 | - [`import.meta.resolve`]: #importmetaresolvespecifier-parent | ||
| 1710 | + [`import.meta.resolve`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve | ||
| 1702 | 1711 | [`import.meta.url`]: #importmetaurl | |
| 1703 | 1712 | [`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import | |
| 1704 | 1713 | [`initialize`]: #initialize | |
@@ -1716,6 +1725,7 @@ for ESM specifiers is [commonjs-extension-resolution-loader][]. | |||
| 1716 | 1725 | [cjs-module-lexer]: https://github.com/nodejs/cjs-module-lexer/tree/1.2.2 | |
| 1717 | 1726 | [commonjs-extension-resolution-loader]: https://github.com/nodejs/loaders-test/tree/main/commonjs-extension-resolution-loader | |
| 1718 | 1727 | [custom https loader]: #https-loader | |
| 1728 | + [import.meta.resolve]: #importmetaresolvespecifier | ||
| 1719 | 1729 | [load hook]: #loadurl-context-nextload | |
| 1720 | 1730 | [percent-encoded]: url.md#percent-encoding-in-urls | |
| 1721 | 1731 | [special scheme]: https://url.spec.whatwg.org/#special-scheme | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,11 +7,22 @@ const experimentalImportMetaResolve = getOptionValue('--experimental-import-meta | |||
| 7 | 7 | * Generate a function to be used as import.meta.resolve for a particular module. | |
| 8 | 8 | * @param {string} defaultParentURL The default base to use for resolution | |
| 9 | 9 | * @param {typeof import('./loader.js').ModuleLoader} loader Reference to the current module loader | |
| 10 | - * @returns {(specifier: string, parentURL?: string) => string} Function to assign to import.meta.resolve | ||
| 10 | + * @param {bool} allowParentURL Whether to permit parentURL second argument for contextual resolution | ||
| 11 | + * @returns {(specifier: string) => string} Function to assign to import.meta.resolve | ||
| 11 | 12 | */ | |
| 12 | - function createImportMetaResolve(defaultParentURL, loader) { | ||
| 13 | + function createImportMetaResolve(defaultParentURL, loader, allowParentURL) { | ||
| 14 | + /** | ||
| 15 | + * @param {string} specifier | ||
| 16 | + * @param {URL['href']} [parentURL] When `--experimental-import-meta-resolve` is specified, a | ||
| 17 | + * second argument can be provided. | ||
| 18 | + */ | ||
| 13 | 19 | return function resolve(specifier, parentURL = defaultParentURL) { | |
| 14 | 20 | let url; | |
| 21 | + | ||
| 22 | + if (!allowParentURL) { | ||
| 23 | + parentURL = defaultParentURL; | ||
| 24 | + } | ||
| 25 | + | ||
| 15 | 26 | try { | |
| 16 | 27 | ({ url } = loader.resolveSync(specifier, parentURL)); | |
| 17 | 28 | return url; | |
@@ -40,8 +51,8 @@ function initializeImportMeta(meta, context, loader) { | |||
| 40 | 51 | const { url } = context; | |
| 41 | 52 | ||
| 42 | 53 | // Alphabetical | |
| 43 | - if (experimentalImportMetaResolve && loader.allowImportMetaResolve) { | ||
| 44 | - meta.resolve = createImportMetaResolve(url, loader); | ||
| 54 | + if (!loader || loader.allowImportMetaResolve) { | ||
| 55 | + meta.resolve = createImportMetaResolve(url, loader, experimentalImportMetaResolve); | ||
| 45 | 56 | } | |
| 46 | 57 | ||
| 47 | 58 | meta.url = url; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -396,7 +396,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { | |||
| 396 | 396 | &EnvironmentOptions::experimental_wasm_modules, | |
| 397 | 397 | kAllowedInEnvvar); | |
| 398 | 398 | AddOption("--experimental-import-meta-resolve", | |
| 399 | - "experimental ES Module import.meta.resolve() support", | ||
| 399 | + "experimental ES Module import.meta.resolve() parentURL support", | ||
| 400 | 400 | &EnvironmentOptions::experimental_import_meta_resolve, | |
| 401 | 401 | kAllowedInEnvvar); | |
| 402 | 402 | AddOption("--experimental-permission", | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -41,7 +41,6 @@ assert.strictEqual(import.meta.resolve('baz/', fixtures), | |||
| 41 | 41 | ||
| 42 | 42 | { | |
| 43 | 43 | const cp = spawn(execPath, [ | |
| 44 | - '--experimental-import-meta-resolve', | ||
| 45 | 44 | '--input-type=module', | |
| 46 | 45 | '--eval', 'console.log(typeof import.meta.resolve)', | |
| 47 | 46 | ]); | |
@@ -50,7 +49,6 @@ assert.strictEqual(import.meta.resolve('baz/', fixtures), | |||
| 50 | 49 | ||
| 51 | 50 | { | |
| 52 | 51 | const cp = spawn(execPath, [ | |
| 53 | - '--experimental-import-meta-resolve', | ||
| 54 | 52 | '--input-type=module', | |
| 55 | 53 | ]); | |
| 56 | 54 | cp.stdin.end('console.log(typeof import.meta.resolve)'); | |
@@ -59,7 +57,6 @@ assert.strictEqual(import.meta.resolve('baz/', fixtures), | |||
| 59 | 57 | ||
| 60 | 58 | { | |
| 61 | 59 | const cp = spawn(execPath, [ | |
| 62 | - '--experimental-import-meta-resolve', | ||
| 63 | 60 | '--input-type=module', | |
| 64 | 61 | '--eval', 'import "data:text/javascript,console.log(import.meta.resolve(%22node:os%22))"', | |
| 65 | 62 | ]); | |
@@ -68,7 +65,6 @@ assert.strictEqual(import.meta.resolve('baz/', fixtures), | |||
| 68 | 65 | ||
| 69 | 66 | { | |
| 70 | 67 | const cp = spawn(execPath, [ | |
| 71 | - '--experimental-import-meta-resolve', | ||
| 72 | 68 | '--input-type=module', | |
| 73 | 69 | ]); | |
| 74 | 70 | cp.stdin.end('import "data:text/javascript,console.log(import.meta.resolve(%22node:os%22))"'); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,7 +3,7 @@ import assert from 'assert'; | |||
| 3 | 3 | ||
| 4 | 4 | assert.strictEqual(Object.getPrototypeOf(import.meta), null); | |
| 5 | 5 | ||
| 6 | - const keys = ['url']; | ||
| 6 | + const keys = ['resolve', 'url']; | ||
| 7 | 7 | assert.deepStrictEqual(Reflect.ownKeys(import.meta), keys); | |
| 8 | 8 | ||
| 9 | 9 | const descriptors = Object.getOwnPropertyDescriptors(import.meta); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -94,7 +94,6 @@ describe('Loader hooks', { concurrency: true }, () => { | |||
| 94 | 94 | it('import.meta.resolve of a never-settling resolve', async () => { | |
| 95 | 95 | const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | |
| 96 | 96 | '--no-warnings', | |
| 97 | - '--experimental-import-meta-resolve', | ||
| 98 | 97 | '--experimental-loader', | |
| 99 | 98 | fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), | |
| 100 | 99 | fixtures.path('es-module-loaders/never-settling-resolve-step/import.meta.never-resolve.mjs'), | |
@@ -207,7 +206,6 @@ describe('Loader hooks', { concurrency: true }, () => { | |||
| 207 | 206 | it('should not leak internals or expose import.meta.resolve', async () => { | |
| 208 | 207 | const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | |
| 209 | 208 | '--no-warnings', | |
| 210 | - '--experimental-import-meta-resolve', | ||
| 211 | 209 | '--experimental-loader', | |
| 212 | 210 | fixtures.fileURL('es-module-loaders/loader-edge-cases.mjs'), | |
| 213 | 211 | fixtures.path('empty.js'), | |
@@ -222,7 +220,6 @@ describe('Loader hooks', { concurrency: true }, () => { | |||
| 222 | 220 | it('should be fine to call `process.exit` from a custom async hook', async () => { | |
| 223 | 221 | const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | |
| 224 | 222 | '--no-warnings', | |
| 225 | - '--experimental-import-meta-resolve', | ||
| 226 | 223 | '--experimental-loader', | |
| 227 | 224 | 'data:text/javascript,export function load(a,b,next){if(a==="data:exit")process.exit(42);return next(a,b)}', | |
| 228 | 225 | '--input-type=module', | |
@@ -239,7 +236,6 @@ describe('Loader hooks', { concurrency: true }, () => { | |||
| 239 | 236 | it('should be fine to call `process.exit` from a custom sync hook', async () => { | |
| 240 | 237 | const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | |
| 241 | 238 | '--no-warnings', | |
| 242 | - '--experimental-import-meta-resolve', | ||
| 243 | 239 | '--experimental-loader', | |
| 244 | 240 | 'data:text/javascript,export function resolve(a,b,next){if(a==="exit:")process.exit(42);return next(a,b)}', | |
| 245 | 241 | '--input-type=module', | |
| Back | FazBrowse Home | New Git URL |
0 commit comments