标准答案

  1. ESM 产物适合现代构建工具做静态分析和 Tree Shaking。
  2. CJS 产物用于兼容仍然依赖 require 的 Node 或旧工具链场景。
  3. 类型声明通常通过 tsc、vue-tsc 或 dts 插件输出 .d.ts。
  4. React、Vue 等宿主依赖通常放到 peerDependencies,并在打包时 external 掉。
  5. 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,导致组件样式在生产构建中被删除。

作者信息