Skip to content

Commit 091da92

Browse files
committed
fix(pnp): esm - support import attributes (#6268)
**What's the problem this PR addresses?** In Node.js v22 import assertions were replaced with import attributes so we need to add support for those as well. Fixes #6267 **How did you fix it?** Added support for the `importAttributes` property. **Checklist** - [x] I have read the [Contributing Guide](https://yarnpkg.com/advanced/contributing). - [x] I have set the packages that need to be released for my changes to be effective. - [x] I will check that all automated PR checks pass before the PR gets reviewed.
1 parent 450097c commit 091da92

File tree

5 files changed

+61
-14
lines changed

5 files changed

+61
-14
lines changed

.yarn/versions/a5b83769.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
releases:
2+
"@yarnpkg/cli": patch
3+
"@yarnpkg/plugin-pnp": patch
4+
"@yarnpkg/pnp": patch
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-nm"
14+
- "@yarnpkg/plugin-npm-cli"
15+
- "@yarnpkg/plugin-pack"
16+
- "@yarnpkg/plugin-patch"
17+
- "@yarnpkg/plugin-pnpm"
18+
- "@yarnpkg/plugin-stage"
19+
- "@yarnpkg/plugin-typescript"
20+
- "@yarnpkg/plugin-version"
21+
- "@yarnpkg/plugin-workspace-tools"
22+
- "@yarnpkg/builder"
23+
- "@yarnpkg/core"
24+
- "@yarnpkg/doctor"
25+
- "@yarnpkg/nm"
26+
- "@yarnpkg/pnpify"
27+
- "@yarnpkg/sdks"

packages/acceptance-tests/pkg-tests-specs/sources/pnp-esm.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ describe(`Plug'n'Play - ESM`, () => {
243243
);
244244

245245
(loaderFlags.HAS_UNFLAGGED_JSON_MODULES ? test : test.skip)(
246-
`it should not resolve JSON modules without an import assertion`,
246+
`it should not resolve JSON modules without an import assertion/attribute`,
247247
makeTemporaryEnv(
248248
{
249249
type: `module`,
@@ -259,14 +259,14 @@ describe(`Plug'n'Play - ESM`, () => {
259259

260260
await expect(run(`node`, `./index.js`)).rejects.toMatchObject({
261261
code: 1,
262-
stderr: expect.stringContaining(`ERR_IMPORT_ASSERTION_TYPE_MISSING`),
262+
stderr: expect.stringContaining(loaderFlags.SUPPORTS_IMPORT_ATTRIBUTES_ONLY ? `ERR_IMPORT_ATTRIBUTE_MISSING` : `ERR_IMPORT_ASSERTION_TYPE_MISSING`),
263263
});
264264
},
265265
),
266266
);
267267

268268
(loaderFlags.HAS_UNFLAGGED_JSON_MODULES ? test : test.skip)(
269-
`it should resolve JSON modules with an import assertion`,
269+
`it should resolve JSON modules with an import assertion/attribute`,
270270
makeTemporaryEnv(
271271
{
272272
type: `module`,
@@ -277,7 +277,7 @@ describe(`Plug'n'Play - ESM`, () => {
277277
await xfs.writeFilePromise(
278278
ppath.join(path, `index.js` as Filename),
279279
`
280-
import foo from './foo.json' assert { type: 'json' };
280+
import foo from './foo.json' ${loaderFlags.SUPPORTS_IMPORT_ATTRIBUTES ? `with` : `assert`} { type: 'json' };
281281
console.log(foo.name);
282282
`,
283283
);

packages/yarnpkg-pnp/sources/esm-loader/built-loader.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/esm-loader/hooks/load.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import {VirtualFS, npath} from '@yarnpkg/fslib';
2-
import fs from 'fs';
3-
import {fileURLToPath, pathToFileURL} from 'url';
1+
import {VirtualFS, npath} from '@yarnpkg/fslib';
2+
import fs from 'fs';
3+
import {fileURLToPath, pathToFileURL} from 'url';
44

5-
import {HAS_JSON_IMPORT_ASSERTION_REQUIREMENT, WATCH_MODE_MESSAGE_USES_ARRAYS} from '../loaderFlags';
6-
import * as loaderUtils from '../loaderUtils';
5+
import {HAS_JSON_IMPORT_ASSERTION_REQUIREMENT, SUPPORTS_IMPORT_ATTRIBUTES, SUPPORTS_IMPORT_ATTRIBUTES_ONLY, WATCH_MODE_MESSAGE_USES_ARRAYS} from '../loaderFlags';
6+
import * as loaderUtils from '../loaderUtils';
77

88
// The default `load` doesn't support reading from zip files
99
export async function load(
@@ -13,6 +13,9 @@ export async function load(
1313
importAssertions?: {
1414
type?: 'json';
1515
};
16+
importAttributes?: {
17+
type?: 'json';
18+
};
1619
},
1720
nextLoad: typeof load,
1821
): Promise<{ format: string, source?: string, shortCircuit: boolean }> {
@@ -26,10 +29,21 @@ export async function load(
2629
if (!format)
2730
return nextLoad(urlString, context, nextLoad);
2831

29-
if (HAS_JSON_IMPORT_ASSERTION_REQUIREMENT && format === `json` && context.importAssertions?.type !== `json`) {
30-
const err = new TypeError(`[ERR_IMPORT_ASSERTION_TYPE_MISSING]: Module "${urlString}" needs an import assertion of type "json"`) as TypeError & { code: string };
31-
err.code = `ERR_IMPORT_ASSERTION_TYPE_MISSING`;
32-
throw err;
32+
if (HAS_JSON_IMPORT_ASSERTION_REQUIREMENT && format === `json`) {
33+
if (SUPPORTS_IMPORT_ATTRIBUTES_ONLY) {
34+
if (context.importAttributes?.type !== `json`) {
35+
const err = new TypeError(`[ERR_IMPORT_ATTRIBUTE_MISSING]: Module "${urlString}" needs an import attribute of "type: json"`) as TypeError & { code: string };
36+
err.code = `ERR_IMPORT_ATTRIBUTE_MISSING`;
37+
throw err;
38+
}
39+
} else {
40+
const type = `importAttributes` in context ? context.importAttributes?.type : context.importAssertions?.type;
41+
if (type !== `json`) {
42+
const err = new TypeError(`[ERR_IMPORT_ASSERTION_TYPE_MISSING]: Module "${urlString}" needs an import ${SUPPORTS_IMPORT_ATTRIBUTES ? `attribute` : `assertion`} of type "json"`) as TypeError & { code: string };
43+
err.code = `ERR_IMPORT_ASSERTION_TYPE_MISSING`;
44+
throw err;
45+
}
46+
}
3347
}
3448

3549
// https://github.com/nodejs/node/pull/44366/files#diff-f6796082f599554ec3a29c47cf026cb24fc5104884f2632e472c05fe622d778bR477-R479

packages/yarnpkg-pnp/sources/esm-loader/loaderFlags.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,9 @@ export const ALLOWS_NON_FILE_PARENT = major > 18 || (major === 18 && minor >= 1)
2626

2727
// https://github.com/nodejs/node/pull/49869
2828
export const ALLOWS_EXTENSIONLESS_FILES = major >= 21 || (major === 20 && minor >= 10) || (major === 18 && minor >= 19);
29+
30+
// https://github.com/nodejs/node/pull/50140
31+
export const SUPPORTS_IMPORT_ATTRIBUTES = major >= 21 || (major === 20 && minor >= 10) || (major === 18 && minor >= 20);
32+
33+
// https://github.com/nodejs/node/pull/52104
34+
export const SUPPORTS_IMPORT_ATTRIBUTES_ONLY = major >= 22;

0 commit comments

Comments
 (0)