| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -232,13 +232,17 @@ added: REPLACEME | |||
| 232 | 232 | * `base` {string|URL} The absolute location (`file:` URL string or FS path) of the | |
| 233 | 233 | containing module. For CJS, use `__filename` (not `__dirname`!); for ESM, use | |
| 234 | 234 | `import.meta.url`. You do not need to pass it if `specifier` is an `absolute specifier`. | |
| 235 | - * Returns: {string|undefined} A path if the `package.json` is found. When `startLocation` | ||
| 235 | + * Returns: {string|undefined} A path if the `package.json` is found. When `specifier` | ||
| 236 | 236 | is a package, the package's root `package.json`; when a relative or unresolved, the closest | |
| 237 | - `package.json` to the `startLocation`. | ||
| 237 | + `package.json` to the `specifier`. | ||
| 238 | 238 | ||
| 239 | - > **Caveat**: Do not use this to try to determine module format. There are many things effecting | ||
| 239 | + > **Caveat**: Do not use this to try to determine module format. There are many things affecting | ||
| 240 | 240 | > that determination; the `type` field of package.json is the _least_ definitive (ex file extension | |
| 241 | - > superceeds it, and a loader hook superceeds that). | ||
| 241 | + > supersedes it, and a loader hook supersedes that). | ||
| 242 | + | ||
| 243 | + > **Caveat**: This currently leverages only the built-in default resolver; if | ||
| 244 | + > [`resolve` customization hooks][resolve hook] are registered, they will not affect the resolution. | ||
| 245 | + > This may change in the future. | ||
| 242 | 246 | ||
| 243 | 247 | ```text | |
| 244 | 248 | /path/to/project | |
@@ -1579,6 +1583,7 @@ returned object contains the following keys: | |||
| 1579 | 1583 | [module wrapper]: modules.md#the-module-wrapper | |
| 1580 | 1584 | [prefix-only modules]: modules.md#built-in-modules-with-mandatory-node-prefix | |
| 1581 | 1585 | [realm]: https://tc39.es/ecma262/#realm | |
| 1586 | + [resolve hook]: #resolvespecifier-context-nextresolve | ||
| 1582 | 1587 | [source map include directives]: https://sourcemaps.info/spec.html#h.lmz475t4mvbx | |
| 1583 | 1588 | [transferable objects]: worker_threads.md#portpostmessagevalue-transferlist | |
| 1584 | 1589 | [transform TypeScript features]: typescript.md#typescript-features | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -268,8 +268,8 @@ function getPackageJSONURL(specifier, base) { | |||
| 268 | 268 | throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base), null); | |
| 269 | 269 | } | |
| 270 | 270 | ||
| 271 | - const pjsonImportAttributes = { __proto__: null, type: 'json' }; | ||
| 272 | - let cascadedLoader; | ||
| 271 | + /** @type {import('./esm/resolve.js').defaultResolve} */ | ||
| 272 | + let defaultResolve; | ||
| 273 | 273 | /** | |
| 274 | 274 | * @param {URL['href'] | string | URL} specifier The location for which to get the "root" package.json | |
| 275 | 275 | * @param {URL['href'] | string | URL} [base] The location of the current module (ex file://tmp/foo.js). | |
@@ -297,10 +297,15 @@ function findPackageJSON(specifier, base = 'data:') { | |||
| 297 | 297 | } | |
| 298 | 298 | ||
| 299 | 299 | let resolvedTarget; | |
| 300 | - cascadedLoader ??= require('internal/modules/esm/loader').getOrInitializeCascadedLoader(); | ||
| 300 | + defaultResolve ??= require('internal/modules/esm/resolve').defaultResolve; | ||
| 301 | 301 | ||
| 302 | 302 | try { | |
| 303 | - resolvedTarget = cascadedLoader.resolve(specifier, `${parentURL}`, pjsonImportAttributes).url; | ||
| 303 | + // TODO(@JakobJingleheimer): Detect whether findPackageJSON is being used within a loader | ||
| 304 | + // (possibly piggyback on `allowImportMetaResolve`) | ||
| 305 | + // - When inside, use the default resolve | ||
| 306 | + // - (I think it's impossible to use the chain because of re-entry & a deadlock from atomics). | ||
| 307 | + // - When outside, use cascadedLoader.resolveSync (not implemented yet, but the pieces exist). | ||
| 308 | + resolvedTarget = defaultResolve(specifier, { parentURL: `${parentURL}` }).url; | ||
| 304 | 309 | } catch (err) { | |
| 305 | 310 | if (err.code === 'ERR_UNSUPPORTED_DIR_IMPORT') { | |
| 306 | 311 | resolvedTarget = err.url; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -149,4 +149,44 @@ describe('findPackageJSON', () => { // Throws when no arguments are provided | |||
| 149 | 149 | }); | |
| 150 | 150 | })); | |
| 151 | 151 | }); | |
| 152 | + | ||
| 153 | + it('should work within a loader', async () => { | ||
| 154 | + const specifierBase = './packages/root-types-field'; | ||
| 155 | + const target = fixtures.fileURL(specifierBase, 'index.js'); | ||
| 156 | + const foundPjsonPath = path.toNamespacedPath(fixtures.path(specifierBase, 'package.json')); | ||
| 157 | + const { code, stderr, stdout } = await common.spawnPromisified(process.execPath, [ | ||
| 158 | + '--no-warnings', | ||
| 159 | + '--loader', | ||
| 160 | + [ | ||
| 161 | + 'data:text/javascript,', | ||
| 162 | + 'import fs from "node:fs";', | ||
| 163 | + 'import module from "node:module";', | ||
| 164 | + encodeURIComponent(`fs.writeSync(1, module.findPackageJSON(${JSON.stringify(target)}));`), | ||
| 165 | + 'export const resolve = async (s, c, n) => n(s);', | ||
| 166 | + ].join(''), | ||
| 167 | + '--eval', | ||
| 168 | + 'import "node:os";', // Can be anything that triggers the resolve hook chain | ||
| 169 | + ]); | ||
| 170 | + | ||
| 171 | + assert.strictEqual(stderr, ''); | ||
| 172 | + assert.ok(stdout.includes(foundPjsonPath), stdout); | ||
| 173 | + assert.strictEqual(code, 0); | ||
| 174 | + }); | ||
| 175 | + | ||
| 176 | + it('should work with an async resolve hook registered', async () => { | ||
| 177 | + const specifierBase = './packages/root-types-field'; | ||
| 178 | + const target = fixtures.fileURL(specifierBase, 'index.js'); | ||
| 179 | + const foundPjsonPath = path.toNamespacedPath(fixtures.path(specifierBase, 'package.json')); | ||
| 180 | + const { code, stderr, stdout } = await common.spawnPromisified(process.execPath, [ | ||
| 181 | + '--no-warnings', | ||
| 182 | + '--loader', | ||
| 183 | + 'data:text/javascript,export const resolve = async (s, c, n) => n(s);', | ||
| 184 | + '--print', | ||
| 185 | + `require("node:module").findPackageJSON(${JSON.stringify(target)})`, | ||
| 186 | + ]); | ||
| 187 | + | ||
| 188 | + assert.strictEqual(stderr, ''); | ||
| 189 | + assert.ok(stdout.includes(foundPjsonPath), stdout); | ||
| 190 | + assert.strictEqual(code, 0); | ||
| 191 | + }); | ||
| 152 | 192 | }); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments