如何重新导出 antd


因为种种原因,你可能想要将 antd 组件从另一个模块中重新导出,但是这么做并没有像看上去那么简单。

导出类型

重新导出 antd 的类型可能是整个需求中最简单的部分,因为我们只需要简单的使用 export type { xxx } from 'antd' 就行了。

首先我们需要使用 require.resolve 获取 antd 的安装路径,然后用正则表达式解析一下 antd/index.d.ts 的内容,其中以 export type 开头的就是 antd 导出的类型。获取到这些类型名称后,就可以生成代码,在我们自己的模块中重新导出。

导出组件

与类型信息不同,想要重新导出组件还需要考虑支持「按需引用」功能。虽然目前的 antd 文档中写着 JS 组件默认支持基于 ESM 按需引用功能,但是组件对应的样式依赖 babel-plugin-import 实现按需引用。

然而, babel-plugin-import 并不支持 export { xxx } from 'antd' 的语法,它甚至会报错

考虑到 babel-plugin-import 目前并没有人在积极地维护,而且我个人也比较讨厌这种依赖 babel 魔改代码的手段,我决定迂回地解决这个问题——先导入,再导出。

使用简单的 import 语句让 babel-plugin-import 正常地工作,然后再将导入的变量重新 export 出去。不过这里涉及到一个问题,如果我在同一个文件中将 antd 所有的组件全部导入的话,由于 babel-plugin-import 的原因,所有组件的样式将在加载这个文件的时候被加载。这样就破坏了按需加载的特性。

为了避免上述问题,我们得把 babel-plugin-import 的副作用隔离到独立的模块中,以 Button 组件为例:

import { Button as _Button } from 'antd';

export const Button: typeof _Button = _Button;
export * from './lib/button';

如此一来, index.ts 就完全变成用来按需引用子模块的入口,在加载 index.ts 的时候就不会加载所有组件的样式了。

除此之外,你可能还发现了我在导出组件的时候特意标注了变量的类型,这是因为 TypeScript 要求我们给导出的变量类型起一个稳定的名字,否则编译会报错。


发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

You can use markdown syntax in comment