导航
| 工具 | 核心定位 | 主要优势 | 典型劣势 | 生态特点 |
|---|---|---|---|---|
| Webpack | 通用型打包器(老牌) | 功能强、插件丰富、兼容性好 | 配置复杂、编译慢 | 适合复杂前端应用(老项目、兼容IE) |
| Vite | 新一代前端构建工具 | 极快的开发启动速度、天然支持 ESM | 构建产物基于 Rollup,有时不够灵活 | 适合现代前端项目(Vue3、React、Svelte 等) |
| Rollup | 专注于库打包 | 输出简洁、高效 Tree Shaking | 开发体验较弱、不适合大项目 HMR | 专为打包库/工具设计 |
| Tsup | Rollup + esbuild 封装 | 极快构建速度、零配置、支持多格式 | 灵活度低,复杂场景下要自定义 | 适合 TypeScript 工具库、Node 包 |
| 场景 | 推荐工具 | 理由 | 推荐输出格式 | 备注 |
|---|---|---|---|---|
| Web 前端应用 | ✅ Vite | Dev server 极快,原生支持 HMR,生产构建走 Rollup | ESModule、Legacy | Vue3、React 应用的主流选择 |
| 老项目 | ✅ Webpack | 插件生态成熟,兼容旧环境 | UMD / IIFE | 仍是 Vue2 / jQuery / React 等 系项目主力 |
| 组件库 / UI 库 | ✅ Rollup → 或 Tsup(更轻) | 高效 Tree Shaking,灵活输出多格式 | ESM + CJS + 类型声明 | Rollup 可自定义复杂构建逻辑,Tsup 快速轻量 |
| 工具库(纯 TS/JS 工具函数) | ✅ Tsup | 极速打包,自动生成声明文件 | ESM + CJS | 比 Rollup 配置更简洁 |
| Node.js SDK / CLI 工具 | ✅ Tsup 或 esbuild | 编译快,支持动态 import、内置 watch | CJS + ESM | 最快构建 Node 库的方案 |
| Monorepo 子包(内部共享包) | ✅ Tsup | 支持多入口、简化 config | ESM + CJS | Turborepo/PNPM 常配合使用 |
| 低代码 / 无代码平台核心引擎 | ✅ Rollup | 控制打包输出粒度、保留模块边界 | ESM + DTS | 适合需要高定制与按需加载 |
| 第三方 SDK(需浏览器直引) | ✅ Rollup | 支持输出 UMD/IIFE 格式、体积小 | UMD + Min | 可直接 <script> 引入 |
无论用什么构建工具,打包配置都围绕这 4 个关键点:
| 配置项 | 含义 | 典型表现 |
|---|---|---|
| entry(入口) | 构建起点文件 | src/index.ts、src/main.ts |
| output(出口) | 产物输出路径与文件名 | dist/index.esm.js、dist/index.cjs.js |
| format(模块格式) | 输出包的模块类型 | esm、cjs、umd、iife |
| exports(导出字段) | package.json 中的模块分发定义 | "exports": { "import": "./dist/index.esm.js", "require": "./dist/index.cjs.js" } |
✅ 解释:
格式 主要面向 是否现代 一句话理解 ESM 现代浏览器 / 现代打包器 ✅ 最新 官方标准模块 CJS Node.js ⚠️ 老但仍主流 Node 的传统模块 UMD 浏览器 + Node 通吃 ⚠️ 过渡方案 “万能兼容包” IIFE 直接 <script> ⚠️ 最老 立即执行的全局脚本
无论使用哪种构建工具,建议统一 package.json 导出结构:
{
"name": "@your-scope/utils",
"version": "1.0.0",
"type": "module",
"main": "./dist/index.cjs.js", // CJS 入口
"module": "./dist/index.esm.js", // ESM 入口(旧生态)
"types": "./dist/index.d.ts", // 类型声明
"exports": {
".": {
"import": "./dist/index.esm.js",
"require": "./dist/index.cjs.js"
},
"./*": "./dist/*"
},
"files": ["dist"]
}
✅ 解释:
- exports 是 Node.js ESM 时代的官方推荐写法;
- 同时兼容旧版 bundler(通过 main / module);
- 保留 types 指向生成的 .d.ts 文件。
Tsup 是最推荐的子包打包工具:零配置、极速、支持多格式输出。
// tsup.config.ts
import { defineConfig } from 'tsup'
export default defineConfig({
entry: ['src/index.ts'], // 入口文件
outDir: 'dist', // 输出目录
format: ['esm', 'cjs'], // 输出格式
dts: true, // 生成类型声明文件
clean: true, // 清空 dist
sourcemap: true, // 可选:生成 sourcemap
splitting: false, // 对库一般不开 splitting
minify: false // 可选:工具库通常不压缩
})
👉 结果产物结构
dist/
├── index.esm.js
├── index.cjs.js
├── index.d.ts
✅ 适用于:
- TS 工具函数库
- Monorepo 子包(utils / hooks / api-sdk 等)
Rollup 控制力最强,适合需要多入口 / CSS 抽离 / Tree Shaking 的组件库。
// rollup.config.mjs
import typescript from '@rollup/plugin-typescript'
import dts from 'rollup-plugin-dts'
import vue from 'rollup-plugin-vue'
export default [
// JS 打包配置
{
input: 'src/index.ts',
output: [
{ file: 'dist/index.esm.js', format: 'es' },
{ file: 'dist/index.cjs.js', format: 'cjs' }
],
plugins: [
vue(), // 可选:组件库需要
typescript({ tsconfig: './tsconfig.json' })
],
external: ['vue', 'lodash-es'], // 避免打包外部依赖
},
// 类型声明打包
{
input: 'src/index.ts',
output: { file: 'dist/index.d.ts', format: 'es' },
plugins: [dts()]
}
]
👉 结果产物结构
dist/
├── index.esm.js
├── index.cjs.js
├── index.d.ts
✅ 可扩展为:
- 每个组件独立入口(input: { button: 'src/button/index.ts', ... })
- 支持 CSS 分离、tree shaking、按需导入
Vite 内部构建基于 Rollup,可用于库打包模式:
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
build: {
lib: {
entry: 'src/index.ts',
name: 'MyUILib',
fileName: (format) => `index.${format}.js`,
formats: ['es', 'cjs']
},
rollupOptions: {
external: ['vue'], // 避免打包 vue
}
}
})
✅ 输出结构同样为:
dist/
├── index.es.js
├── index.cjs.js
适合「临时发布的小型组件包」或「内部 UI 库」。
// webpack.config.js
const path = require('path')
module.exports = {
mode: 'production',
entry: './src/index.ts',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.cjs.js',
library: { type: 'commonjs2' } // 输出为 CJS 模块
},
resolve: { extensions: ['.ts', '.js'] },
module: {
rules: [{ test: /\\.ts$/, use: 'ts-loader' }]
}
}
✅ 可通过 output.library.type 切换:
- 'module' → ESM
- 'commonjs2' → CJS
- 'umd' → 通用包
packages/
├── components/ # UI 组件库
│ ├── rollup.config.mjs
│ ├── package.json
│ └── src/
├── utils/ # 工具函数库
│ ├── tsup.config.ts
│ ├── package.json
│ └── src/
├── hooks/ # 复用 Hooks
│ ├── tsup.config.ts
│ └── src/
└── playground/ # 测试场景
├── vite.config.ts
└── src/
统一规范