Skip to content

Commit

Permalink
feat: support ESM (#270)
Browse files Browse the repository at this point in the history
  • Loading branch information
merceyz authored Jun 13, 2023
1 parent 5956d95 commit be2489c
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 48 deletions.
8 changes: 7 additions & 1 deletion sources/corepackUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {createHash} from 'crypto';
import {once} from 'events';
import fs from 'fs';
import type {Dir} from 'fs';
import Module from 'module';
import path from 'path';
import semver from 'semver';

Expand Down Expand Up @@ -214,5 +215,10 @@ export async function runVersion(locator: Locator, installSpec: { location: stri
];
process.execArgv = [];

return nodeUtils.loadMainModule(binPath);
// Unset the mainModule and let Node.js set it when needed.
process.mainModule = undefined;

// Use nextTick to unwind the stack, and consequently remove Corepack from
// the stack trace of the package manager.
process.nextTick(Module.runMain, binPath);
}
16 changes: 0 additions & 16 deletions sources/module.d.ts

This file was deleted.

27 changes: 0 additions & 27 deletions sources/nodeUtils.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,3 @@
import Module from 'module';
import path from 'path';

/**
* Loads a module as a main module, enabling the `require.main === module` pattern.
*/
export function loadMainModule(id: string): void {
const modulePath = Module._resolveFilename(id, null, true);

const module = new Module(modulePath, undefined);

module.filename = modulePath;
module.paths = Module._nodeModulePaths(path.dirname(modulePath));

Module._cache[modulePath] = module;

process.mainModule = module;
module.id = `.`;

try {
return module.load(modulePath);
} catch (error) {
delete Module._cache[modulePath];
throw error;
}
}

export interface NodeError extends Error {
code: string;
}
36 changes: 32 additions & 4 deletions tests/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,10 @@ it(`should not override the package manager exit code`, async () => {
});
});

it(`should not override the package manager exit code when it throws`, async () => {
it(`should not preserve the process.exitCode when a package manager throws`, async () => {
// Node.js doesn't preserve process.exitCode when an exception is thrown
// so we need to make sure we don't break this behaviour.

await xfs.mktempPromise(async cwd => {
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
packageManager: `[email protected]`,
Expand All @@ -575,9 +578,9 @@ it(`should not override the package manager exit code when it throws`, async ()
`);

await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({
exitCode: 42,
stdout: expect.stringContaining(`foo`),
stderr: ``,
exitCode: 1,
stdout: ``,
stderr: expect.stringContaining(`foo`),
});
});
});
Expand Down Expand Up @@ -606,3 +609,28 @@ it(`should not set the exit code after successfully launching the package manage
});
});
});

it(`should support package managers in ESM format`, async () => {
await xfs.mktempPromise(async cwd => {
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
packageManager: `[email protected]`,
});

const yarnDir = ppath.join(npath.toPortablePath(process.env.COREPACK_HOME!), `yarn/2.2.2` as PortablePath);

await xfs.mkdirPromise(yarnDir, {recursive: true});
await xfs.writeFilePromise(ppath.join(yarnDir, `yarn.js` as PortablePath), `
import 'fs';
console.log(42);
`);
await xfs.writeJsonPromise(ppath.join(yarnDir, `package.json` as PortablePath), {
type: `module`,
});

await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({
exitCode: 0,
stdout: `42\n`,
stderr: ``,
});
});
});
Binary file added tests/nock/6YlkCvzyrFlW9WizGIO9AA-1.dat
Binary file not shown.
Binary file added tests/nock/urO1i4GpxQt29UQLMf23wA-1.dat
Binary file not shown.

0 comments on commit be2489c

Please sign in to comment.