facebook / create-react-app

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

`yarn tsc && react-scripts build` v3 takes 1 hour to complete #7003

Open jewseppi opened 5 years ago

jewseppi commented 5 years ago

Is this a bug report?

Yes, The production build of a TypeScript project requires almost an hour to complete.

I have tried many different version combinations all with the same result; either my system crashes or I get a very slow build process.

yarn start takes about 5 min and my production build takes almost 1 hour; it's quite consistent.

Currently on the following versions. "@types/styled-components": "4.1.10", "react-scripts": "3.0.0", "typescript": "3.3.4000",

Did you try recovering your dependencies?

I have deleted these files numerous times and tried a few of the typescript-dev versions as well as the styled-component types.

I am using Yarn Version 1.15.2

Which terms did you search for in User Guide?

script react-scripts tsc build slow typescript cra creating optimized production build takes an hour

Environment

Issues are consistent in both environments.

  1. Windows 16GB RAM, WSL (Ubuntu Install)
  2. IBM Cloud Docker Instance

npx: installed 91 in 18.872s

Environment Info:

System: OS: Linux 4.4 Ubuntu 18.04.1 LTS (Bionic Beaver) CPU: (4) x64 Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz Binaries: Node: 11.11.0 - ~/.nvm/versions/node/v11.11.0/bin/node Yarn: 1.15.2 - /usr/bin/yarn npm: 6.7.0 - ~/.nvm/versions/node/v11.11.0/bin/npm Browsers: Chrome: Not Found Firefox: Not Found npmPackages: react: Not Found react-dom: Not Found react-scripts: Not Found npmGlobalPackages: create-react-app: Not Found

Steps to Reproduce

This is a very large project with hundreds of components.

"start": react-scripts start", (5-6 min)
"build": "tsc && react-scripts build" (~53min),

I upgraded my existing installation to the newest version of React which supports Hooks and integrated TypeScript which caused the development server to slow down on first launch; with the console displaying the following.

Files successfully emitted, waiting for typecheck results...

When I commit and merge the code, a deployment build is spun up in a Docker instance which takes almost an hour to complete.

Expected Behavior

I would expect the production build to take no more than 10 min. The development server should also launch a bit quicker.

deftomat commented 5 years ago

How long it took without TS? Both start and build?

How long it took to finish just tsc ?

deftomat commented 5 years ago

We had a similar issue as we are using custom create-react-app fork with enabled tslint. Looks like project grows to the size, where fork-ts-checker-webpack-plugin slows down really badly. We solve it by disabling tslint but you are using the default create-react-app which is not using tslint.

Maybe @johnnyreilly could help us with this as message "Files successfully emitted, waiting for typecheck results..." means that create-react-app is waiting for result from fork-ts-checker-webpack-plugin.

For your information, we are currently not listening to fork-ts-checker-service-out-of-memory event but as you mentioned that build actually finished, then I think it is not an issue.

johnnyreilly commented 5 years ago

I'd be interested to know how tsc alone performs and whether this is related to the regression in performance with TS 3.4. The ticket mentioned 3.3 so perhaps not.

I've never encountered a build that performs that badly before. I'm also curious that this script is first running tsc and then running react-scripts: "build": "tsc && react-scripts build"

Can't guarantee I'll be able to help more than this but these are my quick observations

rajzik commented 5 years ago

I have same issue. Local build took about 1 minute avg. this was after node reinstallation (removed all cache and node js files). But on docker it took 1000 second to build production package. It doesn't matter if CI is present or not. I have tried multiple docker/node versions always the same result. Also I have tried to change versions of typescript and styled components with no effect or very small effect on build time.

johnnyreilly commented 5 years ago

