react使用cdn加载react全家桶、antv、axios、antd

3,723 阅读2分钟

项目是使用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