Migrate React-Scripts v2.x to v3.0.0


On April 22, 2019, Facebook react-scripts v3.0.0 was released. In this article I’ll try to describe a process of migration in general, with some issues and solutions to them, I’ve experienced while doing this migration.
On April 22, 2019, Facebook react-scripts v3.0.0 was released. In this article I’ll try to describe a process of migration in general, with some issues and solutions to them, I’ve experienced while doing react-scripts migration.
Most notable features of this release are:
- React Hooks are now fully supported
- TypeScript linting now integrated into ESLint
- Absolute imports using jsconfig.json or tsconfig.json
- Also, bug which made react-scripts test --coverage impossible to run in watch mode, is now fixed
Update react-scripts
To make update the react-scripts latest version, according to release notes, you should run the following command inside your project’s directory terminal:

or

Note: during an update, you may see that react-scripts package depends on a different version of some of your dependencies (ex. eslint , or any other dependency). In that case, you can remove explicitly provided dependencies it clashes with from your package.json file (all except typescript) and then — re-run installation command above. In case of a typescript, you’ll need to type and save its version inside package.json. This way, step-by-step you’ll trust react-scripts to install and maintain dependencies it relies on (and will clean your package.json file as a slight bonus).
Migrate rules from TSLint to ESLint
Next big thing might be moving all of your Typescript linting rules from tslint.json into .eslintrc :
- if you’re starting from a scratch, create an empty .eslintrc file in the root of your project’s directory and add the following basic configuration there:

- if you already have an existing .eslintrc config, make sure it already extends "react-app" . It is being made to properly show you all of react-script bundled rules during manual linting or inside of your code editor of choice (in my case that’s VSCode).
- now copy-paste all of your tslint rules from tslint.json -> "rules" section into .eslintrc -> "rules" section.
- the next step will be running eslint with command below and checking for possible rules syntax errors:

Note: errors will relate to true or false set for rules, which expect 0, 1, 2 or "off", "warn", "error" as a value correspondingly.
- If you have multiple tslint configs for linting code on different stages (ex. separate dev and separate pre-commit configs), don’t forget doing the same operation for them, but naming files accordingly.
Note: as an alternative, you can skip everything related to rules copy-pasting above and just re-write your rules from scratch using http://ESlint.org/docs/rules documentation and then continue from the next step.
- fix your npm scripts inside package.json to use eslint instead of tslint .
Note: if needed, you can specify needed config for each separate npm script with --config flag (ex. eslint --config .eslintrc --fix \”src/**/*.{ts,tsx,js}\”).
- now lint your files and fix all possible errors
- remove all tslint related files and configs from package.json and re-run your npm install or yarn to clean node_modules folder from stale dependencies.
Absolute imports
Now, react-scripts supports absolute imports based on jsconfig.json / tsconfig.json baseUrl setting. To configure it, create or update your jsconfig.json or tsconfig.json with following lines:

Note: currently the only supported options for baseUrl are node_modules which are set by default, and src .
Starting from this point, you can import your components specifying the relative path to your src folder, instead of writing a long chain of our beloved ../../../ :

A small note on Jest tests file naming
If your tests file names don’t have a .spec or .test suffix, and for instance are called simply as test.tsx (like it was in my case) — they won’t be discovered by a react-scripts test runner. As a result, you’ll need to rename them not to be called as test.tsx but to include this suffix in their name (ex. Button.test.tsx).
Another note on react-scripts test
If in your development process you relied on the react-scripts test --coverage running only once (ex. — CI run, or some pre-commit hook), it’s now running in watch mode by default. So to fix that, you’ll need to add --watchAll=false flag, to make sure it will not run in a watch mode.
Good luck!