为啥我的 Create React App Dev Server 需要这么长时间才能启动?

Posted

技术标签:

【中文标题】为啥我的 Create React App Dev Server 需要这么长时间才能启动?【英文标题】:Why does my Create React App Dev Server take so long to start?为什么我的 Create React App Dev Server 需要这么长时间才能启动? 【发布时间】:2022-01-15 05:04:55 【问题描述】:

我已经使用 Create React App 在 React 中创建了一个 Web 应用程序。在我的开发过程中,我的开发服务器的启动时间大大增加。现在启动大约需要 8 分钟。我正在使用 Craco 修改我的 Webpack 配置并编译我的 Less 主题,但我可以确认在没有 Craco 的情况下启动需要同样长的时间。当我使用 Craco 和 Webpackbar 运行我的服务器时,我可以判断出大部分启动时间是由 babel-loader 转换 node_modules 中的文件占用的,所以我怀疑这要么是我的配置问题,要么是我的依赖项的问题。该项目是用 TypeScript 编写的,除了 React 之外,我最大的两个依赖项是 Ant Design (antd) 和 Ant Design Icons (@antd/icons)。

我在下面包含了我的 package.json 和 craco.config.js 以及我的文件的依赖项以显示依赖关系树:

//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";

如何修改我的 Craco 配置以获得合理的开发服务器启动时间?

【问题讨论】:

~8 秒似乎没有那么长~哦,你说的是分钟。是的,很长 【参考方案1】:

我正在回答我自己的问题,因为我找到了一个可行的解决方案,但我没有将其标记为正确,因为我不相信我已经完全解决了这个问题。我将启动时间缩短到 2 分钟左右,但考虑到我的项目并不太复杂,我仍然认为启动时间不会太长。我仍然相信 Babel 的转译量超出了应有的水平。

虽然在我的 Craco 配置中使用 eslint: enable: false 似乎没有任何效果,但在 .env 中设置 DISABLE_ESLINT_PLUGIN=true 似乎有效 (docs)。

我在我的 Craco 配置中添加了以下选项,这大大缩短了我的开发服务器的启动时间:

//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 */ 
    
  ]

注意事项:

虽然 Babel 缓存确实有效,但 Webpack 缓存不会在 Craco updates to support the newly released CRA v5(3 天前发布)支持 Webpack v5 Persistent Caching 之前工作。同时,额外的配置选项被忽略。 虽然这些设置适用于约 95% 的构建,但the Webpack devs expect this to fail with ~5% of projects 虽然我在任何地方都找不到它的记录,但 this folder of the Webpackbar source 中的所有记者姓名都可以作为字符串传递到 reporters 数组中。 我也尝试将我的项目发送到compile with SWC to improve performance,但是当我访问我的应用程序时,它告诉我没有定义 React。我可能会对此进行进一步调查。

有用的资源:

This Medium Post on Webpack/Babel/ESLint Caching The Webpack Docs on Webpack Cache The Official Webpack Guide on Persistent Caching The Webpack Docs on babel-loader Options The Create React App Advanced Configuration Environment Variables List

【讨论】:

以上是关于为啥我的 Create React App Dev Server 需要这么长时间才能启动?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我无法在我的系统中安装 React 和卸载 create-react-app?

为啥我在使用 create-react-app 的生产构建中丢失了 Bootstrap 样式?

为啥 create-react-app 现在要为 App 使用一个函数组件?

为啥 create-react-app 会同时创建 App.js 和 index.js?

为啥 npm uninstall -g create-react-app 失败?

使用 create-react-app 将 react-router-dom 添加到 react 应用程序时,为啥玩笑测试会中断