如果你有一个业务组件库,希望打包输出为 esm + cjs + dts,有什么思路?
打包成 ESM、CJS 和生成 TypeScript 的 .d.ts 类型声明文件,关键是合理配置构建工具。
我们可以选用 Rollup 或 Vite(底层也是用 Rollup),下面以使用 Vite 构建组件库 为例,讲讲如何配置输出 ESM + CJS + DTS:
一、初始化项目结构
假设目录结构是:
/src
Button/index.tsx
index.ts // 组件库入口
package.json
vite.config.ts
tsconfig.json二、Vite 配置打包输出
vite.config.ts 示例:
ts
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
import path from 'path';
export default defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, 'src/index.ts'), // 组件库入口
name: 'MyComponentLib',
formats: ['es', 'cjs'],
fileName: (format) => `my-component-lib.${format}.js`,
},
rollupOptions: {
external: ['react', 'react-dom'], // 避免打包这些外部依赖
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
},
},
plugins: [dts()],
});重点解释下配置细节:
formats: ['es', 'cjs']:表示输出两种格式。external: 保持react、react-dom是外部依赖(否则会被打进 bundle)。vite-plugin-dts:自动为库生成类型定义文件。
三、生成 .d.ts 类型文件
安装 vite-plugin-dts 插件:
bash
pnpm add vite-plugin-dts -D它会读取 tsconfig.json 并在打包时生成类型声明到 dist/ 目录。你也可以单独用 tsc 生成,但 vite-plugin-dts 更方便,支持合并等特性。
四、tsconfig.json 配置
json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"declaration": true,
"declarationDir": "dist/types",
"emitDeclarationOnly": true,
"jsx": "react-jsx",
"outDir": "dist",
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"strict": true
},
"include": ["src"]
}确保开启 declaration 和 emitDeclarationOnly,并设置好 include。
五、打包命令配置
在 package.json 中配置构建命令:
json
{
"main": "dist/my-component-lib.cjs.js",
"module": "dist/my-component-lib.es.js",
"types": "dist/types/index.d.ts",
"scripts": {
"build": "vite build"
}
}main是 CJS 的入口module是 ESM 的入口types指向类型声明文件
六、验证输出
执行:
bash
pnpm build会输出:
dist/my-component-lib.es.jsdist/my-component-lib.cjs.jsdist/types/index.d.ts
此时组件库即可支持多种模块加载方式和类型提示。
其他建议
- 如果库中包含样式文件(如
.scss),要通过插件或 Vite 自定义配置将样式打包或分离。 - 发布前可以通过
npm pack查看实际输出的文件内容。 - 如果考虑 tree-shaking,建议每个组件也单独导出,便于用户按需引入。
题目要点:
- 使用
vite.build搭配vite-plugin-dts可以同时输出 ESM、CJS 和.d.ts。 - 保持 React、Vue 等为 external 避免重复打包。
- 配置
package.json的main/module/types字段,清晰指向输出结果。 - 确保 tsconfig.json 中开启类型声明生成并指定输出路径。
- 实际打包后建议用真实项目验证加载和类型提示是否正常。