React项目打包流程

一、React项目打包流程

复制代码
一、React项目打包流程

1. 项目打包

打包命令:npm run build

2. 预览

接着命令行会提示执行:
先:npm install -g serve  
然后执行此命令:serve -s build

二、打包优化 - 配置路由懒加载

复制代码
二、打包优化 - 配置路由懒加载
路由懒加载是指路由的JS资源只有在被访问时才会动态获取,目的是为了优化项目首次打开的时间

1. 把路由修改为由React提供的lazy函数进行动态导入
2. 使用React内置的Suspense组件包裹路由中element选项对应的组件

代码如下所示:
// 路由配置
import { Suspense, lazy } from 'react';
import { AuthRoute } from '@/components/AuthRoute';
import { createBrowserRouter } from 'react-router-dom';

// 一级路由
import Layout from '@/pages/Layout';
import Login from "@/pages/Login";

// 1. lazy函数对二级路由组件进行导入
const Home = lazy(() => import('@/pages/Home'))
const Article = lazy(() => import('@/pages/Article'))
const Publish = lazy(() => import('@/pages/Publish'))

// 二级路由
// import Home from '@/pages/Home';
// import Article from '@/pages/Article';
// import Publish from '@/pages/Publish';

// 配置路由实例
const router = createBrowserRouter([
    {
        path: '/',
        // 根据权限的有无控制路由跳转
        element: <AuthRoute><Layout /></AuthRoute>,
        children: [
            {
                path: 'home',
                element: <Suspense fallback="加载中"><Home /></Suspense>
            },
            {
                path: 'article',
                element: <Suspense fallback="加载中"><Article /></Suspense>
            },
            {
                path: 'publish',
                element: <Suspense fallback="加载中"><Publish /></Suspense>
            }
        ]
    },
    {
        path: '/login',
        element: <Login />
    }
])

export default router;

三、打包优化 - 包体积分析

复制代码
三、打包优化 - 包体积分析

通过可视化的方式,直观的体现项目中各种包打包之后的体积大小,方便做优化

1. 安装包 --> source-map-explorer

npm i source-map-explorer

2. 配置命令指定要分析的js文件

在package.json内scripts添加如下代码:"analyze": "source-map-explorer 'build/static/js/*.js'"

"scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "craco eject",
    "analyze": "source-map-explorer 'build/static/js/*.js'"
}

四、打包优化 - CDN优化

复制代码
四、打包优化 - CDN优化

1. 什么是CDN? 
CDN是一种内容分发网络服务,当用户请求网站内容时,由离用户最近的服务器将缓存的资源内容传递给用户

2. 哪些资源可以放到CDN服务器
体积较大的非业务JS文件,比如react、react-dom
⑴. 体积较大,需要利用CDN文件在浏览器的缓存特性,加快加载时间
⑵. 非业务JS文件,不需要经常做变动,CDN不用频繁更新缓存

3. 项目中怎么做?
⑴. 把需要做CDN缓存的文件排除在打包之外(react,react-dom)
⑵. 以CDN的方式重新引入资源(react、react-dom)


1. craco.config.js代码如下:

// 扩展webpack的配置
const path = require('path');
// 引入辅助函数
const {whenProd, getPlugin, pluginByName} = require('@craco/craco');

module.exports = {
    // webpack 配置
    webpack: {
        // 配置别名
        alias: {
            // 约定:使用@表示src文件所在路径
            '@': path.resolve(__dirname, 'src')
        },
        // 配置CDN
        configure: webpackConfig => {
            let cdn;
            whenProd(() => {
                // key: 不参与打包的包(由dependencies依赖项中的key决定)
                // value: cdn文件中,挂载于全局的变量名称,为了替换之前在开发环境下
                webpackConfig.externals = {
                    react: 'React',
                    'react-dom': 'ReactDOM'
                }
                // 配置现成的cdn资源地址
                // 实际开发的时候,用公司自己花钱买的cdn服务器
                cdn = {
                    js: [
                        "https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js",
                        "https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js"
                    ]
                }
            });

            // 通过htmlWebpackPlugin插件,在public/index.html注入cdn资源url
            const {isFound, match} = getPlugin(webpackConfig, pluginByName('HtmlWebpackPlugin'));
            if (isFound) {
                // 找到了HtmlWebpackPlugin的插件
                match.userOptions.cdn = cdn;
            }

            return webpackConfig;
        }
    }
}

2. public文件夹下index.html代码如下:

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
     <!-- 动态插入cdn资源url, 加载第三发包的 CDN 链接 -->
    <% htmlWebpackPlugin.userOptions.cdn.js.forEach(cdnURL => { %>
      <script src="<%= cdnURL %>"></script>
    <% }) %>
</body>
相关推荐
@大迁世界8 小时前
07.React 中的 createRoot 方法是什么?它具体如何运作?
前端·javascript·react.js·前端框架·ecmascript
发现一只大呆瓜10 小时前
React-彻底搞懂 Redux:从单向数据流到 useReducer 的终极抉择
前端·react.js·面试
发现一只大呆瓜11 小时前
React-路由监听 / 跳转 / 守卫全攻略(附实战代码)
前端·react.js·面试
Ruihong17 小时前
【VuReact】轻松实现 Vue 到 React 路由适配
前端·react.js
软弹20 小时前
深入理解 React Ref 机制:useRef 与 forwardRef 的协作原理
前端·javascript·react.js
前端炒粉20 小时前
React 面试高频题
前端·react.js·面试
张一凡9320 小时前
React 项目也能用依赖注入?我尝试了一下,真香
前端·react.js
Csvn21 小时前
Redux Toolkit 实战
react.js
snow_yan21 小时前
基于 json-render 的流式表单渲染方案
前端·react.js·llm
Csvn21 小时前
组件设计模式(下):HOC、Render Props 与 Compound Components
react.js