Why does my Create React App Dev Server take so long to start?
Asked Answered
U

1

6

I have created a web application in React with Create React App. Somewhere in my development process, the launch time for my development server grew tremendously. It now takes about 8 minutes to launch. I am using Craco to modify my Webpack config and to compile my Less theme, but I can confirm that launching without Craco takes just as long. I can tell when I run my server with Craco and Webpackbar that the majority of the launch time is taken by babel-loader transpiling files in node_modules, so I suspect that this is either a problem with my configs or my dependencies. The project is written in TypeScript and my two biggest dependencies besides React are Ant Design (antd) and Ant Design Icons (@antd/icons).

I've included my package.json and craco.config.js as well as the dependencies of my files below to show the dependency tree:

//package.json
{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@ant-design/icons": "^4.7.0",
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "antd": "^4.17.2",
    "axios": "^0.23.0",
    "craco-less": "^1.20.0",
    "rc-footer": "^0.6.6",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^5.3.0",
    "react-syntax-highlighter": "^15.4.4",
    "web-vitals": "^1.1.2"
  },
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@craco/craco": "^6.4.3",
    "@types/antd": "^1.0.0",
    "@types/react-router-dom": "^5.1.9",
    "@types/react-syntax-highlighter": "^13.5.2",
    "@types/webpack-bundle-analyzer": "^4.4.1",
    "@types/webpackbar": "^4.0.2",
    "craco-antd": "^1.19.0",
    "react-scripts": "4.0.3",
    "webpack-bundle-analyzer": "^4.5.0",
    "webpackbar": "^5.0.0-3"
  }
}
//craco.config.js
const CracoAntDesignPlugin = require( "craco-antd" )
const WebpackBar = require( "webpackbar" )
const { BundleAnalyzerPlugin } = require( "webpack-bundle-analyzer" )
const path = require( "path" )
const { getThemeVariables } = require( "antd/dist/theme" )

module.exports = {
  eslint: {
    enable: false // This doesn't seem to do anything, either. I still get eslint warnings after launching.
  },
  webpack: {
    cacheDirectory: true, // I'm not sure if this has any effect.
    plugins: [
      // @ts-ignore
      new WebpackBar( { profile: true } ),
      new BundleAnalyzerPlugin(
        {
          openAnalyzer: false,
          analyzerMode: "static",
          reportFilename: path.join( __dirname,  "build", "bundle_analysis.html" )
        }
      )
    ]
  },
  plugins: [
    {
      plugin: CracoAntDesignPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: getThemeVariables( {
              dark: true
            } )
          }
        }
      }
    }
  ]
}
//Imports in index.tsx
import React, { createElement, lazy, Suspense, useEffect, useState } from "react";
import ReactDOM from "react-dom";
import PropTypes, { InferProps } from "prop-types";
import {
  BrowserRouter,
  Switch,
  Route,
  Redirect,
  NavLink,
  useRouteMatch
} from "react-router-dom"
import { Col, Empty, Layout, Menu, Row, Skeleton } from "antd"
import { MenuOutlined } from "@ant-design/icons"

import { Callback, Repeat } from "./Utils"
import Header from "./Header"
import Footer from "./Footer"

import "./index.less"
import "rc-footer/assets/index.css"
import reportWebVitals from "./reportWebVitals"
//Imports in Header.tsx
import { useEffect, useState } from "react"
//Imports in Footer.tsx
import { Button, Card, Space } from "antd"
import useBreakpoint from "antd/lib/grid/hooks/useBreakpoint"
import RCFooter from "rc-footer"
//Imports in MyAccount.tsx
import { Button, Card, Col, Form, Input, Row } from "antd";
//Imports in Utils.tsx
import { useEffect } from "react"
import PropTypes, { InferProps } from "prop-types"
//Imports in index.less
@import "normalize.css";
@import "~antd/dist/antd.less";
@import "~antd/dist/antd.dark.less";

How can I modify my Craco config to have a reasonable dev server launch time?

Upland answered 10/12, 2021 at 13:58 Comment(1)
~8 seconds don't seem that long~ oh you said minutes. yea that's longManual
U
5

I'm answering my own question because I found a workable solution, but I'm not marking it as correct because I don't believe that I've completely solved the problem. I got my launch time down to about 2 minutes, but I still don't think that launching should take that long considering that my project is not too complicated. I still believe that Babel is transpiling more than it should.

Although using eslint: { enable: false } didn't seem to have any effect in my Craco config, setting DISABLE_ESLINT_PLUGIN=true in .env seemed to work (docs).

I added the following options to my Craco config which improved my development server's launch time considerably:

//craco.config.js

//Imports are unchanged

module.exports = {
  typescript: {
    // Visual Studio Code does type checking, so CRA doesn't need to:
    enableTypeChecking: false
  },
  babel: {
    loaderOptions: {
      //Enable babel-loader cache:
      cacheDirectory: true, //This is the correct location for cacheDirectory (it was wrong in the question)
      //Compress cache which improves launch speed at the expense of disk space:
      cacheCompression: false
    }
  },
  webpack: {
    configure: {
      cache: {
        //Enable Webpack cache:
        type: "filesystem"
        //This have any effect until Craco updates to CRA v5
        //which has support for Webpack v5 (see notes below)
      }
    },
    plugins: [ //Webpack plugins:
      new WebpackBar(
        {
          reporters: process.env.NODE_ENV === "development"
            ? [
                //Enable default progress bar:
                "fancy",
                //Display time for compile steps after compilation:
                "profile",
                //(Optional) Display launch time and chunck size:
                "stats"
              ]
            : [
                //Hide fancy progress bar and profiling for production build:
                "basic"
              ]
        }
      ),
      new BundleAnalyzerPlugin( { /* Options are unchanged */ } )
    ]
  },
  plugins: [ //Craco plugins:
    {
      plugin: CracoAntDesignPlugin,
      options: { /* Options are unchanged */ }
    }
  ]
}

A Few Things to Note:

Useful Resources:

Upland answered 17/12, 2021 at 10:10 Comment(1)
Using the typescript and babel options in craco dropped my build time from 1m 25s to 15s. Thanks a million!Dehiscence

© 2022 - 2024 — McMap. All rights reserved.