| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ef43f08 commit c1a8439
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -372,9 +372,18 @@ Expose the [Web Crypto API][] on the global scope. | |||
| 372 | 372 | added: | |
| 373 | 373 | - v13.9.0 | |
| 374 | 374 | - v12.16.2 | |
| 375 | + changes: | ||
| 376 | + - version: REPLACEME | ||
| 377 | + pr-url: https://github.com/nodejs/node/pull/49028 | ||
| 378 | + description: synchronous import.meta.resolve made available by default, with | ||
| 379 | + the flag retained for enabling the experimental second argument | ||
| 380 | + as previously supported. | ||
| 375 | 381 | --> | |
| 376 | 382 | ||
| 377 | - Enable experimental `import.meta.resolve()` support. | ||
| 383 | + Enable experimental `import.meta.resolve()` parent URL support, which allows | ||
| 384 | + passing a second `parentURL` argument for contextual resolution. | ||
| 385 | + | ||
| 386 | + Previously gated the entire `import.meta.resolve` feature. | ||
| 378 | 387 | ||
| 379 | 388 | ### `--experimental-loader=module` | |
| 380 | 389 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -321,7 +321,7 @@ import { readFileSync } from 'node:fs'; | |||
| 321 | 321 | const buffer = readFileSync(new URL('./data.proto', import.meta.url)); | |
| 322 | 322 | ``` | |
| 323 | 323 | ||
| 324 | - ### `import.meta.resolve(specifier[, parent])` | ||
| 324 | + ### `import.meta.resolve(specifier)` | ||
| 325 | 325 | ||
| 326 | 326 | <!-- | |
| 327 | 327 | added: | |
@@ -336,36 +336,45 @@ changes: | |||
| 336 | 336 | - v14.18.0 | |
| 337 | 337 | pr-url: https://github.com/nodejs/node/pull/38587 | |
| 338 | 338 | description: Add support for WHATWG `URL` object to `parentURL` parameter. | |
| 339 | + - version: | ||
| 340 | + - REPLACEME | ||
| 341 | + pr-url: https://github.com/nodejs/node/pull/49028 | ||
| 342 | + description: Unflag import.meta.resolve, with `parentURL` parameter still | ||
| 343 | + flagged. | ||
| 339 | 344 | --> | |
| 340 | 345 | ||
| 341 | - > Stability: 1 - Experimental | ||
| 342 | - | ||
| 343 | - This feature is only available with the `--experimental-import-meta-resolve` | ||
| 344 | - command flag enabled. | ||
| 346 | + > Stability: 1.2 - Release candidate | ||
| 345 | 347 | ||
| 346 | - * `specifier` {string} The module specifier to resolve relative to `parent`. | ||
| 347 | - * `parent` {string|URL} The absolute parent module URL to resolve from. If none | ||
| 348 | - is specified, the value of `import.meta.url` is used as the default. | ||
| 349 | - * Returns: {string} | ||
| 348 | + * `specifier` {string} The module specifier to resolve relative to the | ||
| 349 | + current module. | ||
| 350 | + * Returns: {string} The absolute (`file:`) URL string for the resolved module. | ||
| 350 | 351 | ||
| 351 | - Provides a module-relative resolution function scoped to each module, returning | ||
| 352 | - the URL string. In alignment with browser behavior, this now returns | ||
| 353 | - synchronously. | ||
| 354 | - | ||
| 355 | - > **Caveat** This can result in synchronous file-system operations, which | ||
| 356 | - > can impact performance similarly to `require.resolve`. | ||
| 352 | + [`import.meta.resolve`][] is a module-relative resolution function scoped to | ||
| 353 | + each module, returning the URL string. | ||
| 357 | 354 | ||
| 358 | 355 | ```js | |
| 359 | 356 | const dependencyAsset = import.meta.resolve('component-lib/asset.css'); | |
| 357 | + // file:///app/node_modules/component-lib/asset.css | ||
| 360 | 358 | ``` | |
| 361 | 359 | ||
| 362 | - `import.meta.resolve` also accepts a second argument which is the parent module | ||
| 363 | - from which to resolve: | ||
| 360 | + All features of the Node.js module resolution are supported. Dependency | ||
| 361 | + resolutions are subject to the permitted exports resolutions within the package. | ||
| 364 | 362 | ||
| 365 | 363 | ```js | |
| 366 | 364 | import.meta.resolve('./dep', import.meta.url); | |
| 365 | + // file:///app/dep | ||
| 367 | 366 | ``` | |
| 368 | 367 | ||
| 368 | + > **Caveat** This can result in synchronous file-system operations, which | ||
| 369 | + > can impact performance similarly to `require.resolve`. | ||
| 370 | + | ||
| 371 | + Previously, Node.js implemented an asynchronous resolver which also permitted | ||
| 372 | + a second contextual argument. The implementation has since been updated to be | ||
| 373 | + synchronous, with the second contextual `parent` argument still accessible | ||
| 374 | + behind the `--experimental-import-meta-resolve` flag: | ||
| 375 | + | ||
| 376 | + * `parent` {string|URL} An optional absolute parent module URL to resolve from. | ||
| 377 | + | ||
| 369 | 378 | ## Interoperability with CommonJS | |
| 370 | 379 | ||
| 371 | 380 | ### `import` statements | |
@@ -500,8 +509,8 @@ They can instead be loaded with [`module.createRequire()`][] or | |||
| 500 | 509 | ||
| 501 | 510 | Relative resolution can be handled via `new URL('./local', import.meta.url)`. | |
| 502 | 511 | ||
| 503 | - For a complete `require.resolve` replacement, there is a flagged experimental | ||
| 504 | - [`import.meta.resolve`][] API. | ||
| 512 | + For a complete `require.resolve` replacement, there is the | ||
| 513 | + [import.meta.resolve][] API. | ||
| 505 | 514 | ||
| 506 | 515 | Alternatively `module.createRequire()` can be used. | |
| 507 | 516 | ||
@@ -1705,7 +1714,7 @@ success! | |||
| 1705 | 1714 | [`data:` URLs]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs | |
| 1706 | 1715 | [`export`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export | |
| 1707 | 1716 | [`import()`]: #import-expressions | |
| 1708 | - [`import.meta.resolve`]: #importmetaresolvespecifier-parent | ||
| 1717 | + [`import.meta.resolve`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve | ||
| 1709 | 1718 | [`import.meta.url`]: #importmetaurl | |
| 1710 | 1719 | [`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import | |
| 1711 | 1720 | [`initialize`]: #initialize | |
@@ -1722,6 +1731,7 @@ success! | |||
| 1722 | 1731 | [`util.TextDecoder`]: util.md#class-utiltextdecoder | |
| 1723 | 1732 | [cjs-module-lexer]: https://github.com/nodejs/cjs-module-lexer/tree/1.2.2 | |
| 1724 | 1733 | [custom https loader]: #https-loader | |
| 1734 | + [import.meta.resolve]: #importmetaresolvespecifier | ||
| 1725 | 1735 | [load hook]: #loadurl-context-nextload | |
| 1726 | 1736 | [percent-encoded]: url.md#percent-encoding-in-urls | |
| 1727 | 1737 | [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 | |
|---|---|---|---|
@@ -399,7 +399,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { | |||
| 399 | 399 | &EnvironmentOptions::experimental_wasm_modules, | |
| 400 | 400 | kAllowedInEnvvar); | |
| 401 | 401 | AddOption("--experimental-import-meta-resolve", | |
| 402 | - "experimental ES Module import.meta.resolve() support", | ||
| 402 | + "experimental ES Module import.meta.resolve() parentURL support", | ||
| 403 | 403 | &EnvironmentOptions::experimental_import_meta_resolve, | |
| 404 | 404 | kAllowedInEnvvar); | |
| 405 | 405 | AddOption("--experimental-policy", | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,7 +39,6 @@ assert.strictEqual(import.meta.resolve('baz/', fixtures), | |||
| 39 | 39 | ||
| 40 | 40 | { | |
| 41 | 41 | const cp = spawn(execPath, [ | |
| 42 | - '--experimental-import-meta-resolve', | ||
| 43 | 42 | '--input-type=module', | |
| 44 | 43 | '--eval', 'console.log(typeof import.meta.resolve)', | |
| 45 | 44 | ]); | |
@@ -48,7 +47,6 @@ assert.strictEqual(import.meta.resolve('baz/', fixtures), | |||
| 48 | 47 | ||
| 49 | 48 | { | |
| 50 | 49 | const cp = spawn(execPath, [ | |
| 51 | - '--experimental-import-meta-resolve', | ||
| 52 | 50 | '--input-type=module', | |
| 53 | 51 | ]); | |
| 54 | 52 | cp.stdin.end('console.log(typeof import.meta.resolve)'); | |
@@ -57,7 +55,6 @@ assert.strictEqual(import.meta.resolve('baz/', fixtures), | |||
| 57 | 55 | ||
| 58 | 56 | { | |
| 59 | 57 | const cp = spawn(execPath, [ | |
| 60 | - '--experimental-import-meta-resolve', | ||
| 61 | 58 | '--input-type=module', | |
| 62 | 59 | '--eval', 'import "data:text/javascript,console.log(import.meta.resolve(%22node:os%22))"', | |
| 63 | 60 | ]); | |
@@ -66,7 +63,6 @@ assert.strictEqual(import.meta.resolve('baz/', fixtures), | |||
| 66 | 63 | ||
| 67 | 64 | { | |
| 68 | 65 | const cp = spawn(execPath, [ | |
| 69 | - '--experimental-import-meta-resolve', | ||
| 70 | 66 | '--input-type=module', | |
| 71 | 67 | ]); | |
| 72 | 68 | 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'), | |
@@ -155,7 +154,6 @@ describe('Loader hooks', { concurrency: true }, () => { | |||
| 155 | 154 | it('should not leak internals or expose import.meta.resolve', async () => { | |
| 156 | 155 | const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | |
| 157 | 156 | '--no-warnings', | |
| 158 | - '--experimental-import-meta-resolve', | ||
| 159 | 157 | '--experimental-loader', | |
| 160 | 158 | fixtures.fileURL('es-module-loaders/loader-edge-cases.mjs'), | |
| 161 | 159 | fixtures.path('empty.js'), | |
@@ -170,7 +168,6 @@ describe('Loader hooks', { concurrency: true }, () => { | |||
| 170 | 168 | it('should be fine to call `process.exit` from a custom async hook', async () => { | |
| 171 | 169 | const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | |
| 172 | 170 | '--no-warnings', | |
| 173 | - '--experimental-import-meta-resolve', | ||
| 174 | 171 | '--experimental-loader', | |
| 175 | 172 | 'data:text/javascript,export function load(a,b,next){if(a==="data:exit")process.exit(42);return next(a,b)}', | |
| 176 | 173 | '--input-type=module', | |
@@ -187,7 +184,6 @@ describe('Loader hooks', { concurrency: true }, () => { | |||
| 187 | 184 | it('should be fine to call `process.exit` from a custom sync hook', async () => { | |
| 188 | 185 | const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | |
| 189 | 186 | '--no-warnings', | |
| 190 | - '--experimental-import-meta-resolve', | ||
| 191 | 187 | '--experimental-loader', | |
| 192 | 188 | 'data:text/javascript,export function resolve(a,b,next){if(a==="exit:")process.exit(42);return next(a,b)}', | |
| 193 | 189 | '--input-type=module', | |
| Back | FazBrowse Home | New Git URL |
0 commit comments