22 - 构建工具
构建工具
tsc(TypeScript Compiler)
TypeScript 自带的编译器,适合库开发和类型检查。
// tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true
},
"include": ["src/**/*"]
}
// package.json
{
"scripts": {
"build": "tsc",
"typecheck": "tsc --noEmit",
"watch": "tsc --watch"
}
}
| 优点 | 缺点 |
|---|
| 原生支持,无需额外依赖 | 编译速度慢 |
| 生成完整的类型声明 | 不支持打包 |
| 支持增量编译 | 不适合大型应用 |
esbuild
极快的 JavaScript/TypeScript 打包器:
基本配置
// build.ts
import esbuild from "esbuild";
await esbuild.build({
entryPoints: ["src/index.ts"],
bundle: true,
outdir: "dist",
platform: "node",
target: "node18",
format: "esm",
sourcemap: true,
minify: true,
splitting: true
});
package.json
{
"scripts": {
"build": "node build.ts",
"dev": "node build.ts --watch"
}
}
库打包
// build.ts
import esbuild from "esbuild";
await esbuild.build({
entryPoints: ["src/index.ts"],
bundle: true,
outdir: "dist",
platform: "neutral",
format: ["cjs", "esm"],
splitting: true,
sourcemap: true,
dts: true, // 生成 .d.ts(需要 esbuild-dts-plugin)
external: ["react", "react-dom"]
});
| 优点 | 缺点 |
|---|
| 极快的编译速度 | 不生成类型声明(需要额外插件) |
| 内置打包功能 | 不支持 TypeScript 类型检查 |
| 零配置使用 | 生态不如 webpack |
Vite
现代前端构建工具,开发环境使用 esbuild:
# 创建 Vite 项目
npm create vite@latest my-app -- --template react-ts
# 或手动安装
npm install -D vite @vitejs/plugin-react
配置
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src")
}
},
server: {
port: 3000,
proxy: {
"/api": "http://localhost:8080"
}
},
build: {
outDir: "dist",
sourcemap: true,
minify: "esbuild",
rollupOptions: {
output: {
manualChunks: {
vendor: ["react", "react-dom"],
router: ["react-router-dom"]
}
}
}
}
});
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src"]
}
| 优点 | 缺点 |
|---|
| 极快的开发服务器热更新 | 需要额外的类型检查 |
| 开箱即用的 TypeScript 支持 | 某些高级配置需要了解 Rollup |
| 内置优化(代码分割、Tree-shaking) | 大型项目可能需要调优 |
环境变量类型
// vite-env.d.ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string;
readonly VITE_APP_TITLE: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
Webpack
成熟的模块打包工具:
npm install -D webpack webpack-cli ts-loader typescript
配置
// webpack.config.ts
import path from "path";
import webpack from "webpack";
import HtmlWebpackPlugin from "html-webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
const config: webpack.Configuration = {
mode: process.env.NODE_ENV === "production" ? "production" : "development",
entry: "./src/index.tsx",
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].[contenthash].js",
clean: true
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
alias: {
"@": path.resolve(__dirname, "src")
}
},
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"]
},
{
test: /\.(png|svg|jpg|gif)$/,
type: "asset/resource"
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css"
})
],
optimization: {
splitChunks: {
chunks: "all"
}
}
};
export default config;
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "./dist",
"sourceMap": true,
"noEmit": true
},
"include": ["src"]
}
| 优点 | 缺点 |
|---|
| 极其灵活的配置 | 配置复杂 |
| 庞大的插件生态 | 构建速度较慢 |
| 成熟稳定 | 学习曲线陡峭 |
构建工具对比
| 特性 | tsc | esbuild | Vite | Webpack |
|---|
| 速度 | 慢 | 极快 | 快 | 慢 |
| 类型检查 | ✅ | ❌ | 插件 | 插件 |
| 打包 | ❌ | ✅ | ✅ | ✅ |
| 热更新 | ❌ | ❌ | ✅ | ✅ |
| 配置复杂度 | 低 | 低 | 中 | 高 |
| 适用场景 | 库 | 库/脚本 | 应用 | 应用 |
选择建议
| 项目类型 | 推荐工具 |
|---|
| npm 包/库 | tsc + esbuild |
| React/Vue 应用 | Vite |
| 大型企业应用 | Webpack(成熟生态) |
| 快速脚本/CLI | esbuild |
| Node.js 服务 | tsc 或 tsx |
业务场景:库开发的构建配置
// esbuild 库构建脚本
import esbuild from "esbuild";
import { execSync } from "child_process";
// 打包
await esbuild.build({
entryPoints: ["src/index.ts"],
bundle: true,
outdir: "dist",
platform: "neutral",
format: ["cjs", "esm"],
splitting: true,
sourcemap: true,
minify: true,
external: ["react", "react-dom"]
});
// 生成类型声明
execSync("tsc --emitDeclarationOnly --outDir dist");
console.log("Build complete!");
// package.json
{
"name": "my-library",
"version": "1.0.0",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
},
"require": {
"types": "./dist/index.d.ts",
"default": "./dist/index.cjs"
}
}
},
"files": ["dist"],
"scripts": {
"build": "node build.ts",
"typecheck": "tsc --noEmit"
}
}
注意事项
- Vite 和 esbuild 不做类型检查——需要单独运行
tsc --noEmit - 使用
isolatedModules: true——确保代码可以被单独转译 - 库开发生成
.d.ts——使用 tsc --emitDeclarationOnly - 代码分割——合理配置
manualChunks 优化加载性能 - Source Map——生产环境考虑是否需要 Source Map
扩展阅读