feat: always enable ESM loader with the new API (#29991)
It does not require a process restart anymore, so safe to enable. Fixes #29747.
This commit is contained in:
parent
b41b802662
commit
be1af15d57
|
|
@ -334,25 +334,33 @@ export async function loadEmptyConfigForMergeReports() {
|
|||
}
|
||||
|
||||
export function restartWithExperimentalTsEsm(configFile: string | undefined, force: boolean = false): boolean {
|
||||
const nodeVersion = +process.versions.node.split('.')[0];
|
||||
// New experimental loader is only supported on Node 16+.
|
||||
if (nodeVersion < 16)
|
||||
return false;
|
||||
if (!configFile && !force)
|
||||
return false;
|
||||
// Opt-out switch.
|
||||
if (process.env.PW_DISABLE_TS_ESM)
|
||||
return false;
|
||||
// Node.js < 20
|
||||
|
||||
// There are two esm loader APIs:
|
||||
// - Older API that needs a process restart. Available in Node 16, 17, and non-latest 18, 19 and 20.
|
||||
// - Newer API that works in-process. Available in Node 21+ and latest 18, 19 and 20.
|
||||
|
||||
// First check whether we have already restarted with the ESM loader from the older API.
|
||||
if ((globalThis as any).__esmLoaderPortPreV20) {
|
||||
// clear execArgv after restart, so that childProcess.fork in user code does not inherit our loader.
|
||||
process.execArgv = execArgvWithoutExperimentalLoaderOptions();
|
||||
return false;
|
||||
}
|
||||
if (!force && !fileIsModule(configFile!))
|
||||
return false;
|
||||
|
||||
// Node.js < 20
|
||||
// Now check for the newer API presence.
|
||||
if (!require('node:module').register) {
|
||||
// Older API is experimental, only supported on Node 16+.
|
||||
const nodeVersion = +process.versions.node.split('.')[0];
|
||||
if (nodeVersion < 16)
|
||||
return false;
|
||||
|
||||
// With older API requiring a process restart, do so conditionally on the config.
|
||||
const configIsModule = !!configFile && fileIsModule(configFile);
|
||||
if (!force && !configIsModule)
|
||||
return false;
|
||||
|
||||
const innerProcess = (require('child_process') as typeof import('child_process')).fork(require.resolve('../../cli'), process.argv.slice(2), {
|
||||
env: {
|
||||
...process.env,
|
||||
|
|
@ -367,7 +375,8 @@ export function restartWithExperimentalTsEsm(configFile: string | undefined, for
|
|||
});
|
||||
return true;
|
||||
}
|
||||
// Nodejs >= 21
|
||||
|
||||
// With the newer API, always enable the ESM loader, because it does not need a restart.
|
||||
registerESMLoader();
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -552,7 +552,9 @@ test('should load cjs config and test in non-ESM mode', async ({ runInlineTest }
|
|||
expect(result.passed).toBe(2);
|
||||
});
|
||||
|
||||
test('should disallow ESM when config is cjs', async ({ runInlineTest }) => {
|
||||
test('should allow ESM when config is cjs', async ({ runInlineTest, nodeVersion }) => {
|
||||
test.skip(nodeVersion.major < 18, 'ESM loader is enabled conditionally with older API');
|
||||
|
||||
const result = await runInlineTest({
|
||||
'package.json': `{ "type": "module" }`,
|
||||
'playwright.config.cjs': `
|
||||
|
|
@ -567,8 +569,24 @@ test('should disallow ESM when config is cjs', async ({ runInlineTest }) => {
|
|||
`,
|
||||
});
|
||||
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.output).toContain('Unknown file extension ".ts"');
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.passed).toBe(1);
|
||||
});
|
||||
|
||||
test('should load mts without config', async ({ runInlineTest, nodeVersion }) => {
|
||||
test.skip(nodeVersion.major < 18, 'ESM loader is enabled conditionally with older API');
|
||||
|
||||
const result = await runInlineTest({
|
||||
'a.test.mts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
test('check project name', ({}, testInfo) => {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
`,
|
||||
});
|
||||
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.passed).toBe(1);
|
||||
});
|
||||
|
||||
test('should be able to use use execSync with a Node.js file inside a spec', async ({ runInlineTest }) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue