强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

TypeScript 开发指南 / 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 打包器:

npm install -D esbuild

基本配置

// 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"]
}
优点缺点
极其灵活的配置配置复杂
庞大的插件生态构建速度较慢
成熟稳定学习曲线陡峭

构建工具对比

特性tscesbuildViteWebpack
速度极快
类型检查插件插件
打包
热更新
配置复杂度
适用场景库/脚本应用应用

选择建议

项目类型推荐工具
npm 包/库tsc + esbuild
React/Vue 应用Vite
大型企业应用Webpack(成熟生态)
快速脚本/CLIesbuild
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"
  }
}

注意事项

  1. Vite 和 esbuild 不做类型检查——需要单独运行 tsc --noEmit
  2. 使用 isolatedModules: true——确保代码可以被单独转译
  3. 库开发生成 .d.ts——使用 tsc --emitDeclarationOnly
  4. 代码分割——合理配置 manualChunks 优化加载性能
  5. Source Map——生产环境考虑是否需要 Source Map

扩展阅读