React + TS + Ant Design 裁包小记

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

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

按需加载你的组件

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

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 相关的代码打包进来

// 方法1
import Button from 'antd/lib/button';
import Menu from 'antd/lib/menu';

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

// 方法2
import {Button, Menu} from 'antd';

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

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

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

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

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

/**
 * 手动按需引入需要的 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

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行为不一定一致,所以在进行这一步替换之后,务必进行详尽的测试。不认为自己有能力把控风险的同学请谨慎操作。

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

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

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯社交用户体验设计

vuejs初体验-Chrome插件开发实录

3362
来自专栏贾鹏辉的技术专栏@CrazyCodeBoy

React Native调试技巧与心得

本文出自《React Native学习笔记》系列文章。 在做React Native开发时,少不了的需要对React Native程序进行调试。调试程序是每一位...

6225
来自专栏前端儿

教你如何在React及Redux项目中进行服务端渲染

使用 redux-saga 处理异步action,使用 express 处理页面渲染

3201
来自专栏一个默默无闻的工程师的日常

Qt常用窗口部件

2873
来自专栏肖蕾的博客

第三章:中文绘制(一 傻逼版)Hiero工具BitmapFont绘制中文

1.LibGdx底层使用OpenGL ,可以支持中文。 2.中文汉字,都是以贴图的方式显示。 3.显示中文,需要读取包含中文汉字信息的 .fnt 后缀文件,...

1332
来自专栏啸天"s blog

制作MAGISK字体模块

自从上了8.1后,手机换字体只能通过magisk模块进行更改,用其他方式就会翻车,无奈之下去找字体包,可是感觉有的自己喜欢的字体大多数是ttf格式就很不开心。

8.1K2
来自专栏技术博客

ExtJs七(ExtJs Mvc创建ViewPort)

在4.1的时候,要先创建一个扩展于Ext.app.Application的类,然后用create创建它的实例来开始应用程序的。而在4.1.1,则可直接调用app...

1404
来自专栏从零开始学自动化测试

Fiddler抓包10-会话框添加请求类型(get、post)

前言 在使用fiddler抓包的时候,查看请求类型get和post每次只有点开该请求,在Inspectors才能查看get和post请求,不太方便。于是可以在会...

2274
来自专栏小樱的经验随笔

基于Windows下python3.4.1IDLE常用快捷键小结

安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器。 IDLE默认不能显示行号,使用ALT+G 跳到对应...

3966
来自专栏CRPER折腾记

Angular 2 + 折腾记 :(8) 动手写一个不怎么靠谱的上传组件

上传功能在任何一个网站中的地位都是举足轻重的,这篇文章主要扯下如何实现一个上传组件

1621

扫码关注云+社区

领取腾讯云代金券