cypress icon indicating copy to clipboard operation
cypress copied to clipboard

TypeScript 5 support for sourceMap option

Open elevatebart opened this issue 1 year ago • 29 comments

Current behavior

If I want to use TypeScript 5 and use sourceMap in my tsconfig.json, cypress errors with the following error.

Error: Webpack Compilation Error
/Users/bart/Dev/cypress-with-ts5/tsconfig.json
[tsl] ERROR
      TS5053: Option 'sourceMap' cannot be specified with option 'inlineSourceMap'.

Desired behavior

No response

Test code to reproduce

https://github.com/elevatebart/cypress-with-ts5/

Cypress Version

12.8.1

Node version

v18.7.0

Operating System

macOS 13.2.1

Debug Logs

No response

Other

No response

elevatebart avatar Mar 23 '23 20:03 elevatebart

I found this old issue that throws the same error. Maybe that helps https://github.com/cypress-io/cypress/issues/8477

elevatebart avatar Mar 23 '23 20:03 elevatebart

Hi, I encountered the same error with typescript@5, and "sourceMap": false, worked. However, cypress now reports the wrong line when a test error occurs.

koooge avatar Mar 25 '23 17:03 koooge

Related: https://github.com/cypress-io/cypress/issues/26148

Might be fixed in https://github.com/cypress-io/cypress/pull/26173

lmiller1990 avatar Mar 27 '23 03:03 lmiller1990

Encountering the same issue with Typescript 5.0.3 - solution was just to pin our cypress tests to 4.9.5 while aforementioned GH issues get resolved.

peniqliotuv avatar Apr 03 '23 15:04 peniqliotuv

Yep please give us a few, there are some TS 5 incompatibilities - some of them are upstream, in ts-node, eg #26148, leading to a PR in TS itself. We will get through these soon. Thanks!

lmiller1990 avatar Apr 03 '23 23:04 lmiller1990

The issue is we hard code inlineSourceMap: https://github.com/cypress-io/cypress/blob/4963893ac5738d8a0e447c0a624639a21ae7a072/npm/webpack-batteries-included-preprocessor/index.js#L41

One work around would be to provide your own preprocessor and webpack config that does not set this option, eg: https://github.com/elevatebart/cypress-with-ts5/compare/main...lmiller1990:cypress-with-ts5:example-fix?expand=1

Alternatively, you should be able to modify our defaults and remove the inlineSourceMap options, something like described here: https://github.com/cypress-io/cypress/tree/4963893ac5738d8a0e447c0a624639a21ae7a072/npm/webpack-preprocessor#modifying-default-options

I don’t know if we can just remove the inlineSourceMap option in our default preprocessor, that might be a breaking change. We could detect if they are using sourceMap and if they are, conditionally remove it. I'd say providing your own webpack-preprocessor with the defaults you'd like to use is probably a good work around for now - more control, and you can also use webpack 5 (default is 4).

lmiller1990 avatar Apr 20 '23 21:04 lmiller1990

Facing the same error

CheIIau avatar May 30 '23 21:05 CheIIau

Alternatively, you should be able to modify our defaults and remove the inlineSourceMap options, something like described here: https://github.com/cypress-io/cypress/tree/4963893ac5738d8a0e447c0a624639a21ae7a072/npm/webpack-preprocessor#modifying-default-options

@lmiller1990 in cypress.config.ts, I tried:

export default defineConfig({
...
  e2e: {
    setupNodeEvents(on) {
      const options = { ...webpackPreprocessor.defaultOptions };
      console.log(JSON.stringify(options));
    },
  },
})

However, the rule you mention does not appear in the result. options gives out:

{"webpackOptions":{"mode":"development","module":{"rules":[{"test":{},"exclude":[{}],"use":[{"loader":"babel-loader","options":{"presets":["@babel/preset-env"]}}]}]}},"watchOptions":{}}

Strangely, I can't find cypress/npm/webpack-batteries-included-preprocessor/index.js in my node_modules. Any idea why?

One work around would be to provide your own preprocessor and webpack config that does not set this option, eg: https://github.com/elevatebart/cypress-with-ts5/compare/main...lmiller1990:cypress-with-ts5:example-fix?expand=1

Sadly this fails for me too as I'm having trouble finding the right webpack.config to use and the cypress compilation returns an import error for my own module.

image