Random thought: are you building in the root of your docker container? I've an idea that's problematic for reasons that escape me. Something was reported in ts-loader (I don't think it was ts-loader specific). Read details here: https://github.com/TypeStrong/ts-loader/issues/758#issuecomment-379733292

rajzik commented 5 years ago

Random thought: are you building in the root of your docker container? I've an idea that's problematic for reasons that escape me. Something was reported in ts-loader (I don't think it was ts-loader specific). Read details here: TypeStrong/ts-loader#758 (comment)

Nope, working in subdirectory. Using this dockerfile.

FROM node:11.9.0-stretch
FROM cypress/browsers:chrome67

RUN mkdir /var/build-folder
RUN npm install -g serve yarn

WORKDIR /var/build-folder/

COPY . .

RUN yarn

RUN yarn build

ENTRYPOINT ["/bin/sh", "-c", "./test.sh"]
jewseppi commented 5 years ago

running tsc doesn't seem to cause an issue (completes in ~ 1min) I combined it with the build command hoping to see an improvement.

I also tried with typescript 3.4.1 and 3.4.5 all with the same issue.

I found some posts suggesting I eject and use Fork TS Checker Webpack plugin, but I would much rather be stuck with hour long deployments than an ejected CRA.

ianschmitz commented 5 years ago

We already use fork-ts-checker-webpack-plugin in this project. It internally uses the TypeScript compiler to do the type checking.

rajzik commented 5 years ago

It looks like when there is lazy loading and circular dependency it will take a long time in production mode on docker/node. I think this is another issue that I have. EDIT: On local machine it runs around 1 minute I have tried it on mac, PC, linux(ubuntu). But when running in docker container, time is always ~16 minutes average (1000s).

jewseppi commented 5 years ago

I've resolved the issue however its hard to pinpoint the exact cause; seems there were multiple side effects happening.

"@date-io/core": "^1.2.0",
"@date-io/date-fns": "^1.3.5",
"@material-ui/core": "^1.5.1",
"@material-ui/icons": "^2.0.3",
"date-fns": "^2.0.0-alpha.27",
"material-ui": "^0.20.2",
"material-ui-pickers": "1.0.0-rc.14",
"styled-components": "^4.2.0",
"typescript": "3.5.0-dev.20190512",

material-ui/material-ui-pickers is deprecated for @material-ui & @material-ui/pickers however there seems to be a conflict with @material-ui/core and style themes don't render properly when using withStyles(); unfortunately I'm stuck with a project that heavily uses these HOC's.

I also added a condition to the tsconfig.json to exclude all .js & .jsx files in my project which could have been part of the reason build times were taking an hour.

{ "compilerOptions": { "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, "strict": true, "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "noImplicitAny": true, "noEmit": true, "jsx": "preserve" }, "include": ["src"], "exclude": ["src/*/.js", "src/*/.jsx"] }

There is still the issue of my CPU ( i7 ) running at 100%, node consumes all available resources; when I close apps node increases it's consumption.

There is clearly a leak and I'm wondering if it's package related or a hardware failure.

My cloud deployments are down to 3min now :)

jewseppi commented 5 years ago

Finally resolved the CPU issue but now seems to have slowed down the typechecking, getting the message "Files successfully emitted, waiting for typecheck results..." in my terminal.

Docker build times are back up to ~50min

@types/styled-components is a conflicting package (newer versions break the docker build) date-fns has a format issue, using moment to get around this.

"dependencies": { "@date-io/core": "^1.2.0", "@date-io/date-fns": "^1.3.5", "date-fns": "^2.0.0-alpha.27", "material-ui": "^0.20.2", "material-ui-pickers": "1.0.0-rc.14", "moment": "^2.24.0", "styled-components": "^4.2.0", "typescript": "3.3.4000", }, "devDependencies": { "@types/node": "^12.0.2", "@types/styled-components": "4.0.3", },

johnnyreilly commented 5 years ago

Re: styled components it sounds like TypeScript 3.5 will improve the situation: https://devblogs.microsoft.com/typescript/announcing-typescript-3-5-rc/

jewseppi commented 5 years ago

thanks @johnnyreilly I just installed 3.5-rc and it resolved the build times and the typechecking.

I am still getting 100% CPU usage when connected to AC (HP Elite Book i7)

johnnyreilly commented 5 years ago

Glad things are improving! I wonder if this issue might help you with the CPU usage problem: https://github.com/microsoft/TypeScript/issues/31048

See also: https://github.com/facebook/create-react-app/issues/6792#issuecomment-485149432

InvictusMB commented 5 years ago

I ran into a similar issue on Windows when migrating from CRA 2.1.3 to 3.x. Although for me it was the opposite: yarn start took 10 - 20 minutes instead. I narrowed down the root cause to 2.1.7 -> 2.1.8 change and specifically this pr #6406 TS version I used was 3.3.1 in all setups.

With every top level import like import * as MUI from '@material-ui/core' or even import {Button} from '@material-ui/core' the build time increased non linearly. Adding a single @material-ui/icons import to the mix increased the build time 2x more.

This does not happen if I disable async mode for fork-ts-checker-webpack-plugin. Tested on both CRA 2.1.8 and 3.x versions. This is the config line I flipped to false: https://github.com/facebook/create-react-app/blob/bdaccf7161af1d78a867d7798759be296ad1b4c5/packages/react-scripts/config/webpack.config.js#L637

I can confirm that setting TSC_WATCHFILE=UseFsEventsWithFallbackDynamicPolling or TSC_WATCHFILE=UseFsEvents mitigates the issue. Still, it is not obvious to me why it manifests itself only in async mode in the first place.

Ravnurin commented 5 years ago

@InvictusMB thanks to your post, I was able to come up with a combined solution that appears to have massively improved my start up times (typically took 1-2 minutes, now it's ~15 seconds) as well as my continuous build speeds (used to be 3-5 seconds, now 2).

After reading your post and how Material UI's official site recommend path imports in development environments, I switched all my named imports to path imports and it seems to have done the trick!

import { Grid } from '@material-ui/core';  // before

import Grid from '@material-ui/core/Grid'; // after

However, before switching them all out I realised this would quickly become cumbersome, considering I will have to do anywhere between 3-8 MUI path imports in each of my React component. So instead, I created an index file at src/material/index to contain path imports of all the MUI components I use in my project, and then just do named imports from that index file. 😃

E.g.

// index.ts

// Components
export { default as Grid } from '@material-ui/core/Grid';
export { default as Button } from '@material-ui/core/Button';
export { default as FormControl } from '@material-ui/core/FormControl';
export { default as InputLabel } from '@material-ui/core/InputLabel';
...etc.

// Styles
export { default as createStyles } from '@material-ui/core/styles/createStyles';
export { default as makeStyles } from '@material-ui/core/styles/makeStyles';

// Icons
export { default as CalendarIcon } from '@material-ui/icons/CalendarTodayOutlined';
export { default as MenuIcon } from '@material-ui/icons/Menu';
export { default as LockOutlinedIcon } from '@material-ui/icons/LockOutlined';
InvictusMB commented 5 years ago

@Ravnurin, you are welcome. For my purposes and similar reasons I've hacked together a few Babel macros to do this job for me: https://www.npmjs.com/package/@ram-stack/material-ui.macro https://www.npmjs.com/package/@ram-stack/material-ui-icons.macro

I prefer namespace imports over named imports mainly because further down in the code I want to distinguish where a particular component is coming from without scrolling up and parsing 20+ imports over and over again.

Having MUI.Button and Recharts.BarChart helps a lot with that and prevents unnecessary context switching. I know no other way to quickly tell if the component is a MUI component, our internal library component, project specific component etc.

And I'm not going to give that up to compiler deficiencies.

deftomat commented 5 years ago

@Ravnurin Did you consider to report this "import workaround" as a bug to TypeScript team?

I know that imports could have a side effects and changing the imports could theoretically affect the code in certain cases (which almost everyone consider as unwanted and unexpected behaviour), but it is probably not an issue for static type check. So, maybe they can help us with this 😉

InvictusMB commented 5 years ago

@deftomat It is not yet clear (at least to me) if this is caused by TS itself or by fork-ts-checker-webpack-plugin implementation. I've dumped my observations in this thread.

jamesg1 commented 5 years ago

With Babel 7 out suppporting Typescript would there be a push to move from tsc to that? I'm facing large build times on docker and a little locally. Whats the best way to overrride thefork-ts-checker-webpack-plugin? I thought CRA supports tree shaking so import { Grid } from '@material-ui/core'; would be fine?

deftomat commented 5 years ago

@jamesg1 CRA is already using the Babel 7 to transpile TypeScript into JavaScript. However, as Babel is just a transpiler, CRA is using fork-ts-checker to run type-checks.

So, Babel is something like tsc --transpileOnly (not a valid command) and fork-ts-checker is like tsc --noEmit.

CRA is using both to "simulate" the tsc.

jamesg1 commented 5 years ago

Cheers for the info, the reason i ask is I'm trying to make docker builds faster for an app I'm working on which is CRA v3 with typescript. I'm wondering if its due to the material imports above which is extending the build/compile time, it takes 3 or so minutes to compile the app with yarn build.

deftomat commented 5 years ago

Unfortunately, I think that this still requires a little bit of investigation. Looks like we still don't know for 100% if it is caused by TypeScript itself or by fork-ts-checker (https://github.com/facebook/create-react-app/issues/7003#issuecomment-496137807)

cyrus-za commented 5 years ago

Not using material-ui, but my builds also take long (around 3-5 min) inside docker. Using typescript 3.5.2 with CRA 3.0.1

Is there some command to run to check which packages are taking long to transpile or type check? PS. 90% of my actual code is still in JS and only around 5 files in TS at the moment.

EDIT: On codeship it completely fails (only sometimes) when running out of memory.


<--- Last few GCs --->

[73:0x55aa01a9a4a0]   181594 ms: Mark-sweep 1326.2 (1427.0) -> 1326.0 (1427.5) MB, 1909.4 / 0.0 ms  (average mu = 0.107, current mu = 0.009) allocation failure scavenge might not succeed
[73:0x55aa01a9a4a0]   183308 ms: Mark-sweep 1327.9 (1427.5) -> 1327.7 (1429.0) MB, 1710.7 / 0.0 ms  (average mu = 0.057, current mu = 0.002) allocation failure scavenge might not succeed

<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0xd68d224fc5d]
    1: StubFrame [pc: 0xd68d220fcbc]
Security context: 0x0c0b9439d9d1 <JSObject>
    2: addMappingWithCode [0x139ce5841ec1] [/setup/node_modules/source-map/lib/source-node.js:~150] [pc=0xd68d4366e99](this=0x09f0335845e9 <JSGlobal Object>,0x2219eb678c11 <Object map = 0xd4c315dedc1>,0x32dfb5230891 <String[5]: o)&&(>)
    3: /* anonymous */ [0x29a9ce1822c9] [/setup/node_modules/source-map/lib/source-node....

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

Writing Node.js report to file: report.20190629.182235.73.0.001.json
Node.js report completed
error Command failed with exit code 1.

Running yarn why source-map shows that react-scripts (among other things) depend on it. I am guessing this has to do with the type-checking that @deftomat mentioned

info Reasons this module exists
   - Hoisted from "terser-webpack-plugin#source-map"
   - Hoisted from "handlebars#source-map"
   - Hoisted from "ts-node#source-map-support#source-map"
   - Hoisted from "terser-webpack-plugin#terser#source-map"
   - Hoisted from "handlebars#uglify-js#source-map"
   - Hoisted from "terser-webpack-plugin#webpack-sources#source-map"
   - Hoisted from "react-scripts#jest-environment-jsdom-fourteen#jest-util#source-map"
   - Hoisted from "react-scripts#babel-jest#@jest#transform#source-map"
   - Hoisted from "react-scripts#postcss-flexbugs-fixes#postcss#source-map"
   - Hoisted from "@storybook#react#babel-plugin-react-docgen#recast#source-map"
   - Hoisted from "react-scripts#jest-environment-jsdom-fourteen#jest-util#@jest#source-map#source-map"
   - Hoisted from "react-scripts#html-webpack-plugin#html-minifier#clean-css#source-map"
   - Hoisted from "react-scripts#jest-environment-jsdom-fourteen#jsdom#escodegen#source-map"
   - Hoisted from "@storybook#react#babel-plugin-react-docgen#react-docgen#recast#source-map"
   - Hoisted from "react-scripts#html-webpack-plugin#html-minifier#uglify-js#source-map"
   - Hoisted from "react-scripts#jest#jest-cli#@jest#core#@jest#reporters#source-map"
   - Hoisted from "react-scripts#jest#jest-cli#@jest#core#@jest#reporters#istanbul-lib-source-maps#source-map"
cyrus-za commented 5 years ago

This seems to be an error from v2 already. See: #6406, #5903, #6209 and #5820

@ianschmitz care to take a look at this?

PS. got CI=true set in the build. Not sure if that plays a role?

veksen commented 5 years ago

InvictusMB's answer (https://github.com/facebook/create-react-app/issues/7003#issuecomment-494251468) was the fix for me.

lukas1994 commented 5 years ago

yarn build takes 190sec for my project. This is the slowest part of my docker build script. Is there a way to speed this up?

johnnyreilly commented 5 years ago

I think this issue can present if you have your project in the root. Try moving it down a directory and see if that helps

lukas1994 commented 5 years ago

Interesting -- I'm running everything in /frontend in my container. Locally, it takes 70sec -- which is also quite slow tbf :/

lukas1994 commented 4 years ago

I'm still having this issue. Any ideas on how I can fix this?

mattoni commented 4 years ago

My production build is taking upward of 15 minutes. I am using the typescript template but other than that no changes have been made to the build process. Type checking also takes several minutes with TS3.8

veksen commented 4 years ago

I thought it was fixed, but ended up still having issues with long builds on other computers. I gave up and migrated from a base config of react-boilerplate-ts.

lukas1994 commented 4 years ago

Is anyone working on this? This is still a huge issue for us.

christopher-francisco commented 4 years ago

I have this problem, my project is fairly big so unless I add NODE_OPTIONS=--max-old-space-size=4096, it won't build, throwing OOM.

When it builds, it takes about 21 minutes.

We've built it with an old manually configured webpack setup and it takes 5 mins, so I'm guessing it's related to Typescript

jamesg1 commented 4 years ago

@lukas1994 I just tried the new snowpack typescript react template and it handles compilation of TS much faster leveraging ESM imports. It's backwards compatible with CRA and Typescript compatible out of the box, might be worth a try to help with your build performance issues. https://www.snowpack.dev/#what-is-snowpack%3F

deftomat commented 4 years ago

@jamesg1 Does Snowpack work correctly with old CommonJS packages? Because if yes, then it sound like a way to go. At least for a development.

jamesg1 commented 4 years ago

@jamesg1 Does Snowpack work correctly with old CommonJS packages? Because if yes, then it sound like a way to go. At least for a development.

I've been using their webpack bundler recently and find it great. The config is much more flexible than CRA yet keeps the simplicity similar to CRA.

anit commented 4 years ago

Our react application is in initial stages and at most we have added 5 components with libs like chakra-ui and styled-components

Solutions tried so far with respect to fork-ts-checker plugin, no difference in build time. Its still 1.5 hours:

  1. Setting async: true. Reduced cpu usage
  2. Changed the build script to TSC_WATCHFILE=UseFsEventsWithFallbackDynamicPolling react-app-rewired build

Alternatively I went right into node_modules and removed spliced fork-ts-checker from the plugins and the build was done in 10 seconds.

Digging more and found out that in addToAffectedFilesPendingEmit function it gets stuck on follow line:

        var existingKind = state.affectedFilesPendingEmitKind.get(affectedFilePendingEmit);

The problem is it always halts / pauses indefinitely (sort of) after processing few files.

anit commented 4 years ago

My issue was resolved after I bumped my typescript version from 3.9.7 to 4.0.0-beta. Build time with 3.9.7 eventually got to 4 hours. And it failed after 4 hours of running, pointing to this error: Expression produces a union type that is too complex to represent. TS2590. After this I just thought of giving upgrade to beta a try and the build time is now 10 seconds.

Yashpk789987 commented 4 years ago

@anit my issue didn't resolved after switching to typescript 4.0.0-beta. I am stuck . what should i do ? can anyone help me ??

yulolimum commented 4 years ago

Alternatively I went right into node_modules and removed spliced fork-ts-checker from the plugins and the build was done in 10 seconds.

For anyone looking for a workaround - @anit 's response helped me "solve" this issue with "typescript": "3.9.7" and "react-scripts": "3.0.1".

Local builds went from over 10mins to 40 seconds.

Provided is a patch file to use with patch-package (remove the .txt extension).

react-scripts+3.0.1.patch.txt

mankutila commented 3 years ago

Is an issue for me too. Prod build takes 10 mins. How can I debug it at least?

LuMizera commented 3 years ago

My build is also taking 30+ min, and i've tried a lot of things to improve and could not get a single second better

What i've tried: Changing imports from material-ui (which is heavy) removing some librarys and other things and none had any positive impact

jimyhdolores commented 3 years ago

Lo mismo por acá :(

spantheslayer commented 3 years ago

even specifying the max--old usafe for build does not effect the performance at all ,, is there any other solution ??

gkp1 commented 1 year ago

Ubuntu 20.04 LTS, running on a VPS, 1GB RAM. Regular user, with sudo privileges. Takes over an hour to build.

I am certain that having more RAM would make it faster, but it kind of makes no sense to take so long, because I have 2GB swap memory. Also, it would be GREAT if there was any progress bar or progress percentage indicator. Would be really really nice. Like, really. Show us where the loading is hanging...

I need to run this command before npm run build, or else it will always give me an error due to only having 1024MB RAM. Each argument fixes one error. export NODE_OPTIONS="--max-old-space-size=1024 --openssl-legacy-provider" (if you're still having problems, search how to enable swap memory) my dependencies:

  "dependencies": {
    "@material-ui/core": "^4.11.0",
    "@material-ui/icons": "^4.9.1",
    "@material-ui/lab": "^4.0.0-alpha.56",
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.0.4",
    "@testing-library/user-event": "^12.1.7",
    "axios": "^0.21.1",
    "date-fns": "^2.16.1",
    "emoji-mart": "^3.0.1",
    "formik": "^2.2.0",
    "i18next": "^19.8.2",
    "i18next-browser-languagedetector": "^6.0.1",
    "markdown-to-jsx": "^7.1.0",
    "mic-recorder-to-mp3": "^2.2.2",
    "qrcode.react": "^1.0.0",
    "react": "^16.13.1",
    "react-color": "^2.19.3",
    "react-dom": "^16.13.1",
    "react-modal-image": "^2.5.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "3.4.3",
    "react-toastify": "^6.0.9",
    "recharts": "^2.0.2",
    "socket.io-client": "^3.0.5",
    "use-sound": "^2.0.1",
    "yup": "^0.32.8"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {}
}