create-react-app: Cannot compile TypeScript app created with CRA because of parsing errors

Describe the bug

create-react-app seems to have issues compiling valid TypeScript code.

Did you try recovering your dependencies?

Yes, in a number of ways. I cannot manage to fix this, despite spending hours on researching it.

I’ve tried:

  1. Googling (finding semi-similar issues reported, but no answers or solutions)
  2. Removing node_modules and doing npm install and npm ci
  3. Removing package-lock.json and npm install and npm ci
  4. Reconstructing the entire package.json file by doing npm install <package-name> for every single dependency.

Which terms did you search for in User Guide?

parsing error, unexpected token, syntax error, create-react-app, private access modifier, failed to compile, typescript syntax error and tons of permutations of these.

Environment

  • Windows 10 x64
  • node v12.19.0
  • npm 6.14.8

Steps to reproduce

  1. npx create-react-app my-app --typescript
  2. Edit App.tsx and add the following code under the import statements and above the function App() ... line:
class Foo {
  private bar: number;

  constructor() {
    this.bar = 1;
  }
}

Full content of App.tsx:

import React from 'react';
import logo from './logo.svg';
import './App.css';

class Foo {
  private bar: number;

  constructor() {
    this.bar = 1;
  }
}

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
  1. Run npm run build

NOTE: There are other syntaxes which do not work, such as readonly and more.

Expected behavior

The app is compiled successfully.

Actual behavior

λ npm run build

> my-app@0.1.0 build C:\Users\...\my-app
> react-scripts build

Creating an optimized production build...
Failed to compile.

C:/Users/.../my-app/src/App.tsx
  Line 6:11:  Parsing error: Unexpected token

  4 |
  5 | class Foo {
> 6 |   private bar: number;
    |           ^
  7 |
  8 |   constructor() {
  9 |     this.bar = 1;


npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! my-app@0.1.0 build: `react-scripts build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the my-app@0.1.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\...\npm-cache\_logs\2020-10-13T05_11_20_782Z-debug.log

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 32
  • Comments: 25

Commits related to this issue

Most upvoted comments

Okay, scratch that. After comparing the output of a fresh yarn create react-app with my existing package.json it seems that the file now contains the following section:

  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },

This was missing in the app I upgraded. Presumably this was added to the generator output at some point in the past but inferred if missing and that logic got canned at some point in the 4.0.0 pre-releases, breaking old apps that were missing this bit.

Adding this to my package.json fixed the problem, monorepo or not.

for me, react-scripts build was succeeding locally but failing in a docker container. The solution was to copy my .eslintrc.js into the container before doing the build.

My eslintrc does not use react-app or react-app/jest, so it does not seem to be those configs specifically that prevent this issue.

I do not have an eslintConfig section in my package.json.

Bizarre issue.

For anyone else landing here, and not thinking that linting has anything to do with the error you are having. I just found out that CRA always adds ESLint so it will run even if you remove all your ESLint config. And then it will crash because ESLint without config cannot handle TypeScript.

The fix is to add back:

  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  }

to your package.json

deleting the eslintrc file helped me

Not sure why yet, but the thing that has solved this problem for me was deleting an .eslintrc file I had in the root folder

To give an update on my comment yesterday, I was able to resolve my personal problem, which probably ended up unrelated to this topic after all.

My issue was that my project is split into different modules - “client”, “shared” and “server”, and I was including the “shared” module in my “client” without transpiling the TS first. (Via npm link or npm install ../local/path/to/the/module)

The baffling part is that I have been using the shared package for weeks without the error appearing, and then it suddenly popped up out of nowhere.

The correct solution is probably to just transpile the shared package before using it, but what I did instead was to install CRACO and change the CRA webpack config to add an additional rule:

npm install -D @craco/craco ts-loader

craco.config.js:

const path = require("path");

module.exports = {
  webpack: {
    configure: webpackConfig => {

      // ts-loader is required to reference external typescript projects/files (non-transpiled)
      webpackConfig.module.rules.push({
        test: /\.ts(x)?$/,
        loader: 'ts-loader',
        include: [
          path.resolve(__dirname, '../your/local/path'),
          path.resolve(__dirname, '/node_modules/your-local-package-name'),
        ],
        options: {
          transpileOnly: true,
          configFile: 'tsconfig.json',
        },
      })

      return webpackConfig;
    }
  }
};

and then replace react-scripts start calls in the package.json scripts segment with craco start (and same for build). That resolved my problem.

The problem also happened in WSL2, which tipped me off to the thought that it might not be Windows-related after all.

While my woes ended up not directly related, I hope that the context may provide some ideas for solving this particular case.

I did some digging and it seems like this was introduced by the changes to ESLint config handling in v4.0 (see https://github.com/facebook/create-react-app/pull/9587/files#diff-8e25c4f6f592c1fcfc38f0d43d62cbd68399f44f494c1b60f0cf9ccd7344d697L372 and then https://github.com/facebook/create-react-app/pull/9640/files#diff-8e25c4f6f592c1fcfc38f0d43d62cbd68399f44f494c1b60f0cf9ccd7344d697R366).

In particular, the default lint config is now using eslint-config-react-app/base instead of eslint-config-react-app/index: this matters because only the latter configures a TS-aware lint parser.

https://github.com/facebook/create-react-app/blob/d9eb05ff3c52238c59a97ffae940f35a22c8e891/packages/eslint-config-react-app/index.js#L33

Likely solution is to move TS-aware parser config to the base file?

Not sure why yet, but the thing that has solved this problem for me was deleting an .eslintrc file I had in the root folder

Thanks. Doesn’t work for me - I don’t even have that file.