Skip to content
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

Next.js + TS not working out of the box #27448

Closed
lmiller1990 opened this issue Aug 3, 2023 · 8 comments · Fixed by #27484
Closed

Next.js + TS not working out of the box #27448

lmiller1990 opened this issue Aug 3, 2023 · 8 comments · Fixed by #27484

Comments

@lmiller1990
Copy link
Contributor

npx create-next-app@latest
# pick a name
# you want typescript
# cd in
npm install cypress
npx cypress open

Choose CT

$ npx cypress open                                   (git)-[main]-
It looks like this is your first time using Cypress: 12.17.3

✔  Verified Cypress! /Users/lachlanmiller/Library/Caches/Cypress…

Opening Cypress...

DevTools listening on ws://127.0.0.1:64587/devtools/browser/2450b5e1-62a4-4a62-b9fc-2c24fc8c158c
Missing baseUrl in compilerOptions. tsconfig-paths will be skipped
/Users/lachlanmiller/Library/Caches/Cypress/12.17.3/Cypress.app/Contents/Resources/app/node_modules/ts-node/dist/index.js:311
        return new TSError(diagnosticText, diagnosticCodes, diagnostics);
               ^
TSError: ⨯ Unable to compile TypeScript:
error TS5095: Option 'bundler' can only be used when 'module' is set to 'es2015' or later.

I think we are not working with "moduleResolution": "bundler"

https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#moduleresolution-bundler

Probably related: #26308

@lmiller1990
Copy link
Contributor Author

Work around for now is change to node:

"moduleResolution": "node"

This makes basically no difference from what I can tell for Next.js, but broken out of the box is a bad look. I will try to patch this quickly.

@karlhorky
Copy link
Contributor

karlhorky commented Aug 3, 2023

Workaround

For people looking for a temporary workaround, probably better to only apply the old, obsolete "moduleResolution": "Node" option (which is required for Cypress to work) to the ts-node options, to reduce the usage throughout your codebase:

tsconfig.json

{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "Bundler"
  },
+ // Old "moduleResolution": "Node" option required for Cypress
+ // https://github.com/cypress-io/cypress/issues/26308#issuecomment-1663592648
+ //
+ // TODO: Remove when issue is resolved https://github.com/cypress-io/cypress/issues/27448
+ "ts-node": {
+   "compilerOptions": {
+     "module": "ESNext",
+     "moduleResolution": "Node"
+   }
+ }
}

wingy3181 added a commit to wingy3181/cypress-e2e-streaming-poc that referenced this issue Aug 3, 2023
@lmiller1990
Copy link
Contributor Author

We need to fix this in core asap, this is a showstopper, will look into it asap.

@lmiller1990
Copy link
Contributor Author

lmiller1990 commented Aug 8, 2023

Bit of background / rant, but I understand what we need to do now, I think. It's kind of unfortunate the JS ecosystem has headed in this direction... some context follows:

I just read https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#moduleresolution-bundler in more detail to get an idea of what module: bundler implies. My understanding: there is no format definition. By setting module: bundler, you are opting out of any known module system, and into an ad-hoc fusion of CommonJS and ES Modules.

From the TS release notes:

But in some ways, the original node resolution mode was already out of date. Most modern bundlers use a fusion of the ECMAScript module and CommonJS lookup rules in Node.js. For example, extensionless imports work just fine like in CommonJS, but when looking through the export conditions of a package, they’ll prefer an import condition just like in an ECMAScript file.

To model how bundlers work, TypeScript now introduces a new strategy: --moduleResolution bundler.

This is the real root of the endless complexity in the JavaScript ecosystem. Instead of trying to use the real module system that is supported by both browsers and Node.js natively, bundlers decided to just define our own in userland. It's a weird fusion of CommonJS and ES Modules.

error TS5095: Option 'bundler' can only be used when 'module' is set to 'es2015' or later.

Why can't I use moduleResolution: bundler with module: commonjs? You can use webpack to bundle a code base using commonjs, right? It looks like this was touched on in the actual PR with no real conclusive answer: microsoft/TypeScript#51669.


I am suspecting this actual problem is this:

We hard-code module: "commonjs" here, but this does not make sense for many code bases anymore. It might have at the time, but not anymore. We can remove that for CT only - that might be best. I tried that, but now I got some other equally frustrating error:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /Users/lachlanmiller/code/work/ct-automation/npx-create-next-app/cypress.config.ts

That's because, unlike the Next.js dev server, Cypress itself is an Electron app that does use module: commonjs. I think we can fix that by moving the commonjs inside here:

.

This seems to work, at least for the Next.js example.

@lmiller1990
Copy link
Contributor Author

I have no idea if this is a breaking change or what the impact is, but trying: #27484

We will likely need some additional logic to handle resolving and running the cypress.config.ts that is defined using ES syntax in a non type: module project. Let's see how CI goes for now.

@karlhorky
Copy link
Contributor

karlhorky commented Aug 8, 2023

Since you hit the [ERR_UNKNOWN_FILE_EXTENSION ]: Unknown file extension ".ts" error again, it may also make sense to batch this change with additional TS + ESM fixes from the long-running issue here:

  1. As mentioned in point one in your comment here, you could try applying ESM always to TypeScript compilations (also mentioned in my suggestion from December 2022):

    B) can ts-node/esm always be used, also for CJS files?

    After Spec API TypeScript Code breaks the config.ts file - [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" #23141 (comment)

    Now that you're modifying the TS configuration, you may want to consider this - this may offer a solution to multiple problems at once, and may be simpler overall.

  2. A second suggestion here was to support cypress.config.mts as seen in Support cypress.config.mts #24962 , although this is less relevant here

@lmiller1990
Copy link
Contributor Author

lmiller1990 commented Aug 9, 2023

Yeah, I think we need a proper, big picture solution, endlessly patching every use case is really impractical and painful. I'll do a little more digging around this and see if we can actually simplify things - I think the complexity in Cypress is starting to leak out a bit.

mts should definitely be supported, I think this cannot work until something is done about commonjs here:

. mts will not work due to this override, I think this probably made sense a while ago, but not anymore, since using ESM is actually becoming a thing (well... kind of. It's not really ESM, but the weird "commonjs/ES module" mix, which is what module: bundler is all about).

I'm really disappointed TS actually supports this weird ESM/CJS mix of module systems - call it chimera.js if you will, since that's what it is - a hybrid between two module systems. TS is meant to be a superset of JS - I think that should include the module systems, which are CommonJS and ESM - supporting this weird bundler defined module system should have been outside the scope of TypeScript, imo. It's a little depressing that we have two perfectly servicable module systems, CommonJS and ESM (and Node.js supports both!!) yet hardly anyone is actually using either of them in their native form :'(

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Aug 29, 2023

Released in 13.0.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v13.0.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Aug 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants