You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Create React App:如何用config-overrides.js实现JS按需加载?

解决方案:通过config-overrides.js实现按需加载并优化chunk加载

一、关闭默认prefetch预加载

Create React App默认会为异步chunk添加rel=prefetch属性,导致页面初始化时就请求所有未来可能用到的chunk。在config-overrides.js中可以完全关闭该行为:

const { override } = require('customize-cra');

module.exports = override(
  (config) => {
    // 配置HtmlWebpackPlugin,关闭prefetch
    config.plugins.forEach(plugin => {
      if (plugin.constructor.name === 'HtmlWebpackPlugin') {
        plugin.options.prefetch = false;
        // 仅预加载初始必需的资源
        plugin.options.preload = {
          rel: 'preload',
          include: 'initial'
        };
      }
    });

    // 优化chunk拆分规则
    config.optimization.splitChunks = {
      chunks: 'async', // 仅拆分异步加载的chunk
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'async',
          priority: 10
        },
        common: {
          name: 'common',
          minChunks: 2,
          chunks: 'async',
          priority: 5,
          reuseExistingChunk: true
        }
      }
    };

    return config;
  }
);

二、组件/路由级按需加载

确保业务代码采用异步引入方式,实现真正的按需加载:

方式1:React.lazy + Suspense(推荐)

import React, { lazy, Suspense } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

// 异步引入路由组件
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
const Dashboard = lazy(() => import('./pages/Dashboard'));

function App() {
  return (
    <Router>
      <Suspense fallback={<div>加载中...</div>}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
          <Route path="/dashboard" element={<Dashboard />} />
        </Routes>
      </Suspense>
    </Router>
  );
}

export default App;

方式2:react-loadable(兼容类组件)

import Loadable from 'react-loadable';

const LoadableDashboard = Loadable({
  loader: () => import('./pages/Dashboard'),
  loading: () => <div>加载中...</div>
});

// 在路由中直接使用LoadableDashboard组件

三、解决"Loading chunk.js failed"错误

该错误多因chunk哈希变更、旧chunk被清理或网络异常导致,可通过以下方式处理:

1. 添加错误边界捕获

import React from 'react';

class ChunkErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error) {
    // 检测chunk加载错误并自动刷新
    if (error.message.includes('Loading chunk')) {
      setTimeout(() => window.location.reload(), 1000);
    }
  }

  render() {
    if (this.state.hasError) {
      return <div>页面加载出错,即将自动刷新...</div>;
    }
    return this.props.children;
  }
}

// 用错误边界包裹根组件
export default function Root() {
  return (
    <ChunkErrorBoundary>
      <App />
    </ChunkErrorBoundary>
  );
}

2. 稳定chunk哈希值

在config-overrides.js中添加哈希配置,避免无关代码变更导致chunk哈希变化:

(config) => {
  config.output.filename = 'static/js/[name].[contenthash:8].js';
  config.output.chunkFilename = 'static/js/[name].[contenthash:8].chunk.js';
  // 确保模块id稳定
  config.optimization.moduleIds = 'deterministic';
  return config;
}

四、验证效果

  • 本地运行时,打开浏览器Network面板,切换路由才会加载对应chunk
  • 生产构建后,查看index.html,不会出现带rel=prefetch的chunk链接,仅加载初始必需资源

内容的提问来源于stack exchange,提问作者Lanie Zhang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:17:21