项目是使用react脚手架搭建的,使用了customize-cra、react-app-rewired来修改脚手架默认的配置
1、添加配置项
安装和配置完成基本的config-overrides.js后,添加addWebpackExternals
选项用来配置cdn
完整的配置项请查看:官方文档,下面只展示配置cdn的代码
在里面写入我们需要cdn加载的文件,我们直接把G2plot挂载到全局
const {override, addLessLoader, addWebpackAlias, addWebpackModuleRule, addWebpackExternals} = require('customize-cra')
const path = require('path')
module.exports = override(
/* 由于我们使用了cdn来引入资源,所以这里的按需引入也就不需要了 */
// fixBabelImports('import', {
// libraryName: 'antd',
// libraryDirectory: 'es',
// style: true,
// }),
// 设置路径别名
addWebpackAlias({
'@serve': path.resolve(__dirname, './src/serve'),
'@utils': path.resolve(__dirname, './src/utils'),
'@store': path.resolve(__dirname, './src/store'),
'@views': path.resolve(__dirname, './src/views'),
'@assets': path.resolve(__dirname, './src/assets'),
'@router': path.resolve(__dirname, './src/router'),
'@layouts': path.resolve(__dirname, './src/layouts'),
'@components': path.resolve(__dirname, './src/components'),
}),
//配置cdn引入
addWebpackExternals({
react: 'React',
'react-dom': 'ReactDOM',
'react-router-dom': 'ReactRouterDOM',
'antd': 'antd',
'redux': 'Redux',
'axios': 'axios',
'@antv/g2plot': 'window.G2plot',
})
)
2、index.html添加cdn在线链接
js建议放在下方,原因都知道
<!-- antd样式 -->
<link rel="stylesheet" href="https://unpkg.com/antd@4.16.13/dist/antd.min.css"><link rel="text/less" href="https://unpkg.com/antd@4.16.13/dist/antd.less">
<!-- react相关 -->
<script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/react-router-dom/5.3.0/react-router-dom.min.js"></script>
<script src="https://unpkg.com/redux@4.0.1/dist/redux.js"></script>
<!-- antd -->
<script crossorigin src="https://unpkg.com/antd@4.16.13/dist/antd.min.js"></script>
<!-- G2Plot -->
<script type="text/javascript" src="https://unpkg.com/@antv/g2plot@2.3.33/dist/g2plot.min.js"></script>
<!-- axios -->
<script type="text/javascript" src="https://unpkg.com/axios/dist/axios.min.js"></script>
3、使用
react、react-dom、react-router-dom、redux的使用还是和之前一样,之前怎么使用,配置完成后还是怎么使用,比如下面这个代码
import React from 'react'
import {connect} from 'react-redux'
import {withRouter} from 'react-router-dom'
import styles from './layout.module.less'
import {Col, Row, Dropdown, Menu, Avatar, Modal, message, Breadcrumb} from 'antd'
import {EditOutlined, MenuUnfoldOutlined, MenuFoldOutlined, CaretDownOutlined, LogoutOutlined, ExclamationCircleOutlined} from '@ant-design/icons'
import {removeUserData} from '@utils/local'
import {setCollapse} from '@store/actions/collapse'
import avatarUrl from '@assets/images/users/header.webp'
import menus from '@router/menus'
import {generateBreadcrumbs, generateBreadByRoutes} from './utils'
const HeaderBar = props => {
console.log(props)
const {collapse, setCollapse, location, userInfo} = props
const handleMenuClick = ({key}) => {
if (key === 'logout') {
console.log('logout')
Modal.confirm({
closable: true,
title: '确定要退出登录吗?',
cancelText: '取消',
okText: '确定',
icon: <ExclamationCircleOutlined />,
onOk() {
removeUserData()
window.location.reload()
message.success('退出成功')
}
})
}
}
//折叠菜单
const onHeaderToggleClick = () => {
setCollapse({isCollapsed: !collapse.isCollapsed})
}
const menu = (
<Menu onClick={handleMenuClick}>
<Menu.Item key="logout">
<span className="cursor-pointer">
<LogoutOutlined style={{color:'#1890ff',fontWeight:'bold'}} />
<span style={{marginLeft:'8px'}}>退出登录</span>
</span>
</Menu.Item>
<Menu.Item key="password">
<span className="cursor-pointer">
<EditOutlined style={{color:'red',fontWeight:'bold'}} />
<span style={{marginLeft:'8px'}}>修改密码</span>
</span>
</Menu.Item>
</Menu>
)
const breads = {
...generateBreadByRoutes(menus),
'/': '首页'
}
const list = generateBreadcrumbs(breads, location.pathname)
return (
<header className={styles.headerBar}>
<Col className={styles.headerToggle} style={{marginLeft:collapse.isCollapsed?'20px':'',display:'flex'}} align="middle" justify="center">
<span className={styles.toggleWrapper} onClick={onHeaderToggleClick}>{collapse.isCollapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}</span>
<Breadcrumb style={{marginLeft:'10px'}}>
{list.map(item => (<Breadcrumb.Item key={item.path}>{item.name}</Breadcrumb.Item>))}
</Breadcrumb>
</Col>
<div className={styles.headerRight}>
<Dropdown overlay={menu} placement="bottomRight">
<Row className={styles.user} align="middle">
<span className={styles.name}>{userInfo.userName||'用户名'}</span>
<Avatar
className={styles.avatar}
src={avatarUrl}
icon={<img src={avatarUrl} alt="avatar"/>}
/>
<CaretDownOutlined/>
</Row>
</Dropdown>
</div>
</header>
)
}
const mapDispathToProps = {setCollapse}
export default connect(state => ({collapse: state.collapse, userInfo: state.userInfo}), mapDispathToProps)(withRouter(HeaderBar))
唯一不同的就是G2Plot,官网上是这样使用的
所以我们在需要用到的地方也要这样使用
项目部分页面截图
4、打包测试
完成后我们来打包看下整体的项目体积
开启cdn后的项目体积
未开启后打包完成地项目体积
可能有人说这也没少多少,也就是一半吧,因为我得package.json里面只是把一些重要的依赖开启了cdn,其他的一些还没来得及修改
像这些react相关的都可以,还有md5、nprogress、qs