一、组件库加载方式
我们在使用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 目录
lib—— commonjs模块系统:由nodejs实现,多用于服务器端,通过require导入,module.exports导出,无法使用tree-shaking,无法处理循环依赖。
dist——UMD模块(commonjs的语法+AMD的异步加载)能够在客户端/服务器上工作。
es——es module模块系统:用于服务器/客户端,使用import、export,能够进行静态分析,因此可以进行tree-shaking,能更优雅的处理循环依赖。
1.2 组件目录
不管里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
style/index.tsx:样式入口文件,引入的less文件
button.tsx中并没引入任何样式文件
2、构建npm发布包
antd的打包编译都是使用的antd-tools
库里的方法
进入node_modules/@ant-design/tools/cli
中找到入口require('../gulpfile')
从gulp.task入手,找到'pub' 发现主要是 'compile'和'dist'
- 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
- 清空es/lib目录
- 处理less文件,复制一份less编译成css
- tsc处理ts|tsx文件,生成js和.d.ts
- babel解析js文件流,并在组件style目录下生成css.js
- 复制png|svg静态资源
2.2 compile-finalize
将components下所有组件的样式导入并在lib/style目录下生成components.less文件
2.3 dist
使用尾部pack打包生成dist目录
-
清空dist目录
-
执行webpack打包
-
在dist目录下生成antd.less文件,方便使用者定制化样式
webpack入口文件:由于组件内并没有引入样式文件(less),所以需要在入口文件中引入所有样式文件