浅析antd-v4按需引入

2,929 阅读3分钟

一、组件库加载方式

我们在使用ant-design、element-ui等UI组件库的时候都会使用按需加载来减少产物的体积。以antd-v4为例,以下方式按需加载:

1、手动加载

import Button from 'antd/es/button'
import 'antd/es/button/style'

2、babel-plugin-import插件

babel配置

module.exports = {
    plugins: [
        [
            'import',
            {
                libraryName: 'antd',
                libraryDirectory: 'es',  // es or lib,默认lib
                style: true,  // true: require('antd/es/xxx/style'); css: require('antd/es/xxx/style/css'); funciton: 自定义
            },
            'antd'
        ]
    ]
}

使用组件

// 引入组件
import { Button } from 'antd'

二、antd-npm包解析

1、npm包目录结构

1.1 目录

1687851025780.png
lib—— commonjs模块系统:由nodejs实现,多用于服务器端,通过require导入,module.exports导出,无法使用tree-shaking,无法处理循环依赖。

dist——UMD模块(commonjs的语法+AMD的异步加载)能够在客户端/服务器上工作。

es——es module模块系统:用于服务器/客户端,使用import、export,能够进行静态分析,因此可以进行tree-shaking,能更优雅的处理循环依赖。

1.2 组件目录

1687851043069.png

1687851057706.png

不管里lib还是es目录结构都是一样的,都有一个style目录和js文件,style目录结构也一样。

但在每个组件js文件里并没有引入style相关文件,那style是在什么时候被引入的,如何被引入的呢?

2、babel插件按需引入分析

2.1 不使用babel插件:

当不使用babel插件的时候,引入组件import { Button } from 'antd' tree-shaking能将js按需引入,只需要webpack做相应的配置:

mode: 'production'  // 自动开启optimization.useExports

但样式无法按需加载,只能手动引入或从dist全量引入

2.2 使用babel插件:

配置:{ libraryDirectory: 'es', style: true }

// 引入组件
import { Button } from 'antd'// babel转换后
import 'antd/es/button/style'
import Button from 'antd/es/button'

配置:{ libraryDirectory: 'lib', style: 'css' }

// 引入组件
import { Button } from 'antd'// babel转换后
import 'antd/lib/button/style/css'
import Button from 'antd/lib/button'

三、antd打包流程

1、antd的src

1687851084326.png

style/index.tsx:样式入口文件,引入的less文件

button.tsx中并没引入任何样式文件

image.png

2、构建npm发布包

antd的打包编译都是使用的antd-tools库里的方法

进入node_modules/@ant-design/tools/cli中找到入口require('../gulpfile')

从gulp.task入手,找到'pub' 发现主要是 'compile'和'dist'

1687851100156.png

1687851116615.png

  • dist:生成dist目录
  • compile-with-es: 生成es目录
  • compile-with-lib:生成lib目录
  • compile-finalize:在生成lib/style下生成components.less

2.1 compile es/lib

生成es和lib的步骤都是一样的,只是一个是生成es module一个是commonjs

  1. 清空es/lib目录
  2. 处理less文件,复制一份less编译成css
  3. tsc处理ts|tsx文件,生成js和.d.ts
  4. babel解析js文件流,并在组件style目录下生成css.js
  5. 复制png|svg静态资源

2.2 compile-finalize

将components下所有组件的样式导入并在lib/style目录下生成components.less文件

1687851132622.png

2.3 dist

使用尾部pack打包生成dist目录

  1. 清空dist目录

  2. 执行webpack打包

  3. 在dist目录下生成antd.less文件,方便使用者定制化样式

1687851149065.png

1687851161068.png

webpack入口文件:由于组件内并没有引入样式文件(less),所以需要在入口文件中引入所有样式文件

1687851187610.png

1687851200582.png