type
status
date
slug
summary
tags
category
icon
password

前期工作

也许你废了好大劲打开的源码是这样的?
notion image
这是ant-design的Button组件,你会发现和github源码有很多不一样的地方:
  1. 它不是tsx文件,没有ts语法,就是个普通js。
  1. 有编译器生成的/*#__PURE__*/注释。
  1. React.createElement等函数。
  1. 一些babel转译后的ES5的语法。
  1. ···
这些我们会下面意义拆解。现在我们先把调试环境建立起来。

新建项目

这边我们新建一个vite的react+ts的项目
注意:我们这边使用的是普通typescript,不要选typescript+swc。我们后面会基于babel处理。
修改下App.tsx,把它整的赶紧些。
之后把项目跑起来🚀

调试环境

notion image
创建一个launch文件
  • 类型:chrome。
  • url: 你项目对应的服务地址。
好了现在在你的App文件中断点在App函数上,运行调试吧。
notion image
这个renderWithHooks函数是react的所有hooks函数的入口,点击看下断点目前的位置
notion image
现在指向了App,我们加一个断点条件,也删掉App中的断点。
notion image
重新运行,我们发现现在我们找到了Button这个按钮。我们进入函数内部看下。
不出意外的意外发生了,进来之后我们看到的是文章开头展示的那张被编译后的js代码。
好,正文开始!

Ant Design

下载源码

  • -depth=1:这个参数用于指定克隆时只获取最近的1次commit记录,这样可以减少下载的数据量。
  • -single-branch:这个参数表示只克隆远程仓库的单个分支,默认是master分支。
都是为了快速clone。

观察打包命令

ant-design/package.json
notion image
notion image
  1. build命令做了2件事,分别运行了compile和dist
  1. compile和dist命令又分别通过antd-tools执行的
  1. dist产出的是UMD的包。
  1. compile产出的是ESM和CJS的包。

探索antd-tools

ant-design/node_modules/@ant-design/tools
找到tools下面的package.json文件看到bin注册了antd-tools
notion image
bin文件指向了cli文件夹(require('../lib/cli')),内容如下:
notion image
也就是我们的compile和dist命令。让我们看一下gulp怎么串联流程的。

细品gulpfile

ant-design/node_modules/@ant-design/tools/lib/gulpfile.js
这边主要参与打包的是webpack和tsc+babel。dist对应webpack,compile对应tsc+babel。

先看compile

找到compile的task,分别执行了'compile-with-es', 'compile-with-lib',而他们主要处理逻辑都在compile函数里,区分了模块。
notion image
这边用了tsc和babel解析了,所以我们需要对它们分别做source-map处理。
notion image

添加source-map配置

  1. 添加gulp-sourcemaps
这边下包可以下在ant-design这个目录,利用node_modules找包的向上规则,毕竟我们只做调试用,怎么方便怎么来~
  1. 添加配置
notion image
notion image
2.1. 添加初始化配置
2.2. 添加babel的sourceMap
2.3. 在写入文件前(dest)加入map文件
  1. 最后别忘了ts的sourceMap,ant-design/tsconfig.json中加入

打包试试

可以看到es和lib目录下都有map文件了
notion image

再看dist

这边简单说下dist源码映射的方案,毕竟我们项目90%都是使用的ESM的方式引用的。
同样的找到dist函数的位置,我们发现webpack配置文件是在项目根目录,根目录又指向了@ant-design/tools/lib/getWebpackConfig这个文件。
notion image
notion image
我们目标很明确就是改ts和babel嘛,直接去找loader!
notion image
果然是先经过了tsc处理后,之后babel进行转译。
notion image
添加sourceMap生成配置。我们刚刚改过tsconfig中的sourceMap,如果没改需要改下。
这边要注意下,我们通过import { Button } from 'antd'这种方式引入的是esm的写法,所以这边App.tsx要改下导入语句。

来看效果

重新打包生成es/dist文件夹。我们把es/dist项目中替换一下,顺便清理下vite中的缓存。(在node_modules下的.vite文件)
notion image
我们重新运行下项目发现,成了!
notion image
github源码:
notion image
现在你会发现你进入的断点代码和github上的一毛一样,什么es6语法、ts类型、注释全有了!

Pro Components

下载源码

观察打包命令

pro-components/package.json
notion image
pro-components是用lerna+pnpm维护的,我们来测试下packages/table组件。
安装好依赖之后,我们给table打个包。
  • 注意我们这边包名要去子包的package.json中看下name,并不是table。
notion image
我们发现依然是没有sourcemap的,不过所有的pro-components的包都是通过father构建的,这就很方便了。看下father配置~
notion image
用的是根路径的father配置,我们添加sourcemap=true。
notion image
这边我们只改ESM模块的,之后当然也别忘了开启@ant-design/pro-table中tsconfig的sourcemap。
改下@ant-design/pro-table的打包命令,删除刚刚的es文件夹。
重新运行,我们发现es中多出了map文件。
notion image

看效果

同样我们把构建产物移过去,清除下缓存,重新运行!
notion image
github源码:
notion image
这次不出意外的意外走丢了,完全一样!

总结

梳理下知识点:
  1. 建立调试环境
  1. 观察构建命令,得到构建方案
  1. 针对不同的构建方案,用不同的sourceMap映射,但总体不变的是babel+ts开启sourceMap
  1. 读懂gulp和lerna+pnpm的组织构建
工作中肯定是首先看文档和TS文件定义,但遇到问题或者好奇想深究的时候这肯定不够的。我们可以通过源码断点的形式去分析组件库的设计。后面我会和大家分享基于此方法的几个案例,希望大家持续关注!
绑定成功测试空白文章
NotionNext
NotionNext
一个普通的干饭人🍚
Announcement
🎉NotionNext 4.1已经上线🎉
-- 感谢您的支持 ---
👏欢迎更新体验👏