-
Notifications
You must be signed in to change notification settings - Fork 3.3k
feat: replace ts-node
with tsx
for parsing user configuration
#31520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/15.0.0
Are you sure you want to change the base?
feat: replace ts-node
with tsx
for parsing user configuration
#31520
Conversation
463841e
to
3f1487c
Compare
cypress
|
Project |
cypress
|
Branch Review |
feat/replace_tsnode_for_tsx_config_process
|
Run status |
|
Run duration | 16m 42s |
Commit |
|
Committer | AtofStryker |
View all properties for this run ↗︎ |
Test results | |
---|---|
|
0
|
|
1
|
|
29
|
|
0
|
|
794
|
View all changes introduced in this branch ↗︎ |
UI Coverage
63.64%
|
|
---|---|
|
30
|
|
56
|
Accessibility
96.22%
|
|
---|---|
|
0 critical
4 serious
1 moderate
0 minor
|
|
195
|
3f1487c
to
3803906
Compare
3803906
to
dd4a87b
Compare
…cypress 15 and allows us to not include the 18.19.0 workaround to use --import with tsx inside the ProjectConfigIpc
…s absolute drive paths are not recognized as a file protocol in the node context
… to this PR and should be merged into develop)
e069098
to
916a742
Compare
…not work but now do with tsx
ts-node
with tsx
for parsing user configuration
…eat/replace_tsnode_for_tsx_config_process
/** | ||
* Before the introduction of tsx, Cypress used ts-node (@see https://github.com/TypeStrong/ts-node) with native node to try and load the user's cypress.config.ts file. | ||
* This presented problems because the Cypress node runtime runs in commonjs, which may not be compatible with the user's cypress.config.ts and tsconfig.json. | ||
* To mitigate the aforementioned runtime incompatibility, we used to force TypeScript options for the user in order to load their config inside the our node context | ||
* via a child process, which lead to clashes and issues (outlined in the comments below). | ||
* This is best explained historically in our docs which a screenshot can be see in @see https://github.com/cypress-io/cypress/issues/30426#issuecomment-2805204540 and can be seen | ||
* in an older version of the Cypress codebase (@see https://github.com/cypress-io/cypress/blob/v14.3.0/packages/server/lib/plugins/child/ts_node.js#L24) | ||
* | ||
* Attempted workarounds with ts-node and node: @see https://github.com/cypress-io/cypress/pull/28709 | ||
* Example continued end user issues: @see https://github.com/cypress-io/cypress/issues/30954 and @see https://github.com/cypress-io/cypress/issues/30925 | ||
* Spike into ts-node alternatives (a lot of useful comments on tsx): @see https://github.com/cypress-io/cypress/issues/30426 | ||
* feature issue to replace ts-node as our end user TypeScript loader: @see https://github.com/cypress-io/cypress/issues/31185 | ||
* | ||
* tsx (@see https://tsx.is/) is able to work with both CommonJS and ESM at the same time ( @see https://tsx.is/#seamless-cjs-%E2%86%94-esm-imports), which solves the problem of interoperability that | ||
* Cypress faced with ts-node and really just node itself. We no longer need experimental node flags and ts-node permutations to load the user's config file. | ||
* We can use tsx to load just about anything, including JavaScript files (@see https://github.com/privatenumber/ts-runtime-comparison)! | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there value in having comments about code that's no longer in the repo here? I'm not understanding how I would find how Cypress used to work valuable here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I felt like we should capture it here someplace because why else are we using different tooling to register the user config than how we do it everywhere else in the repo? At least until we unify it maybe? or link out in the comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want this captured someplace but I don't think this is the best place. any ideas?
import type { DataContext } from '..' | ||
|
||
const tsxCodeFrameFilter = '/node_modules/tsx/dist/register' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would we be able to catch if this path changed in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would think the transform error tests in the app package cy-in-cy tests would error since the codeFrame would be broken and missing, which the test checks for https://github.com/cypress-io/cypress/blob/develop/packages/launchpad/cypress/e2e/config-files-error-handling.cy.ts#L204
…eat/replace_tsnode_for_tsx_config_process
Dismissing my comments as addressed
…om:cypress-io/cypress into feat/replace_tsnode_for_tsx_config_process
@@ -95,13 +95,13 @@ async function setFocus () { | |||
async function getBrowserLauncher (browser: Browser, browsers: FoundBrowser[]): Promise<BrowserLauncher> { | |||
debug('getBrowserLauncher %o', { browser }) | |||
|
|||
if (browser.name === 'electron') return await import('./electron') | |||
if (browser.name === 'electron') return require('./electron') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: can we type this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's somewhat irrelevant but we could also explore just importing the files at the top and returning them here
browser: 'electron', | ||
project: 'yarn-v3.1.1-pnp', | ||
onRun: async (run) => { | ||
await run({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this one is a bit bizarre, but the --dev
mode doesn't work exactly correct here has we are using ts-node
to register the typescript options, which pollutes the tsconfig with allowSyntheticDefaultImports
and was causing the test to fail. Not sure why we need dev mode here, but it works fine without it to completely isolate us from ts-node
in our system tests
…st threshold / latest values. Removed redundant comments on ts-node.
@@ -10,6 +10,10 @@ _Released 07/01/2025 (PENDING)_ | |||
- Removed support for [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol) with the [firefox](https://www.mozilla.org/) browser. Addresses [#31189](https://github.com/cypress-io/cypress/issues/31189). | |||
- The Cypress configuration wizard for Component Testing supports TypeScript 5.0 or greater. Addresses [#31187](https://github.com/cypress-io/cypress/issues/31187). | |||
|
|||
**Features:** | |||
|
|||
- [`tsx`](https://tsx.is/) is now used in all cases to run the Cypress config, replacing [ts-node](https://github.com/TypeStrong/ts-node) for TypeScript and Node for commonjs/ESM. This should allow for more interoperability for users who are using any variant of ES Modules. Addresses [#8090](https://github.com/cypress-io/cypress/issues/8090), [#15724](https://github.com/cypress-io/cypress/issues/15724), [#21805](https://github.com/cypress-io/cypress/issues/21805), [#22273](https://github.com/cypress-io/cypress/issues/22273), [#22747](https://github.com/cypress-io/cypress/issues/22747), [#23141](https://github.com/cypress-io/cypress/issues/23141), [#25958](https://github.com/cypress-io/cypress/issues/25958), [#25959](https://github.com/cypress-io/cypress/issues/25959), [#26606](https://github.com/cypress-io/cypress/issues/26606), [#27359](https://github.com/cypress-io/cypress/issues/27359), [#27450](https://github.com/cypress-io/cypress/issues/27450), [#28442](https://github.com/cypress-io/cypress/issues/28442), [#30318](https://github.com/cypress-io/cypress/issues/30318), [#30718](https://github.com/cypress-io/cypress/issues/30718), [#30907](https://github.com/cypress-io/cypress/issues/30907), [#30915](https://github.com/cypress-io/cypress/issues/30915), [#30925](https://github.com/cypress-io/cypress/issues/30925), [#30954](https://github.com/cypress-io/cypress/issues/30954) and [#31185](https://github.com/cypress-io/cypress/issues/31185). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love this long list 👍🏻
Closes
ts-node
withtsx
for user configuration parsing and cypress runtime #31185--experimental-loader
" #30318 (no longer need the--experimental-loader
option)--experimental-loader
option)tsx
will be used to replacets-node
instead ofjiti
)"allowImportingTsExtensions": true
#28442Side effect of not using Node as the loader
--no-experimental-require-module
as we aren't using Node directly as the file loader. see https://nodejs.org/en/blog/release/v22.12.0#requireesm-is-now-enabled-by-default)-Reinforces
ERR_INTERNAL_ASSERTION
with Node.js >= v22.1.0 andexperimental-detect-module
set #30101 (don't need to worry about the--no-experimental-detect-module
option as we aren't using Node directly as the file loader. see https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V22.md?rgh-link-date=2024-08-22T15%3A58%3A27Z#module-syntax-detection-is-now-enabled-by-default)Additional details
Introduces
tsx
as the new tool of choice to load and parse the end user'scypress.config.(js|ts)
, replacingts-node
. This solves a lot of issues around ESM projects using Cypress as we are now able to more easily run ESM based cypress configurations (TypeScript or JavaScript) within the Cypress child process. This means we don't needts-node
work arounds to try to run the user's config ascommonjs
, which results in configuration clashes in TypeScript, nor do we need nodes experimental loaders / options to run ESM JavaScript projects.Steps to test
Go through some of the reproductions in the aforementioned issues and run the pre release binary installed in the project. Notice the project is now able to run
How has the user experience changed?
The TypeScript / ESM experience is greatly improved as users are now able to run Cypress in their project without having to commit to hacky workarounds!
PR Tasks
cypress-documentation
? chore: update typescript docs to tsx cypress-documentation#6155type definitions
? (N/A)