likes
comments
collection
share

按需打包 UI 组件库原理探究

作者站长头像
站长
· 阅读数 14

本文由团队成员 若木 撰写,已授权涂鸦大前端独家使用,包括但不限于编辑、标注原创等权益。

背景

最近小组内有基于基础组件(如:antd )二次封装的需求,有一天听到组内同学讨论如何二次封装的组件库进行按需打包?听到这,心里就开始犯嘀咕了,因为自己之前也搞过基于基础组件库二次封装组件库的事,可从来没有往这个地方想过,想了下大概原因如下:

  1. 基于基础组件库的封装大概干如下几件事:

按需打包 UI 组件库原理探究

2.基于点1,其实我们也可以仔细想一下,代码量不会太多,包也不会太大

总算给自己找了一个相对合理的理由,哈哈。既然有人这么想,跟随一起探索下哈。

组件库到底如何实现按需加载

不晓得,不晓得,但至少使用过吧,赶紧去知名 UI 组件库 Antd 官网翻翻,查下组件按需加载的使用:

按需打包 UI 组件库原理探究

我勒个擦,怎么跟印象中不大一样呢,不过仔细看下 Antd 文档写的也很清楚,我们也找一下之前版本3.x的文档咱们来个大对比

按需打包 UI 组件库原理探究

对比看下来是不是很清醒哈:

Antd 4.X 版本是利用 webpack 基于 ES modules的 treeshaking 实现的按需加载。

Antd 3.X 版本是利用 babel插件 babel-plugin-import 对UI组件模块导入修改来实现按需加载的:

按需打包 UI 组件库原理探究

注意注意前方高能,瓜来,来了哈,仔细看下面两张图:

按需打包 UI 组件库原理探究

按需打包 UI 组件库原理探究 第二张图来自于 babel-plugin-import GitHub,插件默认配置下,应该是从 lib 下导包的,要严谨,要严谨,这个不是重点,不是重点,大家自行娱乐,自行判断哈

按需加载的原理到底是啥

上面说了这么多,似乎都没说到点上,确实如此,要想弄明白,必须搞清楚三件事:

第一件:Webpack

前端项目打包,目前来讲主流应该还是 Webpack (Vite 最近势头有点猛,开发体验也确实不错,有兴趣的话,大家可以尝试下),先了解下Webpack的打包原理,必须上一下经典图:

按需打包 UI 组件库原理探究 根据入口文件,递归查询相关依赖,然后通过各种 loader 和各种 plugin ,最终打包成一个 bundle文件或几个 bundle 文件(代码分割)。

其实这也不是重点,现在的 NPM 包一般会打出两种格式的包:CommonJs 和ES modules。那么问题来了,Webpack 怎么知道加载那种格式的依赖包呢,赶紧去 Webpack 官网刨了下文档,木有找相关的点,万能的互联网,有人提到 Webpack 是按这样的规则加载的对应的包的:

按需打包 UI 组件库原理探究

大概就是这样的哈,先点到这里,不明白没关系,后面再整体串一下哈。

第二件:NPM或package.json

其实上述的过程还是有问题的,Webpack 怎么知道有没有 ES module或 CommonJS module,其实通过组件库 package.json 中相关字段判断出来的:

按需打包 UI 组件库原理探究 (来个小插曲,module 字段不是 NPM 官方定义的字段,最早是有 rollup 提出来的,慢慢的 webpack 也在用啦,仔细的话,你会发现 package.json 有蛮多自定义的字段,可能为其他工具提供服务的)

这么一来,Webpack 就知道如何工作啦。

第三件:UI组件库打包输出什么?

不知道,没关系啦,看看大名鼎鼎的 Antd,输出了什么?

按需打包 UI 组件库原理探究

按需打包 UI 组件库原理探究

是不是很清醒,不明白???,那我从 ES module 和 CommonJS module 两个角度一起串一下下:

按需打包 UI 组件库原理探究

treeshaking 的 原理这里就不啰嗦了,不知道的自行查询下,注意下相关配置,姿势不正确,可能达不到你想要的效果。

总结

各位看官,不知大家有没有瞧明白哈,一直白嫖[捂脸][捂脸][捂脸],第一次输出,见谅见谅哈,大家若有问题欢迎讨论沟通哈

测试demo地址及补充说明:

  1. main 分支,支持构建 es , lib ( commonjs )包输出,同时存在 es , lib 构建输出包的情况下,进行 treeshaking 进行测试生效,进行 babel 插件进行按需加载不生效。

  2. es 分支,仅支持构建es包输出,进行treeshaking按需加载测试生效。

  3. lib 分支,仅支持构建 lib (commonjs)包输出,进行 babel 插件进行按需加载测试生效。

  4. niu-ui(乞丐版) 为测试UI包,examples 为验证用例,通过 webpack-bundle-analyzer ,npm link ,npm link niu-ui 实现验证

  5. 花絮,写这边文章的时候,最开始的使用 antd 进行直接验证,后来发现进行演示不太直观,后面采用自己实现一个简单的 UI 库,为了实现 antd 同样的构建打包结果,其过程中出现了一些有意思的事情,若是大家对打包构建有兴趣的话,后面再补一篇相关的文章。

最后,给大家留个问题,仔细的童鞋,可能也发现了如 Antd 输出的包 es , lib 都是以组件维度分别输出的,是否都必要还是什么哈,欢迎大家留言讨论,嘿嘿咻,结束啦。