I've tried "sourceMap": false, which fixes the compilation issue, but we'll misreport the lines as a previous user said.

flavianh avatar May 31 '23 15:05 flavianh

My workaround for now is just to overwrite original sourceMap inside tsconfig.json in cypress folder:

image

vlad-ivanov-d avatar Jun 01 '23 11:06 vlad-ivanov-d

@flavianh does ^ work for you?

Re:

Strangely, I can't find cypress/npm/webpack-batteries-included-preprocessor/index.js in my node_modules. Any idea why?

Yeah - it's part of the actual Cypress app, which has it's own node_modules (that are not installed into your local project. The actual app and it's dependencies are located in different places depending on your OS, something like these directories.

When you tried making your own webpack config, you got an error - what is that? Maybe we can work through it.

lmiller1990 avatar Jun 05 '23 05:06 lmiller1990

have the same issue with [email protected], [email protected] and "sourceMap": true,, overwrite sourceMap in tsconfig.json in cypress folder does not work for me.

liuliu-dev avatar Jul 05 '23 17:07 liuliu-dev

I also have this problem

nitzcard avatar Jul 12 '23 07:07 nitzcard

Did either of you try https://github.com/cypress-io/cypress/issues/26203#issuecomment-1571861397? It seems to be the best work around for now.

lmiller1990 avatar Jul 12 '23 23:07 lmiller1990

Do note that Cypress also appears to be loading the wrong tsconfig.json file. Cypress's documentation states:

We recommend creating a tsconfig.json inside your cypress folder

But even though I have that file, Cypress still loads the tsconfig.json in the project root.

guilhermesimoes avatar Jul 24 '23 16:07 guilhermesimoes

I have successfully used the workaround above (for now - I remain hopeful that the workaround is only temporarily necessary).

I already had a cypress/tsconfig.json file in my project (in addition to my main tsconfig.json in the project root), so adding "sourceMap": false to the former (to override "sourceMap": true in the latter) was straightforward.

What I don't understand though is why this error only appears after upgrading to TypeScript 5.x?

I have always had "sourceMap": true in my main tsconfig.json; and as far as I can tell Cypress has always defaulted to "inlineSourceMap": true unless overridden by the sourceMap setting in a user-supplied tsconfig.json file.

So with TypeScript 4.x, this was fine:

/* tsconfig.json */
{
  "compilerOptions": {
    // ...
    "sourceMap": true,
    // ...
  }
}

/* cypress/tsconfig.json */
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    // Nothing here about source maps
  }
}

But with TypeScript 5.x we need this:

/* tsconfig.json */
{
  "compilerOptions": {
    // ...
    "sourceMap": true,   // same as always
    // ...
  }
}

/* cypress/tsconfig.json */
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    // ...
    "sourceMap": false   // <-- workaround
    // ...
  }
}

Not that it really matters, but I would be curious to know what actually changed with TypeScript 5.x that triggered the need for the workaround?

scottohara avatar Jul 25 '23 01:07 scottohara

@scottohara TypeScript 5.x did make changes related to tsconfig.json: https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/#supporting-multiple-configuration-files-in-extends

guilhermesimoes avatar Jul 25 '23 08:07 guilhermesimoes

Yeah, that was my first thought too, but that change seems to relate to extending from multiple configs.

I suppose it is possible that in making those changes they have somehow altered how certain config values in a single base tsconfig.json file (e.g. sourceMap) are resolved into the final config; but on the surface it doesn't sound like this should behave any differently to earlier TS versions when just extending from a single tsconfig.json file.

scottohara avatar Jul 25 '23 09:07 scottohara

face the same issue and would like to remove the workaround again

Mexx77 avatar Aug 03 '23 11:08 Mexx77

I've tried the workaround at https://github.com/cypress-io/cypress/issues/26203#issuecomment-1571861397 but my problem is that cypress/tsconfig.json is ignored.

If I set sourceMap to false in the tsconfig.json of the workspace, it works fine. The folder structure in this npm monorepo is as follows:

/packages/
   tsconfig/
      base.json        // <-- setting "sourceMap": false works in here
   project/
      cypress/
         tsconfig.json // <-- This file is never picked up as tsconfig for cypress
      tsconfig.json    // <-- extends from "/packages/tsconfig/base.json" – setting "sourceMap": false works here

attila avatar Sep 05 '23 21:09 attila

