facebook / create-react-app

Set up a modern web app by running one command.
https://create-react-app.dev
MIT License
102.71k stars 26.84k forks source link

Large number of inotify watches on yarn build with typescript in CI builds #10634

Open jkylling opened 3 years ago

jkylling commented 3 years ago

Describe the bug

The fork-ts-checker-webpack-plugin used by webpack in react-scripts spawns a lot of inotify watches on yarn build. This is similar to the issue described in https://github.com/facebook/create-react-app/issues/7612

This causes instabilities and crashes in our jenkins ci kubernetes cluster running with the jenkins kubernetes plugin. Multiple jenkins pipelines can be allocated concurrently on the same kuberentes node. The pipelines which are allocated together with a create-react-app build frequently fail with error messages like No space left on device, or User limit of inotify watches reached, since running out of inotify watches trigger ENOSPC.

Mitigating this by bumping the fs.inotify.max_user_watches in the host os is not an attractive option as it would require using a custom image or deploying a daemonset to set the limit. Increasing the limit might have unintended consequences as well, especially if too many builds using create-react-app run on the same node.

Disabling fork-ts-checker-webpack-plugin or useTypescriptIncrementalApi in the fork-ts-checker-webpack-plugin fixes the issue.

Did you try recovering your dependencies?

This is from a fresh npx create-react-app my-app --template typescript in a node:12 container.

Which terms did you search for in User Guide?

inotify watches, ci, incremental builds

Environment

Running in a node:12 container:

root@ec29fa0bba40:/my-app# npx create-react-app --info
npx: installed 67 in 3.957s

Environment Info:

  current version of create-react-app: 4.0.3
  running from /root/.npm/_npx/21966/lib/node_modules/create-react-app

  System:
    OS: Linux 4.9 Debian GNU/Linux 9 (stretch) 9 (stretch)
    CPU: (8) x64 Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz
  Binaries:
    Node: 12.21.0 - /usr/local/bin/node
    Yarn: 1.22.5 - /usr/local/bin/yarn
    npm: 6.14.11 - /usr/local/bin/npm
  Browsers:
    Chrome: Not Found
    Firefox: Not Found
  npmPackages:
    react: ^17.0.1 => 17.0.1 
    react-dom: ^17.0.1 => 17.0.1 
    react-scripts: 4.0.3 => 4.0.3 
  npmGlobalPackages:
    create-react-app: Not Found

Steps to reproduce

Assuming that you have docker installed the following commands reproduces the problem in a node:12 container. On a linux based os you can also reproduce the issue, by tracking the number of inotify watches using the script below. The commands sets up a clean npx create-react-app my-app --template typescript example app, and runs yarn build while tracking the number of inotify watches. If you then apply the patch to disable useTypescriptIncrementalApi the number of watches stays at zero on the next yarn build

# shell 1
docker run -e CI=true -it --rm --name=inotify-watches-demo --entrypoint=/bin/bash node:12
# shell 2
docker exec -it inotify-watches-demo bash -c "while true; do find /proc/*/fd -lname anon_inode:inotify    -printf '%hinfo/%f\n' 2>/dev/null |    xargs cat | grep -c '^inotify'; sleep 0.2; done"

# shell 1
npx create-react-app my-app --template typescript
cd my-app
yarn build
# watch the number of watches grow to 5497 in shell 2
# The number of watches grows to 5497 again if you re-run yarn build

## FIX ##
# shell 1
patch --forward node_modules/react-scripts/config/webpack.config.js   << EOF
@@ -725,6 +725,7 @@
       // TypeScript type checking
       useTypeScript &&
         new ForkTsCheckerWebpackPlugin({
+          useTypescriptIncrementalApi: false,
           typescript: resolve.sync('typescript', {
             basedir: paths.appNodeModules,
           }),
EOF
yarn build
# number of watchers stays at 0, and the build is faster

I have verified that all the watches belong to the node process running the fork-ts-checker-webpack-plugin.

Expected behavior

The number of inotify watches stays at 0 throughout the entire build.

Actual behavior

The number of inotify watches increases to 5497.

Reproducible demo

See steps to reproduce.

Possible solution

Add an option to turn off fork-ts-checker-webpack-plugin entirely , or disable useTypescriptIncrementalApi.

useTypescriptIncrementalApi: !process.env["CI"],

would suffice.

jw-miaem commented 3 years ago

I tried the above docker script with existing project that was breaking on Jenkins and watches grows to 12052. Can also confirm this goes to 0 with useTypescriptIncrementalApi: false

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 5 days if no further activity occurs.