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

4.0.0 breaks with typescript (all versions) #9868

Closed
benneq opened this issue Oct 23, 2020 · 117 comments
Closed

4.0.0 breaks with typescript (all versions) #9868

benneq opened this issue Oct 23, 2020 · 117 comments
Milestone

Comments

@benneq
Copy link
Contributor

benneq commented Oct 23, 2020

Describe the bug

I made a clean install of cra@next with typescript and then upgraded typescript to 4.1.0-beta ( also tested 4.1.0-dev.20201023 )

npx create-react-app@next --scripts-version=@next --template=typescript@next my-ts-app

$$$ then replaced typescript 4.0.3 with 4.1.0-beta ( or ^4.1.0-beta ) in package.json

rm -rf node_modules package-lock.json && npm i

npm start

Error message:

node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js:239
      appTsConfig.compilerOptions[option] = value;
                                          ^

TypeError: Cannot assign to read only property 'jsx' of object '#<Object>'

( EDIT: This doesn't happen with cra 4.0.0-next.98 )

Did you try recovering your dependencies?

Yes

Which terms did you search for in User Guide?

I just looked for typescript bugs reported and closed in the last few days

Environment

System:
OS: macOS 10.15.7
CPU: (8) x64 Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz
Binaries:
Node: 14.14.0 - /usr/local/bin/node
Yarn: Not Found
npm: 6.14.8 - /usr/local/bin/npm
Browsers:
Chrome: 86.0.4240.111
Firefox: Not Found
Safari: 14.0
npmPackages:
react: ^17.0.1 => 17.0.1
react-dom: ^17.0.1 => 17.0.1
react-scripts: 4.0.0-next.117 => 4.0.0-next.117
npmGlobalPackages:
create-react-app: Not Found

Steps to reproduce

  1. npx create-react-app@next --scripts-version=@next --template=typescript@next my-ts-app

  2. replace typescript 4.0.3 with 4.1.0-beta ( or ^4.1.0-beta ) in package.json

  3. rm -rf node_modules package-lock.json && npm i

  4. npm start

Expected behavior

Should work out of the box

Actual behavior

node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js:239
      appTsConfig.compilerOptions[option] = value;
                                          ^

TypeError: Cannot assign to read only property 'jsx' of object '#<Object>'

Reproducible demo

Steps are simple enough to build your own demo

@iansu
Copy link
Contributor

iansu commented Oct 23, 2020

There is another similar issue with updating the TypeScript config file. We're still trying to determine the root cause. In this particular case you can work around it by manually setting jsx: react-jsx in tsconfig.json.

@benneq
Copy link
Contributor Author

benneq commented Oct 23, 2020

@iansu That doesn't work.

I did the same steps as above, and put "jsx": "react-jsx" in tsconfig.json.

I get the same error when running npm start

@iansu
Copy link
Contributor

iansu commented Oct 23, 2020

That was working for me. You can also try deleting your tsconfig.json and it should automatically get recreated with the new settings.

@benneq
Copy link
Contributor Author

benneq commented Oct 23, 2020

First attempt:

  1. npx create-react-app@next --scripts-version=@next --template=typescript@next my-ts-app
  2. edit package.json: set "typescript" version to ^4.1.0-beta
  3. edit tsconfig.json: set "jsx" to "react-jsx"
  4. rm -rf node_modules package-lock.json && npm i
  5. npm start

Error:

node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js:239
      appTsConfig.compilerOptions[option] = value;
                                          ^

TypeError: Cannot assign to read only property 'jsx' of object '#<Object>'

Second try: deleting tsconfig.json before running npm start. Works! But why?

Here's the recreated tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

That looks exactly the same as the file I had before 😕

@iansu
Copy link
Contributor

iansu commented Oct 23, 2020

I don't know why just changing that value wasn't working for you. This is an annoying bug that we're hoping to have fixed soon.

@benneq
Copy link
Contributor Author

benneq commented Oct 23, 2020

@iansu I found it!!

I started debugging verifyTypSscriptSetup.js

First issue I found: (line 151)

    jsx: {
      parsedValue:
        hasJsxRuntime && semver.gte(ts.version, '4.1.0-beta')
          ? ts.JsxEmit.ReactJsx
          : ts.JsxEmit.React,

It must be ts.JsxEmit.ReactJSX (capital letters) instead of ts.JsxEmit.ReactJsx.

Perfect example why people use TypeScript instead of plain old JS. 😏

@iansu
Copy link
Contributor

iansu commented Oct 23, 2020

You're right about the capitalization but I don't know if that's the root issue. For example, if you change moduleResolution to classic you'll get the same error and that definitely used to work.

@iansu iansu added this to the 4.0.1 milestone Oct 23, 2020
@iansu
Copy link
Contributor

iansu commented Oct 23, 2020

If you'd like to submit a PR to fix that casing issue that would be appreciated.

@benneq
Copy link
Contributor Author

benneq commented Oct 23, 2020

Already done: #9869

@benneq
Copy link
Contributor Author

benneq commented Oct 23, 2020

For example, if you change moduleResolution to classic you'll get the same error and that definitely used to work.

True. But at least I can now restart my app without always deleting tsconfig.json

Btw: I doesn't matter what you change. You don't have to change anything at all. Just save the file as is, and you'll get the error.

@benneq
Copy link
Contributor Author

benneq commented Oct 23, 2020

More Information:

Object.isFrozen(appTsConfig) // false
Object.isFrozen(appTsConfig.compilerOptions) // true
Object.isFrozen(appTsConfig.compilerOptions[option]) // true

That would explain why the property isn't writable.

How about a simple workaround that creates a new object instead of modifying the parsed data?

@benneq
Copy link
Contributor Author

benneq commented Oct 23, 2020

I think I got it! (lines 173 to 194)

    const { config: readTsConfig, error } = ts.readConfigFile(
      paths.appTsConfig,
      ts.sys.readFile
    );

    console.log(Object.isFrozen(readTsConfig.compilerOptions)); // false

    appTsConfig = readTsConfig;

    parsedTsConfig = immer(readTsConfig, config => {
      result = ts.parseJsonConfigFileContent(
        config,
        ts.sys,
        path.dirname(paths.appTsConfig)
      );
    });

    console.log(Object.isFrozen(readTsConfig.compilerOptions)); // true

Guess who's bad...

Again: Wouldn't have happened with TypeScript code 😼

Immer automatically freezes any state trees that are modified using produce.

source: https://immerjs.github.io/immer/docs/freezing

I guess the author of these lines knows why he used immer and how to fix this 😄 Commit: 315ff4b#diff-2f231dbdc363c929e899c94ae0d999f9886fdc6e33fb88d498a6b101a4bf9f68

@ianschmitz Your help would be appreciated

@jamesmfriedman
Copy link
Contributor

I have come across the same issue, I triaged it the exact same way all the way down to immer.

I think the easiest solution here is to just not use immer... It's creating an immutable data structure, but then following code attempts to mutate it 🤷‍♂️.

@jamesmfriedman
Copy link
Contributor

This resolves the issue, although removes the reason to use immer... Plop this at the top of the file.

const setAutoFreeze = require('react-dev-utils/immer').setAutoFreeze;
setAutoFreeze(false);

@benneq
Copy link
Contributor Author

benneq commented Oct 23, 2020

But maybe this causes other issues. I guess there's reason why @ianschmitz introduced immer there.

@jamesmfriedman
Copy link
Contributor

jamesmfriedman commented Oct 23, 2020

@benneq just to be clear, you might want to update the title of this issue, I have verified:

  • This breaks with ANY version of TS
  • This happens anytime one of your local config params doesn't exactly match what create-react-app spits out by default.
  • Simple repro, just set "paths" to anything, and watch it fail.
  • Another repro, as you have stated, try setting "jsx": to "react-jsx"

I think this is a critical bug for anyone trying to migrate over.

@benneq benneq changed the title 4.0.0-next.117 breaks with typescript 4.1.0 beta 4.0.0 breaks with typescript (all versions) Oct 23, 2020
@NearHuscarl
Copy link

See my answer here for a temporary fix. Also kinda related to #9429.

@PupoSDC
Copy link

PupoSDC commented Oct 24, 2020

@NearHuscarl Unfortunately this temporary fix only works if at the end of the day you are using the default TS config in your project. Our project brakes because we use baseUrl: "./src", and we can't hotfix it... :(

@DenysVuika
Copy link

having the same problem, with TS 4.1.0-beta, yarn build works fine, but yarn start gives me

node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js:239
      appTsConfig.compilerOptions[option] = value;
                                          ^

TypeError: Cannot assign to read only property 'jsx' of object '#<Object>'

@marceloclp
Copy link

For anyone looking for a more reliable work around for the time being, that doesn't consist on deleting the tsconfig file or manually changing the content of the faulty file every time dependencies are updated, here is what I did:

  1. Run yarn add line-replace --dev
  2. Create a js file with the code below somewhere on your root folder.
  3. Update your start script in package.json to node path/to/file && react-scripts start
const rplce = require('line-replace')
const path = require('path')

const filePath = path.join(
    __dirname,
    '../node_modules/react-scripts/scripts/utils',
    'verifyTypeScriptSetup.js',
)

rplce({
    file: filePath,
    line: 238,
    text: "    } else if (parsedCompilerOptions[option] !== valueToCheck && option !== 'jsx') {",
    callback: ({ file, error }) => {
        if (error) return console.error(error)
        console.log(`Replaced ${file} successfuly!`)
    }
})

So your script should look something like this:

{
  "start": "node fix-cra.js && react-scripts start"
}

siren added a commit to City-of-Helsinki/tilavarauspalvelu-ui that referenced this issue Nov 25, 2020
wijloc added a commit to wijloc/github-explorer that referenced this issue Nov 25, 2020
Message Error: Cannot use JSX unless '--jsx' flag is provided

Issue: facebook/create-react-app#9868
@DangoPlus
Copy link

Since, I don't like to use beta versions, I used the following settings:
Use an older typescript version (here typescript 4.0.5) with react-scripts 4.0.0, which fit together nicely.
package.json

"react-scripts": "4.0.0",
"typescript": "4.0.5",

Now, you have to adjust tsconfig.json, because "jsx": "react-jsx" is not available in this typescript version. If you don't adjust tsconfig you will run into the following error:
error TS6046: Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'.
Use "jsx": "react" instead.
If you'd like to use beta or dev versions, you could simply use a new typescript dev version:

"react-scripts": "4.0.0",
"typescript": "4.2.0-dev.20201121",

This worked perfectly for me. Hopefully this gets patched sometime soon, I'm not using it for anything particularly important but I know many people do use it for pretty important stuff.

This solution is work for me too.
In my case, I use cra 4.0.1 and craco with typescript, when I run yarn start or yarn build, the tsconfig.json file will changed by verifyTypeScriptSetup.js(in react-scripts, line153-line157).
jsx: { parsedValue: hasJsxRuntime && semver.gte(ts.version, '4.1.0-beta') ? ts.JsxEmit.ReactJSX : ts.JsxEmit.React, value: hasJsxRuntime && semver.gte(ts.version, '4.1.0-beta') ? 'react-jsx' : 'react', reason: 'to support the new JSX transform in React 17', },
The "jsx": "react" will be change to "jsx": "react-jsx" Automatically.
when I change the typescript version to "typescript": "4.0.5", the tsconfig.json file doesn't change anymore.

@cas8180
Copy link

cas8180 commented Nov 26, 2020

Fix for me was to adjust the TS version within VS code.
image

@fjplaurr
Copy link

Since, I don't like to use beta versions, I used the following settings:
Use an older typescript version (here typescript 4.0.5) with react-scripts 4.0.0, which fit together nicely.
package.json

"react-scripts": "4.0.0",
"typescript": "4.0.5",

Now, you have to adjust tsconfig.json, because "jsx": "react-jsx" is not available in this typescript version. If you don't adjust tsconfig you will run into the following error:
error TS6046: Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'.
Use "jsx": "react" instead.
If you'd like to use beta or dev versions, you could simply use a new typescript dev version:

"react-scripts": "4.0.0",
"typescript": "4.2.0-dev.20201121",

This worked perfectly for me. Hopefully this gets patched sometime soon, I'm not using it for anything particularly important but I know many people do use it for pretty important stuff.

Tried this configuration in container running node:12.20.0-alpine3.10 and works!

@fishenal
Copy link

fishenal commented Dec 3, 2020

maybe the package.json should be ^4.0.0 instead of 4.0.0

@hongguang-alt
Copy link

you can delete tsconfig.json , npm run start . The project will create new tsconfig.json file .

@Lukortech
Copy link

you can delete tsconfig.json , npm run start . The project will create new tsconfig.json file .

This doesn't change anything as the new tsconfig created by react-scripts is doomed, too. I'd say it's a blocker for any newcommer to the CRA and react developement in general.

rayyildiz added a commit to rayyildiz/capture-tweet that referenced this issue Dec 7, 2020
@0x0000F1
Copy link

0x0000F1 commented Dec 8, 2020

you can delete tsconfig.json , npm run start . The project will create new tsconfig.json file .

This doesn't change anything as the new tsconfig created by react-scripts is doomed, too. I'd say it's a blocker for any newcommer to the CRA and react developement in general.

update to react-scripts 4.0.1 they fixed it, and it works now as far as I know

hwookim added a commit to hwookim/react-todolist that referenced this issue Jan 7, 2021
 - tsconfig 최초 생성 시에만 스크립트가 작동하는 문제
 - facebook/create-react-app#9868
@thiago-anjos
Copy link

It works for:

package.json

"react-scripts": "4.0.0",
"typescript": "4.0.3",

tsconfig.json

"jsx": "react",

works for me too

@pierremouchan
Copy link

Still does not work with react-scripts 4.0.1 and typescript 4.1.3

@xorb
Copy link

xorb commented Jan 24, 2021

For some reason it does work with yarn.

rm -r node_modules
yarn install

@pierremouchan
Copy link

Okay, the issue was caused by nvm (Node version manager), i had to uninstall nvm and reinstall node through brew.
Now it's working fine !

@HashemKhalifa
Copy link

Okay, the issue was caused by nvm (Node version manager), i had to uninstall nvm and reinstall node through brew.
Now it's working fine !

that sounds a solution, will give it a try!

@mumairofficial
Copy link

Yes this issue is fixed I am using "react-scripts": "^4.0.1" and "typescript": "^4.1.3" which are latest today.

In some cases you may want to remove the node_modules directory and clean install.

@ghost
Copy link

ghost commented Feb 6, 2021

Using VS code, I had to uninstall an extension named typescript god. Closed and reopened VS code. Works fine now. Using "typescript": "^4.1.3" with "react-scripts": "4.0.2"

@clemente-xyz
Copy link

Still does not work with react-scripts 4.0.2 and typescript 4.1.4. Any updates?

@Townsheriff
Copy link

It works for:

package.json

"react-scripts": "4.0.0",
"typescript": "4.0.3",

tsconfig.json

"jsx": "react",

I'm still gettgin this jsx issue with react-scripts=4.0.3 and typescript=4.2.3. For now I'm good with downgrading typescript.

@joaoromeira
Copy link

I solve this error updating react-scripts to 4.0.3

yarn upgrade react-scripts@4.0.3

@serchserch
Copy link

serchserch commented Jul 31, 2021

It still does not work with react-scripts 4.0.3 and typescript 4.2.4.

UPDATE
Try to use

TSC_COMPILE_ON_ERROR=true npm start

rayyildiz added a commit to rayyildiz/capture-tweet that referenced this issue Jul 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests