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

Upgrade to cypress 10 for typescript project broken (from 9.6) #22071

Closed
josh803316 opened this issue Jun 3, 2022 · 33 comments
Closed

Upgrade to cypress 10 for typescript project broken (from 9.6) #22071

josh803316 opened this issue Jun 3, 2022 · 33 comments
Assignees
Labels
stage: investigating Someone from Cypress is looking into this topic: typescript v10.0.2 🐛 Issue present since 10.0.2

Comments

@josh803316
Copy link

Current behavior

As outlined in this issue that was closed prematurely:
#21997

cc @lmiller1990

When I upgrade our existing typescript project it fails with various typescript errors (see the issue listed above). I have created a sample repo that reproduces the issues.

Desired behavior

Smooth upgrade and conversion of support scripts, plugins and specs.

Test code to reproduce

https://github.com/sketchy/cypress10-upgrade-issue
Simply close the repo, update Cypress to 10, follow the upgrade UI process and see the errors.

Cypress Version

10.0.2

Other

Sample repro to reproduce: https://github.com/sketchy/cypress10-upgrade-issue

@spiffytech
Copy link

spiffytech commented Jun 3, 2022

I'm also still getting upgrade errors on 10.0.2. I had to remove the plugin file property from my cypress.json in order for the migrator to start up. After migration, Cypress refuses to start, saying:

Your configFile is invalid: /home/.../cypress.config.ts
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"

@lmiller1990
Copy link
Contributor

Thanks, I am looking into this now.

@lmiller1990
Copy link
Contributor

Thanks, to clarify I was able to reproduce. I am on Node.js 16 and windows. I also reproduced on macOS.

image

@lmiller1990 lmiller1990 self-assigned this Jun 3, 2022
@spiffytech
Copy link

It's happening for me with Node 18 on Linux.

@lmiller1990
Copy link
Contributor

lmiller1990 commented Jun 3, 2022

Edit: see this comment, I think this entire error message was a red herring.

Initially, what seemed to be happening is we hit this line - return await import(pathToFileURL(file).href). In this case we are trying to import a ts file and Node is defaulting to it's native ESM loader, which obviously doesn't work.

On closer inspection, this makes no sense in the first place. The entire logic for loading the config is here. Basically:

  1. Try loading the configFile
  2. Catch the "ERR_REQUIRE_ESM" error if we hit one
  3. Check if esbuild is installed
    3a. Yes: use it
  4. Use node's dynamic import to import the configFile

In your case, we should be just doing (1) since you are using TS - we can just use your local typescript in combination with the ts-node shipped in Cypress. That would mean we return early here.

What's actually happening, outlined here, is you've got a cypress/index.js file (which is unused?) containing ESM import code. This was messing with things, and made Cypress think you were using native ESM (which you are not) and skipping to step 4, attempting to import what is expected to be an ESM file (but it was actually .ts, thus the error).

Removing the unused cypress/index.js fixed it (what is this for?). See my post below for exact what was going on.

@lmiller1990
Copy link
Contributor

lmiller1990 commented Jun 3, 2022

