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
相关推荐
Irene19912 小时前
ElementPlus 与成熟后台框架对比:vue-element-plus-admin、vue-pure-admin等
前端·ui·框架·vue3
尘中客6 小时前
放弃 Echarts?前端直接渲染后端高精度 SVG 矢量图流的踩坑记录
前端·javascript·echarts·前端开发·svg矢量图·echarts避坑
FreeBuf_6 小时前
Chrome 0Day漏洞遭野外利用
前端·chrome
小彭努力中6 小时前
199.Vue3 + OpenLayers 实现:点击 / 拖动地图播放音频
前端·vue.js·音视频·openlayers·animate
2501_916007476 小时前
网站爬虫原理,基于浏览器点击行为还原可接口请求
前端·javascript·爬虫·ios·小程序·uni-app·iphone
前端大波7 小时前
Sentry 每日错误巡检自动化:设计思路与上手实战
前端·自动化·sentry
ZC跨境爬虫8 小时前
使用Claude Code开发校园交友平台前端UI全记录(含架构、坑点、登录逻辑及算法)
前端·ui·架构
慧一居士8 小时前
Vue项目中,何时使用布局、子组件嵌套、插槽 对应的使用场景,和完整的使用示例
前端·vue.js
Можно8 小时前
uni.request 和 axios 的区别?前端请求库全面对比
前端·uni-app
M ? A9 小时前
解决 VuReact 中 ESLint 规则冲突的完整指南
前端·react.js·前端框架