TypeScript 和构建工具(Vite、Webpack等)中构建目标详解

在前端项目中,常常会在 TypeScript、Vite、Webpack、Babel 等工具中看到类似如下配置项:

json 复制代码
"target": "es2020"

这些配置中的 "es5""es6""es2020""esnext" 是 ECMAScript 的不同版本标识,决定了构建产物所使用的语法标准。本篇文章将系统梳理这些标准的区别,并深入讲解:

  • 各版本的差异
  • tsconfig.json 中的 target 与构建工具中 target 的关系
  • 如何配置 polyfill 以支持旧浏览器

各版本 ECMAScript 的语法差异

构建目标 等价标准 发布年份 主要新特性
es5 ECMAScript 5 2009 严格模式、getter/setter、Array 方法如 forEachmap
es6es2015 ECMAScript 6 2015 let/const、箭头函数、模块导入导出、Promise、类、解构
es2016 ECMAScript 7 2016 Array.prototype.includes、指数运算符 **
es2017 ECMAScript 8 2017 async/awaitObject.entries/values
es2018 ECMAScript 9 2018 异步迭代器、命名捕获组、Promise.finally
es2019 ECMAScript 10 2019 flatMap、可选 catch 参数、Object.fromEntries
es2020 ECMAScript 11 2020 可选链 ?.、空值合并 ??BigIntPromise.allSettled
es2021 ECMAScript 12 2021 逻辑赋值运算符、字符串 replaceAllWeakRef
es2022 ECMAScript 13 2022 类字段、顶级 await、.at() 方法
esnext 最新提案 -- 表示"构建时支持的最新语法",可能包含实验特性

TypeScript tsconfig.json 中的 target

json 复制代码
{
  "compilerOptions": {
    "target": "es2020"
  }
}

target 控制 TypeScript 输出的 JavaScript 使用的 语法级别

  • ✅ 是否保留 async/await
  • ✅ 是否保留箭头函数
  • ✅ 是否使用模块语法 import/export
  • ❌ 不影响内置 API,如 Promise.allSettled 是否存在(需另加 polyfill)

构建工具中的 target(Vite、esbuild、Webpack)

Vite / esbuild 示例

ts 复制代码
export default defineConfig({
  build: {
    target: 'es2020'
  }
})
  • 控制构建产物保留的语法,如 ?.??import.meta
  • 不会自动插入 polyfill(如 Promise.allSettledBigInt

Webpack + Babel 示例

js 复制代码
presets: [
  ['@babel/preset-env', {
    targets: '> 0.25%, not dead',
    useBuiltIns: 'usage',
    corejs: 3
  }]
]
  • Babel 会根据目标环境:
    • 降级语法
    • 自动插入 polyfill(结合 core-js

TypeScript target 与构建工具 target 的关系

项目 TypeScript target 构建工具 target
控制语法降级 ✅ 是 ✅ 是
控制 API 支持 ❌ 否 ❌ 否(需 polyfill)
控制代码压缩语法 ❌ 否 ✅ 是(如 Terser)
控制 tree-shaking ❌ 否 ✅ 是(现代语法更利于优化)

推荐配置建议

TypeScript 的 target 不要高于构建工具的 target

否则可能出现:

  • 构建工具无法解析新语法,导致构建失败或运行时报错。
  • esbuild 不会再对降级后的语法进行优化,导致文件体积变大。
场景 tsconfig.json 中 target 构建工具中 target
兼容 IE11 es5 es5
支持现代浏览器 es2020 es2020
Electron/Node.js 环境 es2022 es2022
尽可能现代(实验) esnext esnext

Vite 和 esbuild 中如何引入 polyfill?

构建工具默认不插入 polyfill

Vite 使用 esbuild,只负责语法转换,不会自动处理以下情况:

js 复制代码
Promise.allSettled([...]);
Object.fromEntries(...);
BigInt(123);

方法一:手动引入 core-js polyfill(推荐)

ts 复制代码
// main.ts
import 'core-js/features/promise/all-settled';
import 'core-js/features/object/from-entries';
import 'core-js/features/array/flat-map';

适用于只 polyfill 项目实际用到的部分,构建体积更小、控制更精细

方法二:通过 Babel 插入 polyfill(兼容性优先)

json 复制代码
// babel.config.json
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ]
}

并在 vite.config.ts 中接入 Babel 插件:

ts 复制代码
import legacy from '@vitejs/plugin-legacy';

export default defineConfig({
  plugins: [
    legacy({
      targets: ['defaults', 'not IE 11']
    })
  ]
});

方法三:使用 polyfill.io CDN(公网项目)

html 复制代码
<script src="https://polyfill.io/v3/polyfill.min.js?features=default,Promise.allSettled"></script>

特点:

  • 根据浏览器 User-Agent 自动加载缺失的 polyfill
  • 不适用于内网、Electron、App 内嵌 WebView 等场景

polyfill 方案对比总结

方法 优点 缺点 适用场景
手动引入 core-js 控制精细、体积小 需手动维护 大多数项目
Babel 插入 polyfill 自动处理、完整兼容 构建慢、体积大 兼容性要求高的公共项目
polyfill.io CDN 动态按需加载 依赖网络、不适合私有部署 对公网用户兼容老设备

总结

  • target 配置决定构建产物所使用的 JS 语法版本。
  • tsconfig.jsontarget 控制 TypeScript 输出的语法;构建工具(Vite/Webpack)的 target 控制最终产物保留哪些语法。
  • 若需要兼容低版本浏览器,还需手动或通过 Babel 插入 polyfill。
  • 建议保持 TypeScript 的 target ≤ 构建工具的 target
  • 在现代浏览器为主的项目中,推荐设置为 es2020
相关推荐
一 乐6 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
C_心欲无痕6 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
清沫6 小时前
Claude Skills:Agent 能力扩展的新范式
前端·ai编程
yinuo7 小时前
前端跨页面通信终极指南:方案拆解、对比分析
前端
yinuo7 小时前
前端跨页面通讯终极指南⑨:IndexedDB 用法全解析
前端
xkxnq8 小时前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js
烛阴8 小时前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js
xkxnq8 小时前
第一阶段:Vue 基础入门(第 15天)
前端·javascript·vue.js
anyup10 小时前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos
BBBBBAAAAAi10 小时前
Claude Code安装记录
开发语言·前端·javascript