As part of this I found another potential issue: we are trying to use esbuild for ESM, eg .mjs and "type": "module"`, but it's not set up correctly, see #22074.

@lmiller1990
Copy link
Contributor

lmiller1990 commented Jun 3, 2022

@josh803316 I found I could just do rm cypress/index.js and your project works just fine. Can you give this a try? I think what's happening is, somehow, when we do import { defineConfig } from 'cypress', it ends up resolving the contents of cypress/index.js instead of the node_modules/cypress (!!!).

You actually said this here I'm sorry I missed it. Clearly require.resolve('cypress') should not be returning /Users/josh/git/core-web/cypress/index.ts - that's not where Cypress is installed.

What is this file supposed to be? Plugins go in cypress/plugins/index.js. There's no such functionality associated with cypress/index.js.

Either way, this also explains how you ran into defineConfig is not a function (here) - it was expecting that file to export a defineConfig, which is was not.

I think this should solve your problem?

@lmiller1990
Copy link
Contributor

@spiffytech can you share a minimal repo, or at least some basic info about your project? Although you hit the same problem, it might be due to a different reason.

@maksim-romanov
Copy link

maksim-romanov commented Jun 3, 2022

It's happening for me with Node 18 on MacOs.

i don't have a cypress/index.ts file

@lmiller1990
Copy link
Contributor

@maksim-romanov Hi, thanks for chiming in. Can you provide a minimal repository with the bug? Repo would be ideal - just delete anything that isn't directly related to Cypress. Or if you cannot, your cypress.config.js, cypress/plugins/index.js, package.json etc? That will help with debugging. 🙏

@spiffytech
Copy link

@spiffytech can you share a minimal repo, or at least some basic info about your project? Although you hit the same problem, it might be due to a different reason.

Here you go: https://github.com/spiffytech/cypress-22071-repro

@jimfm
Copy link

jimfm commented Jun 3, 2022

Confirmed that removing the cypress/index.ts file resolved the issue for me.

@josh803316
Copy link
Author

@josh803316 I found I could just do rm cypress/index.js and your project works just fine. Can you give this a try? I think what's happening is, somehow, when we do import { defineConfig } from 'cypress', it ends up resolving the contents of cypress/index.js instead of the node_modules/cypress (!!!).

You actually said this here I'm sorry I missed it. Clearly require.resolve('cypress') should not be returning /Users/josh/git/core-web/cypress/index.ts - that's not where Cypress is installed.

What is this file supposed to be? Plugins go in cypress/plugins/index.js. There's no such functionality associated with cypress/index.js.

Either way, this also explains how you ran into defineConfig is not a function (here) - it was expecting that file to export a defineConfig, which is was not.

I think this should solve your problem?

@lmiller1990 Thanks, that fixed the issue for me! I still can't use import statements in the plugin file but not sure if I'm supposed to be able to or not. Thanks so much for your help! I'll close down the sample repo if you are ok with it.

@brianjenkins94
Copy link

brianjenkins94 commented Jun 3, 2022

#22096 also exhibits this error but isn't fixed by the rm cypress/index.js solution since that isn't a file that exists.

@cypress-bot cypress-bot bot added the stage: investigating Someone from Cypress is looking into this label Jun 3, 2022
EvAvKein added a commit to EvAvKein/Distillogue that referenced this issue Jun 4, 2022
turns out that the last commit upgrading to cy10 wasn't enough, there were file changes instructed by the launcher ...and also i'm now getting the bug at cypress-io/cypress#22071.
'thanks' to that bug i cant test if these files changes are sufficient, so once that bug is resolved i'll push the requisite commit as/if necessary
@lmiller1990
Copy link
Contributor

@josh803316 I found I could just do rm cypress/index.js and your project works just fine. Can you give this a try? I think what's happening is, somehow, when we do import { defineConfig } from 'cypress', it ends up resolving the contents of cypress/index.js instead of the node_modules/cypress (!!!).
You actually said this here I'm sorry I missed it. Clearly require.resolve('cypress') should not be returning /Users/josh/git/core-web/cypress/index.ts - that's not where Cypress is installed.
What is this file supposed to be? Plugins go in cypress/plugins/index.js. There's no such functionality associated with cypress/index.js.
Either way, this also explains how you ran into defineConfig is not a function (here) - it was expecting that file to export a defineConfig, which is was not.
I think this should solve your problem?

@lmiller1990 Thanks, that fixed the issue for me! I still can't use import statements in the plugin file but not sure if I'm supposed to be able to or not. Thanks so much for your help! I'll close down the sample repo if you are ok with it.

If your pluginsFile is index.js it will resolve using CommonJS (require). If you rename it to index.ts, it will then use TypeScript and ts-node, which understands ESM (import). So I'd just recommend that. Since your project is using TypeScript, it seems good to have everything using TypeScript (even your config!).

As an aside, now that cypress.config is a module, you might not need a separate file - you could just write all your code in cypress.config, or import functions. It should offer even more flexibility than plugins/index.js did.

@brianjenkins94 thanks for the detailed bug report in #22096. I'm going to close this issue since the original reporter's bug is solved, and continue the triage and resolution to your bug in the issue you reported.

@actionJacksonfv
Copy link

What is the fix for this?

@brianjenkins94
Copy link

Cypress 10.1.0+

@actionJacksonfv
Copy link

actionJacksonfv commented Jun 17, 2022

@brianjenkins94 (node:4976) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use node --trace-warnings ... to show where the warning was created)
(node:4976) ExperimentalWarning: The Node.js specifier resolution flag is experimental. It could change or be removed at any time.
node:internal/modules/cjs/loader:933
const err = new Error(message);
^

Error: Cannot find module 'typescript'
This is what I get when I upgrade to cypress 10.1.0 It says Module not found. I reinstalled typescript globally with npm i -g typescript The cypress app just continuously loads and never resolves
image

@lmiller1990
Copy link
Contributor

lmiller1990 commented Jun 23, 2022

Install typescript in your project, not globally. It's a dependency of your project, so you should install it there (and add it to your package.json). That is where ts-node is going to look for it.

Unrelated and somewhat embarrassingly there is an issue with windows + usernames containing a space, which is getting fixed right now: #22297. The reason I mention this is the screenshot above this post shows a username with a space, which might be problem (which is unrelated to the typescript problem discussed here - in general, if you are hitting missing module typescript, you need to make sure it's installed locally).

@maxime1992
Copy link

It was working fine last week for me and I got that error now...

Turns out that I forgot to run nvm use and for some reason I was on some old version of nodejs.

@actionJacksonfv
Copy link

Why is this closed? I'm still experiencing in 10.3.0 after a fresh installation of node and cypress.

@pjamessteven
Copy link

@actionJacksonfv I fixed this by deleting my existing cypress.config.ts, restarting cypress and letting it generate new config files.

@lmiller1990
Copy link
Contributor

Why is this closed? I'm still experiencing in 10.3.0 after a fresh installation of node and cypress.

Are you using a global TypeScript?

To answer your original question - it's closed since this issue was resolved, at least for some people (such as the original poster). It's possible the issue is still manifesting based on some other combination of dependencies, projects, etc. If you are still running into this, can you provide a reproduction or explain how I can reproduce it, so I can take a look? Thanks!

@mister-good-deal
Copy link

mister-good-deal commented Jul 11, 2022

Using

  • nodejs v16.15.1
  • yarn v3.2.1
  • cypress v10.3.0
  • vite v2.9.14
  • typescript v4.7.4

with PnP yarn config for package manager on a fresh VueJS 3 project I have the same error

yarn run test:e2e:ci

yarn run test:e2e:ci
1: starting server using command "npm run preview"
and when url "[ 'http://127.0.0.1:4173/' ]" is responding with HTTP status code 200
running tests using command "cypress run --e2e"


> [email protected] preview
> vite preview --port 4173

  > Local: http://localhost:4173/
  > Network: use `--host` to expose
Your configFile is invalid: /home/rom1/Projects/daia-ihm/cypress.config.ts

It threw an error when required, check the stack trace below:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /home/rom1/Projects/daia-ihm/cypress.config.ts
    at new NodeError (node:internal/errors:372:5)
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:76:11)
    at defaultGetFormat (node:internal/modules/esm/get_format:118:38)
    at defaultLoad (node:internal/modules/esm/load:21:20)
    at load$1 (file:///home/rom1/Projects/daia-ihm/.pnp.loader.mjs:179:12)
    at ESMLoader.load (node:internal/modules/esm/loader:407:26)
    at ESMLoader.moduleProvider (node:internal/modules/esm/loader:326:22)
    at new ModuleJob (node:internal/modules/esm/module_job:66:26)
    at ESMLoader.#createModuleJob (node:internal/modules/esm/loader:345:17)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:304:34)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
    at async importModuleDynamicallyWrapper (node:internal/vm/module:437:15)
    at async loadFile (/home/rom1/.cache/Cypress/10.3.0/Cypress/resources/app/node_modules/@packages/server/lib/plugins/child/run_require_async_child.js:106:14)
    at async EventEmitter.<anonymous> (/home/rom1/.cache/Cypress/10.3.0/Cypress/resources/app/node_modules/@packages/server/lib/plugins/child/run_require_async_child.js:116:32)
Error: Command failed with exit code 1: cypress run --e2e
    at makeError (/home/rom1/Projects/daia-ihm/.yarn/cache/execa-npm-5.1.1-191347acf5-fba9022c8c.zip/node_modules/execa/lib/error.js:60:11)
    at handlePromise (/home/rom1/Projects/daia-ihm/.yarn/cache/execa-npm-5.1.1-191347acf5-fba9022c8c.zip/node_modules/execa/index.js:118:26)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  shortMessage: 'Command failed with exit code 1: cypress run --e2e',
  command: 'cypress run --e2e',
  escapedCommand: '"cypress run --e2e"',
  exitCode: 1,
  signal: undefined,
  signalDescription: undefined,
  stdout: undefined,
  stderr: undefined,
  failed: true,
  timedOut: false,
  isCanceled: false,
  killed: false
}

@lmiller1990
Copy link
Contributor

lmiller1990 commented Jul 12, 2022

I recreated it, thanks @ZiperRom1. It is a different issue that manifests the same error. I reproduced it, created a minimal reproduction repo, and created a new issue to track this: #22747

@mellis481
Copy link

In case this can help anyone else, I was able to resolve the Unknown file extension ".ts" invalid config error, by making a change to my cypress/tsconfig.json file.

I changed this:

{
  "compilerOptions": {
    "baseUrl": "../node_modules",
  },
}

... to this:

{
  "compilerOptions": {
    "baseUrl": "..",
  },
}

@Eusebius1920
Copy link

Eusebius1920 commented Aug 3, 2022

In case this can help anyone else, I was able to resolve the Unknown file extension ".ts" invalid config error, by making a change to my cypress/tsconfig.json file.

I changed this:

{
  "compilerOptions": {
    "baseUrl": "../node_modules",
  },
}

... to this:

{
  "compilerOptions": {
    "baseUrl": "..",
  },
}

Seeing the very same issue. Changing baseUrl to one level less "solves" the problem...

@quincysoul
Copy link

This happened to me on NVM lts/gallium - no error on stable.

@akshayjai1
Copy link

https://stackoverflow.com/questions/73221655/unknown-file-extension-ts-cypress-config-ts-on-ci/73443680#73443680

@davidturissini
Copy link

davidturissini commented Aug 23, 2022

One more datapoint here:

I actually found this thread because I was experiencing the Unknown file extension ".ts" issue only in a docker container and only in CI (Github actions in this case). Everything was working fine on my local environment.

My issue actually had very little to do with Cypress and more to do with how ts-node works. In CI, I was running a fairly vanilla docker compose configuration that I assumed would be sufficient to run my typescript tests. It turns out, however, that the Cypress images do not have Typescript installed and it is up to the developer to expose typescript to the cypress container.

Once I realized that I was getting the Unknown file extension ".ts" because ts-node couldn't resolve typescript, the fix was fairly straight forward. In my case, I added an extra layer to the Cypress image that installed typescript. Another possible fix could be to run npm i and mounting that directory into Cypress.

I didn't run into this issue locally because I had all of my dependencies already installed when I mounted by directory.

@atarek12
Copy link
Contributor

I was facing the same issue and resolved it by removing the defineConfig function
I was upgrading from v9.6.1 to v10.6.0

@lmiller1990
Copy link
Contributor

🤔 You should be able to keep defineConfig, that's weird. If you can share a minimal reproduction, I can take a look.

@atarek12
Copy link
Contributor

While trying to create a reproduction repo, I found that this rule "baseUrl": "./node_modules" in the tsconfig.ts file was the cause of that error. By removing this, the project worked with the defineConfig function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stage: investigating Someone from Cypress is looking into this topic: typescript v10.0.2 🐛 Issue present since 10.0.2
Projects
None yet
Development

No branches or pull requests