fix: error loading config file with node 22.12.0 (#30730)

This commit is contained in:
Ryan Manuel
2024-12-10 19:36:17 -07:00
committed by GitHub
parent ed1c510ac4
commit 73de0a8d4d
6 changed files with 33 additions and 30 deletions

View File

@@ -42,7 +42,7 @@ macWorkflowFilters: &darwin-workflow-filters
- equal: [ develop, << pipeline.git.branch >> ]
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
- equal: [ 'chore/update_reporter_mobx', << pipeline.git.branch >> ]
- equal: [ 'ryanm/experiment/esm', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
@@ -152,7 +152,7 @@ commands:
name: Set environment variable to determine whether or not to persist artifacts
command: |
echo "Setting SHOULD_PERSIST_ARTIFACTS variable"
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "chore/update_reporter_mobx" ]]; then
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "ryanm/experiment/esm" ]]; then
export SHOULD_PERSIST_ARTIFACTS=true
fi' >> "$BASH_ENV"
# You must run `setup_should_persist_artifacts` command and be using bash before running this command

View File

@@ -7,6 +7,7 @@ _Released 12/17/2024 (PENDING)_
- Fixed an issue where targets may hang if `Network.enable` is not implemented for the target. Addresses [#29876](https://github.com/cypress-io/cypress/issues/29876).
- Updated Firefox `userChrome.css` to correctly hide the toolbox during headless mode. Addresses [#30721](https://github.com/cypress-io/cypress/issues/30721).
- Fixed an issue loading the `cypress.config.ts` file with Node.js version `22.12.0`. Addresses [#30715](https://github.com/cypress-io/cypress/issues/30715).
**Dependency Updates:**

View File

@@ -313,6 +313,14 @@ export class ProjectConfigIpc extends EventEmitter {
tsNodeEsmLoader = `${tsNodeEsmLoader} --no-experimental-detect-module`
}
// in nodejs 22.12.0, the --experimental-require-module option is now enabled by default.
// We need to disable it with the --no-experimental-require-module flag.
// @see https://github.com/cypress-io/cypress/issues/30715
if (this.nodeVersion && semver.gte(this.nodeVersion, '22.12.0')) {
debug(`detected node version ${this.nodeVersion}, adding --no-experimental-require-module option to child_process NODE_OPTIONS.`)
tsNodeEsmLoader = `${tsNodeEsmLoader} --no-experimental-require-module`
}
if (childOptions.env.NODE_OPTIONS) {
childOptions.env.NODE_OPTIONS += ` ${tsNodeEsmLoader}`
} else {

View File

@@ -1,5 +1,6 @@
import childProcess from 'child_process'
import { expect } from 'chai'
import semver from 'semver'
import sinon from 'sinon'
import { scaffoldMigrationProject as scaffoldProject } from '../helper'
import { ProjectConfigIpc } from '../../../src/data/ProjectConfigIpc'
@@ -34,8 +35,11 @@ describe('ProjectConfigIpc', () => {
})
context('forkChildProcess', () => {
const NODE_VERSIONS = ['18.20.4', '20.17.0']
const NODE_VERSIONS_22_7_0_AND_UP = ['22.7.0', '22.11.4']
// some of these node versions may not exist, but we want to verify
// the experimental flags are correctly disabled for future versions
const NODE_VERSIONS = ['18.20.4', '20.17.0', '22.7.0', '22.11.4', '22.12.0', '22.15.0']
const experimentalDetectModuleIntroduced = '22.7.0'
const experimentalRequireModuleIntroduced = '22.12.0'
let projectConfigIpc
let forkSpy
@@ -52,10 +56,10 @@ describe('ProjectConfigIpc', () => {
})
context('typescript', () => {
[...NODE_VERSIONS, ...NODE_VERSIONS_22_7_0_AND_UP].forEach((nodeVersion) => {
[...NODE_VERSIONS].forEach((nodeVersion) => {
context(`node v${nodeVersion}`, () => {
context('ESM', () => {
it('uses the experimental module loader if ESM is being used with typescript', async () => {
it('passes the correct experimental flags if ESM is being used with typescript', async () => {
// @ts-expect-error
const projectPath = await scaffoldProject('config-cjs-and-esm/config-with-ts-module')
@@ -77,35 +81,23 @@ describe('ProjectConfigIpc', () => {
NODE_OPTIONS: sinon.match('--experimental-specifier-resolution=node --loader'),
},
}))
})
// @see https://github.com/cypress-io/cypress/issues/30084
// at time of writing, 22.11.4 is a node version that does not exist. We are using this version to test the logic for future proofing.
if (NODE_VERSIONS_22_7_0_AND_UP.includes(nodeVersion)) {
it(`additionally adds --no-experimental-detect-module for node versions 22.7.0 and up if ESM is being used with typescript`, async () => {
// @ts-expect-error
const projectPath = await scaffoldProject('config-cjs-and-esm/config-with-ts-module')
const MOCK_NODE_PATH = `/Users/foo/.nvm/versions/node/v${nodeVersion}/bin/node`
const MOCK_NODE_VERSION = nodeVersion
projectConfigIpc = new ProjectConfigIpc(
MOCK_NODE_PATH,
MOCK_NODE_VERSION,
projectPath,
'cypress.config.js',
false,
(error) => {},
() => {},
)
if (semver.gte(nodeVersion, experimentalDetectModuleIntroduced)) {
expect(forkSpy).to.have.been.calledWith(sinon.match.string, sinon.match.array, sinon.match({
env: {
NODE_OPTIONS: sinon.match('--no-experimental-detect-module'),
},
}))
})
}
}
if (semver.gte(nodeVersion, experimentalRequireModuleIntroduced)) {
expect(forkSpy).to.have.been.calledWith(sinon.match.string, sinon.match.array, sinon.match({
env: {
NODE_OPTIONS: sinon.match('--no-experimental-require-module'),
},
}))
}
})
})
context('CommonJS', () => {

View File

@@ -3,7 +3,7 @@ import { defineConfig } from 'cypress'
export default defineConfig({
e2e: {
supportFile: false,
setupNodeEvents: async (_, config) => {
setupNodeEvents: async (_, config: Cypress.PluginConfigOptions) => {
await import('find-up')
return config

View File

@@ -30,6 +30,7 @@ describe('binary node versions', () => {
'cypress/base:20.12.2',
'cypress/base:22.0.0',
'cypress/base:22.7.0',
'cypress/base:22.12.0',
].forEach(smokeTestDockerImage)
})
@@ -39,6 +40,7 @@ describe('type: module', () => {
'cypress/base:20.12.2',
'cypress/base:22.0.0',
'cypress/base:22.7.0',
'cypress/base:22.12.0',
].forEach((dockerImage) => {
systemTests.it(`can run in ${dockerImage}`, {
withBinary: true,