This feels painfully similar to https://github.com/cypress-io/cypress/issues/8477 🥲

IlCallo avatar Sep 13 '23 17:09 IlCallo

Any updates on this? for me "sourceMap": false works for some specs, but fails for others.

Sinled avatar Oct 06 '23 14:10 Sinled

The provided workaround won't work if you attempt to import files from outside the Cypress directory. Whether this is a good or bad idea is a separate discussion, but it can pose real issues for many projects. In such cases, the main tsconfig.json will be picked up.

Are there any plans to address this issue on the Cypress side?

pjanik avatar Jan 09 '24 12:01 pjanik

Having the same issue, setting "sourceMap: false" does not work as a workaround.

fbandrei avatar Jan 18 '24 11:01 fbandrei

Having the same issue, setting "sourceMap: false" does not work as a workaround.

NealArw avatar Mar 13 '24 07:03 NealArw

Encountering the same issue with Typescript 5.0.3 - solution was just to pin our cypress tests to 4.9.5 while aforementioned GH issues get resolved.

@peniqliotuv can you point me to any resources on how to run cypress with an older version of typescript?

asalgado87 avatar Apr 26 '24 16:04 asalgado87

Encountering the same issue with Typescript 5.0.3 - solution was just to pin our cypress tests to 4.9.5 while aforementioned GH issues get resolved.

@peniqliotuv can you point me to any resources on how to run cypress with an older version of typescript?

You can use the ' resolutions' field in the package file

peniqliotuv avatar Apr 26 '24 16:04 peniqliotuv

@peniqliotuv Can you be more specific? Sorry I'm relatively new to this kind of thing. Much appreciated

asalgado87 avatar Apr 26 '24 16:04 asalgado87

Permit me to ask a potentially silly question.

If I understand correctly, this issue arises when:

  • sourceMap: true (as specified by the user in cypress/tsconfig.json)

... conflicts with

  • inlineSourceMap: true (as specified by Cypress in the webpack preprocessor)

... as these two tsconfig options (sourceMap / inlineSourceMap) are mutually exclusive.

The workaround that many of us here have successfully used to avoid this error is to explicitly set sourceMap: false in the user-supplied cypress/tsconfig.json file (noting that there were some concerns mentioned above about whether it would be safe for Cypress to remove the inlineSourceMap: true setting).

Given the mutual exclusivity of these two config options and the fact that Cypress hardcodes the value of one of the options; shouldn't it also hardcode the value of the other?

That is, instead of asking every end-user that encounters this error to apply the same workaround, would it be possible for Cypress to force sourceMap: false at the same time as setting inlineSourceMap: true?

webpackOptions.module.rules.push({
    test: /\.tsx?$/,
    exclude: [/node_modules/],
    use: [
      {
        loader: require.resolve('ts-loader'),
        options: {
          compiler: options.typescript,
          compilerOptions: {
            inlineSourceMap: true,      // if this is true...
            inlineSources: true,
            downlevelIteration: true,
+           sourceMap: false,           // ...then this MUST be false
          },
          logLevel: 'error',
          silent: true,
          transpileOnly: true,
        },
      },
    ],
  })

Or would that not fix the issue because anything in the user-supplied cypress/tsconfig.json takes precedence over the defaults in the webpack processor? (so a user-supplied sourceMap: true would overwrite the Cypress supplied sourceMap: false?)

scottohara avatar May 03 '24 00:05 scottohara

Hi,

After upgrading Typescript to version 5.x we started to have the same issue. We've set sourceMap to false in the e2e/tsconfig.json as a workaround, but I appreciate a final solution in this case.

As @scottohara said, that shouldn't (in theory) be that complicated as we can evaluate both sourceMap and inlineSourceMap values before building the final config to be used.

Anyways, the workaround is applied and hopefully we can move forward until we have nailed-down solution.

WellingtonBraga avatar May 06 '24 13:05 WellingtonBraga

This is still broken for me with Cypress version 13.11.0. I have the sourceMap: false in cypress/tsconfig.json, but it looks like as others have said in this thread, this file is not being picked up.

My folder structure that leads to the Cypress tsconfig.json file is as follows: mygitrepo\src\front\cypress\tsconfig.json

My node_modules are located here: mygitrepo\src\front\node_modules

So it looks like it should be the correct location to me..

CedricHg avatar Jun 06 '24 13:06 CedricHg