Skip to content

Commit 3c71ffa

Browse files
feat(pnp): better builtin not found error with considerBuiltins disabled (#1695)
* feat(pnp): better builtin not found error with considerBuiltins disabled * chore: unbump std version * chore: update pnp hook * Tweaks Co-authored-by: Maël Nison <[email protected]>
1 parent 95af161 commit 3c71ffa

File tree

7 files changed

+145
-46
lines changed

7 files changed

+145
-46
lines changed

.pnp.js

Lines changed: 68 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.yarn/versions/078238f6.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
releases:
2+
"@yarnpkg/cli": prerelease
3+
"@yarnpkg/plugin-pnp": minor
4+
"@yarnpkg/pnp": minor
5+
6+
declined:
7+
- "@yarnpkg/plugin-compat"
8+
- "@yarnpkg/plugin-constraints"
9+
- "@yarnpkg/plugin-dlx"
10+
- "@yarnpkg/plugin-essentials"
11+
- "@yarnpkg/plugin-init"
12+
- "@yarnpkg/plugin-interactive-tools"
13+
- "@yarnpkg/plugin-node-modules"
14+
- "@yarnpkg/plugin-npm-cli"
15+
- "@yarnpkg/plugin-pack"
16+
- "@yarnpkg/plugin-patch"
17+
- "@yarnpkg/plugin-stage"
18+
- "@yarnpkg/plugin-typescript"
19+
- "@yarnpkg/plugin-version"
20+
- "@yarnpkg/plugin-workspace-tools"
21+
- "@yarnpkg/builder"
22+
- "@yarnpkg/core"
23+
- "@yarnpkg/doctor"
24+
- "@yarnpkg/pnpify"

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232

3333
- Scripts can now use the `$RANDOM` variable as well as simple calculations using `+`, `-`, `*`, `/` and `()` inside `$(())`
3434

35+
### Third-party integrations
36+
37+
- The PnP hook will now display clearer error message when requiring Node builtins from contexts that can't access them out of the box (for example when accessing the `fs` module from within a Webpack browser bundle).
38+
3539
## 2.1.1
3640

3741
- Fixed hyperlink rendering on iTerm

packages/acceptance-tests/pkg-tests-specs/sources/pnpapi.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,4 +434,24 @@ describe(`Plug'n'Play API`, () => {
434434
);
435435
});
436436
});
437+
438+
describe(`Semantic Errors`, () => {
439+
test(
440+
`it should throw detailed errors when a builtin is not found and the 'considerBuiltins' option is set to false`,
441+
makeTemporaryEnv(
442+
{},
443+
async ({path, run, source}) => {
444+
await run(`install`);
445+
446+
await expect(source(`require('pnpapi').resolveRequest('fs', ${JSON.stringify(`${npath.fromPortablePath(path)}/`)}, {considerBuiltins: false})`)).rejects.toMatchObject({
447+
externalException: {
448+
message: expect.stringContaining(`Your application tried to access fs. While this module is usually interpreted as a Node builtin,`),
449+
code: `MODULE_NOT_FOUND`,
450+
pnpCode: `UNDECLARED_DEPENDENCY`,
451+
},
452+
});
453+
},
454+
),
455+
);
456+
});
437457
});

packages/gatsby/content/advanced/pnp-api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ Note that the `pnpapi` builtin is *contextual*: while two packages from the same
121121
export const VERSIONS: {std: number, [key: string]: number};
122122
```
123123

124-
The `VERSIONS` object contains a set of numbers that detail which version of the API is currently exposed. The only version that is guaranteed to be there is `std`, which will refer to the version of this document. Other keys are meant to be used to describe extensions provided by third-party implementors.
124+
The `VERSIONS` object contains a set of numbers that detail which version of the API is currently exposed. The only version that is guaranteed to be there is `std`, which will refer to the version of this document. Other keys are meant to be used to describe extensions provided by third-party implementors. Versions will only be bumped when the signatures of the public API change.
125125

126126
**Note:** The current version is 3. We bump it responsibly and strive to make each version backward-compatible with the previous ones, but as you can probably guess some features are only available with the latest versions.
127127

packages/yarnpkg-pnp/sources/hook.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/yarnpkg-pnp/sources/loader/makeApi.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -667,18 +667,34 @@ export function makeApi(runtimeState: RuntimeState, opts: MakeApiOptions): PnpAp
667667
}
668668
}
669669
} else if (dependencyReference === undefined) {
670-
if (isDependencyTreeRoot(issuerLocator)) {
671-
error = makeError(
672-
ErrorCode.UNDECLARED_DEPENDENCY,
673-
`Your application tried to access ${dependencyName}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: ${dependencyName} (via "${requestForDisplay}")\nRequired by: ${issuerForDisplay}\n`,
674-
{request: requestForDisplay, issuer: issuerForDisplay, dependencyName},
675-
);
670+
if (!considerBuiltins && builtinModules.has(request)) {
671+
if (isDependencyTreeRoot(issuerLocator)) {
672+
error = makeError(
673+
ErrorCode.UNDECLARED_DEPENDENCY,
674+
`Your application tried to access ${dependencyName}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${dependencyName} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound.\n\nRequired package: ${dependencyName} (via "${requestForDisplay}")\nRequired by: ${issuerForDisplay}\n`,
675+
{request: requestForDisplay, issuer: issuerForDisplay, dependencyName},
676+
);
677+
} else {
678+
error = makeError(
679+
ErrorCode.UNDECLARED_DEPENDENCY,
680+
`${issuerLocator.name} tried to access ${dependencyName}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${dependencyName} isn't otherwise declared in ${issuerLocator.name}'s dependencies, this makes the require call ambiguous and unsound.\n\nRequired package: ${dependencyName} (via "${requestForDisplay}")\nRequired by: ${issuerForDisplay}\n`,
681+
{request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName},
682+
);
683+
}
676684
} else {
677-
error = makeError(
678-
ErrorCode.UNDECLARED_DEPENDENCY,
679-
`${issuerLocator.name} tried to access ${dependencyName}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: ${dependencyName} (via "${requestForDisplay}")\nRequired by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay})\n`,
680-
{request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName},
681-
);
685+
if (isDependencyTreeRoot(issuerLocator)) {
686+
error = makeError(
687+
ErrorCode.UNDECLARED_DEPENDENCY,
688+
`Your application tried to access ${dependencyName}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: ${dependencyName} (via "${requestForDisplay}")\nRequired by: ${issuerForDisplay}\n`,
689+
{request: requestForDisplay, issuer: issuerForDisplay, dependencyName},
690+
);
691+
} else {
692+
error = makeError(
693+
ErrorCode.UNDECLARED_DEPENDENCY,
694+
`${issuerLocator.name} tried to access ${dependencyName}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.\n\nRequired package: ${dependencyName} (via "${requestForDisplay}")\nRequired by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay})\n`,
695+
{request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName},
696+
);
697+
}
682698
}
683699
}
684700

0 commit comments

Comments
 (0)