标准答案
- ESM 产物适合现代构建工具做静态分析和 Tree Shaking。
- CJS 产物用于兼容仍然依赖 require 的 Node 或旧工具链场景。
- 类型声明通常通过 tsc、vue-tsc 或 dts 插件输出 .d.ts。
- React、Vue 等宿主依赖通常放到 peerDependencies,并在打包时 external 掉。
- package.json 需要正确配置 exports、types、sideEffects,避免消费方解析到错误产物。
题目解析
组件库不是只把源码打成一个 JS 文件。消费方可能来自 Vite、Webpack、Node、SSR、测试环境,不同环境对模块格式和入口解析的期待不同。
类型声明是 TypeScript 用户的入口体验。如果 JS 产物能运行但 types 指向错误,使用方会在导入组件时失去类型提示,甚至无法通过类型检查。
样式和副作用要特别谨慎。组件样式可能需要保留 sideEffects,否则构建工具误以为 CSS 引入可以删除,最终组件逻辑还在,样式却丢了。
代码示例
组件库的 package.json 通常会明确暴露不同格式和类型入口。
JSON
{
"name": "@acme/ui",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"sideEffects": [
"**/*.css"
],
"peerDependencies": {
"vue": "^3.4.0"
}
}常见误区
- 把 Vue、React 等宿主框架打进组件库,导致使用方出现重复框架实例或体积膨胀。
- 只输出 JS,不输出或错误配置类型声明。
- 错误设置 sideEffects: false,导致组件样式在生产构建中被删除。