前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React + TS + Ant Design 裁包小记

React + TS + Ant Design 裁包小记

原创
作者头像
iPlus26
修改2018-07-18 11:22:22
3.5K0
修改2018-07-18 11:22:22
举报
文章被收录于专栏:前端小记前端小记

前段时间做了一个项目,是使用 Create-React-App 脚手架 + TypeScript + Ant Design 组件库搭建的,在减少包体积上有一些方法和大家分享一下。我们目标是将包体积降到几十 k 这样一个级别上,不受限于包体积,坦然使用框架。

下文基于 webpack + TS 来说,如果你的项目不在使用 TypeScript 的话可能会有些不一样,但是思路是一致的;文章比较简单,如果遇到理解问题的话可以文章后面留言。

按需加载你的组件

比如我的项目中有个 modal,用户不点击触发这个弹窗,代码是不会被使用到的。webpack 原生就支持这种动态引入的写法

代码语言:txt
复制
export class YourComponent extends React.Component {
        onClick = () => { // 点击时才加载 Modal 相关的 js, 重命名这段js为 `modal123.hash.js`
            import('../Modal' /* webpackChunkName: 'modal123' */).then(Modal => {
                Modal.show()
            })
        }
}

按需加载 ant design 组件

你当然可以通过如下的方式实现按需加载第三方组件。这样做的话不会将整个组件库都打包进你的 js bundle,只会将 Button 相关的代码打包进来

代码语言:txt
复制
// 方法1
import Button from 'antd/lib/button';
import Menu from 'antd/lib/menu';

但是上述方法做显然不如下面来得方便和简洁。但下面这样做却会将整个组件库打包进你的 js bundle 中,显然是不能用于生产环境。

代码语言:txt
复制
// 方法2
import {Button, Menu} from 'antd';

为此 Ant design 提供了一个 webpack 插件 ts-import-plugin, 使用了这个插件后就可以使用 方法2 引入组件,并在打包的时候按需加载。

less 自定义变量 + 按需加载 ant design 组件样式

在我们的项目中需要自定义 ant design 的组件样式,你可以通过 自定义 less 变量 的方式来实现你的自定义样式

代码语言:txt
复制
@import "~antd/dist/antd.less";   // 引入官方提供的 less 样式入口文件
@primary-color: #2ca7fa;

但这样做的问题是,ant design 样式文件仍然是“整包引入”的,我是通过如下方式按需加载的

代码语言:txt
复制
/**
 * 手动按需引入需要的 antd 样式
 *
 * based on node_modules/antd/lib/style/components.less 
 */
@import "../../node_modules/antd/lib/style/index.less";
@import "../../node_modules/antd/lib/alert/style/index.less";
@import "../../node_modules/antd/lib/button/style/index.less"; // 按需引入官方的基础样式、alert样式、按钮样式

@primary-color: #2ca7fa;

外链 css

把 less 文件从 js bundle 中拆分出来,减少 js bundle 体积,预先加载 css

干掉 MomentJs

使用 dayjs 替换 momentjs. Ant design 的 LocaleProvider 中始终引用了整个 momentjs.

实际上下表中moment这个体积是包含了locales的,本来就会把它删掉,不会有那么多,这里大概会减少20kB左右

library

minified and gzipped

moment

64.2kB

dayjs

2.5kB

source: https://bundlephobia.com/result?p=dayjs@1.7.4

如何使用 2kB 的 dayjs 来替换掉 64 kB 的momentjs 呢,这里用到是 webpack 的 alias

代码语言:txt
复制
module.exports = {
    resolve: {
        alias: {
            'moment': 'dayjs',
            'react': 'anujs',
            'react-dom': 'anujs',
        },
    }
}

减小 React 体积

业界有很多跟 React 保持一致 API 但是可能在兼容性、包体积等方面有差异的类库 (React-like),比如大名鼎鼎的 preact 在 gzip 之后只有 3kB. 我们可以选用包体积更小的类库,和上述的 webpack alias 将 react 和 react dom 替换掉。

我们这里是使用 anujs 替换 react & react-dom. 截至目前,anujs 对 react 16 支持最好,preact, nervjs 等不支持 React Fragment, createPortal 等 API

但这里的风险是,可能会导致兼容性问题:anujs和react行为不一定一致,所以在进行这一步替换之后,务必进行详尽的测试。不认为自己有能力把控风险的同学请谨慎操作。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 按需加载你的组件
  • 按需加载 ant design 组件
  • less 自定义变量 + 按需加载 ant design 组件样式
  • 外链 css
  • 干掉 MomentJs
  • 减小 React 体积
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档