+57
-8
lines changedFilter options
+57
-8
lines changed Original file line number Diff line number Diff line change
@@ -81,13 +81,17 @@ added: v23.2.0
81
81
* `base` {string|URL} The absolute location (`file:` URL string or FS path) of the
82
82
containing module. For CJS, use `__filename` (not `__dirname`!); for ESM, use
83
83
`import.meta.url`. You do not need to pass it if `specifier` is an `absolute specifier`.
84
-
* Returns: {string|undefined} A path if the `package.json` is found. When `startLocation`
84
+
* Returns: {string|undefined} A path if the `package.json` is found. When `specifier`
85
85
is a package, the package's root `package.json`; when a relative or unresolved, the closest
86
-
`package.json` to the `startLocation`.
86
+
`package.json` to the `specifier`.
87
87
88
-
> **Caveat**: Do not use this to try to determine module format. There are many things effecting
88
+
> **Caveat**: Do not use this to try to determine module format. There are many things affecting
89
89
> that determination; the `type` field of package.json is the _least_ definitive (ex file extension
90
-
> superceeds it, and a loader hook superceeds that).
90
+
> supersedes it, and a loader hook supersedes that).
91
+
92
+
> **Caveat**: This currently leverages only the built-in default resolver; if
93
+
> [`resolve` customization hooks][resolve hook] are registered, they will not affect the resolution.
94
+
> This may change in the future.
91
95
92
96
```text
93
97
/path/to/project
Original file line number Diff line number Diff line change
@@ -267,8 +267,8 @@ function getPackageJSONURL(specifier, base) {
267
267
throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base), null);
268
268
}
269
269
270
-
const pjsonImportAttributes = { __proto__: null, type: 'json' };
271
-
let cascadedLoader;
270
+
/** @type {import('./esm/resolve.js').defaultResolve} */
271
+
let defaultResolve;
272
272
/**
273
273
* @param {URL['href'] | string | URL} specifier The location for which to get the "root" package.json
274
274
* @param {URL['href'] | string | URL} [base] The location of the current module (ex file://tmp/foo.js).
@@ -296,10 +296,15 @@ function findPackageJSON(specifier, base = 'data:') {
296
296
}
297
297
298
298
let resolvedTarget;
299
-
cascadedLoader ??= require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
299
+
defaultResolve ??= require('internal/modules/esm/resolve').defaultResolve;
300
300
301
301
try {
302
-
resolvedTarget = cascadedLoader.resolve(specifier, `${parentURL}`, pjsonImportAttributes).url;
302
+
// TODO(@JakobJingleheimer): Detect whether findPackageJSON is being used within a loader
303
+
// (possibly piggyback on `allowImportMetaResolve`)
304
+
// - When inside, use the default resolve
305
+
// - (I think it's impossible to use the chain because of re-entry & a deadlock from atomics).
306
+
// - When outside, use cascadedLoader.resolveSync (not implemented yet, but the pieces exist).
307
+
resolvedTarget = defaultResolve(specifier, { parentURL: `${parentURL}` }).url;
303
308
} catch (err) {
304
309
if (err.code === 'ERR_UNSUPPORTED_DIR_IMPORT') {
305
310
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
});
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4