项目优化

项目优化

项目打包以及本地预览

1
2
3
4
5
6
7
// 打包
yarn build
// 本地预览
// 安装全局安装本地服务包
npm i -g serve
// 或 直接使用
npx serve -s ./build

打包体积分析

1
2
3
4
5
6
7
8
9
10
11
12
13
// 安装分析打包体积的包
yarn add source-map-explorer
// 在package.json中添加一条命令 "anylyze": "source-map-explorer 'build/static/js/*.js"
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject",
"anylyze": "source-map-explorer 'build/static/js/*.js"
}
// 使用
yarn anylyze

路由懒加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 导入 lazy 和 Suspense 需要配合使用
import { lazy, Suspense } from 'react'
// 正常导入页面
import Layout from '@/pages/Layout'
import Login from './pages/Login'
import NotFound from './pages/NotFound'

// 懒加载导入,
const Layout = lazy(() => import('@/pages/Layout'))
const Login = lazy(() => import('./pages/Login'))
const NotFound = lazy(() => import('./pages/NotFound'))

// Suspense组件需要将把懒加载的组件包裹在里面
export default function App() {
return (
<Router history={customHistroy}>
{/* 使用Suspense 包裹所有内容 */}
<Suspense fallback="loading..."> //fallback可以写jsx代码,可以使用组件制作loding效果
<div className="app">
<Switch>
<Route path="/" exact render={() => <Redirect to="/home" />} />
<AuthRoute path="/home" component={Layout} />
<Route path="/login" component={Login} />
{/* 404 */}
<Route>
<NotFound />
</Route>
</Switch>
</div>
</Suspense>
</Router>
)
}

配置CDN(内容分发网络)

通过 craco 来修改webpack配置,从而实现CDN优化

craco文档地址

外部扩展(Externals)

安装 craco

1
2
3
yarn add  @craco/craco
//或者
npm install @craco/craco --save

在项目 根目录新建craco.config.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
const { whenProd, getPlugin, pluginByName } = require('@craco/craco')
// whenProd => when production 针对生产环境做处理
// whenProd()第一个参数,在生产环境中,第二个参数,默认值
// whenProd(() => {},[])
const path = require('path')
module.exports = {
// webpack配置
webpack: {
// 配置别名
alias: {
// 约定:使用 @ 表示 src 文件所在路径
'@': path.resolve(__dirname, 'src'),
},
configure: (webpackConfig) => {
// 生产环境下,配置 externals
webpackConfig.externals = whenProd(
() => ({
react: 'React',
'react-dom': 'ReactDOM',
redux: 'Redux',
'react-router-dom': 'ReactRouterDOM',
}),
{}
)
// 拿到 HtmlWebpackPlugin 插件
const { isFound, match } = getPlugin(
webpackConfig,
pluginByName('HtmlWebpackPlugin')
)
// 生产环境下,暴露 CDN 链接到模板页面中
if (isFound) {
// match 表示当前匹配的插件 HtmlWebpackPlugin
// 通过 options 将额外的数据添加给 HtmlWebpackPlugin 插件
// options可以传递任意数据,比如,此处我们自己写的 cdn 就是要额外传递的数据
match.options.cdn = {
// js 链接
js: whenProd(
() => [
'https://cdn.bootcdn.net/ajax/libs/react/18.2.0/cjs/react-jsx-dev-runtime.production.min.js',
'https://cdn.bootcdn.net/ajax/libs/react-dom/18.2.0/cjs/react-dom-server-legacy.browser.production.min.js',
'https://cdn.bootcdn.net/ajax/libs/redux/4.2.1/redux.min.js',
'https://cdn.bootcdn.net/ajax/libs/react-router-dom/6.10.0/react-router-dom.production.min.js',
],
[]
),
// css 链接
css: [],
}
}
return webpackConfig
},
},
}

public/index.html中:

1
2
3
4
5
6
7
	
<div id="root"></div>
<!-- 加载第三方包的 CDN链接 -->
<% htmlWebpackPlugin.options.cdn.js.forEach(cdnURL => { %>
<script src="<%= cdnURL %>"></script>
<% }) %>
</body>

查找项目中对应的CDN

unpkg
bootcdn