Skip to content

Commit

Permalink
fix(pnp): allow ESM loader to load arbitrary file extensions as CJS
Browse files Browse the repository at this point in the history
  • Loading branch information
kherock committed Dec 1, 2021
1 parent 4bf39c9 commit 70a8f61
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 11 deletions.
44 changes: 42 additions & 2 deletions packages/acceptance-tests/pkg-tests-specs/sources/pnp-esm.test.ts
Expand Up @@ -194,7 +194,25 @@ describe(`Plug'n'Play - ESM`, () => {
);

test(
`it should not allow unknown extensions`,
`it should load commonjs with an unknown extension`,
makeTemporaryEnv(
{
},
async ({path, run, source}) => {
await xfs.writeFilePromise(ppath.join(path, `index.ts` as Filename), `console.log(typeof require === 'undefined')`);

await expect(run(`install`)).resolves.toMatchObject({code: 0});

await expect(run(`node`, `./index.ts`)).resolves.toMatchObject({
code: 0,
stdout: `false\n`,
});
},
),
);

test(
`it should not allow unknown extensions with {type: "module"}`,
makeTemporaryEnv(
{
type: `module`,
Expand All @@ -214,7 +232,7 @@ describe(`Plug'n'Play - ESM`, () => {

// Tests https://github.com/nodejs/node/issues/33226
test(
`it should not load extensionless commonjs files as ESM`,
`it should load extensionless commonjs files`,
makeTemporaryEnv(
{ },
{
Expand All @@ -233,6 +251,28 @@ describe(`Plug'n'Play - ESM`, () => {
),
);

test(
`it should not allow extensionless files with {"type": "module"}`,
makeTemporaryEnv(
{
type: `module`,
},
{
pnpEnableEsmLoader: true,
},
async ({path, run, source}) => {
await xfs.writeFilePromise(ppath.join(path, `index` as Filename), ``);

await expect(run(`install`)).resolves.toMatchObject({code: 0});

await expect(run(`node`, `./index`)).rejects.toMatchObject({
code: 1,
stderr: expect.stringContaining(`Unknown file extension`),
});
},
),
);

test(
`it should support ESM binaries`,
makeTemporaryEnv(
Expand Down
2 changes: 1 addition & 1 deletion packages/yarnpkg-pnp/sources/esm-loader/built-loader.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 16 additions & 8 deletions packages/yarnpkg-pnp/sources/esm-loader/loaderUtils.ts
Expand Up @@ -48,16 +48,24 @@ export function getFileFormat(filepath: string): string | null {
`Unknown file extension ".json" for ${filepath}`,
);
}
// Matching files without extensions deviates from Node's default
// behaviour but is a fix for https://github.com/nodejs/node/issues/33226
case ``:
case `.js`: {
const pkg = nodeUtils.readPackageScope(filepath);
if (pkg) {
return pkg.data.type ?? `commonjs`;
}
// assume CJS for files outside of a package boundary
if (!pkg)
return `commonjs`;
return pkg.data.type ?? `commonjs`;
}
// Matching files beyond those handled above deviates from Node's default
// --experimental-loader behavior but is required to work around
// https://github.com/nodejs/node/issues/33226
default: {
const pkg = nodeUtils.readPackageScope(filepath);
if (!pkg)
return `commonjs`;
// prevent extensions beyond .mjs or .js from loading as ESM
if (pkg.data.type === `module`)
return null;
return pkg.data.type ?? `commonjs`;
}
}

return null;
}

0 comments on commit 70a8f61

Please sign in to comment.