await 本身不会被单独降级,而是 async/await 整体被编译为 Promise 链或 generator 形式:esbuild 在 target 为 ES2015+ 时保留原语法,Babel 在 ES5 目标下转为 .then() 链或 regenerator-runtime 包装的 generator;降级由编译器(Babel/esbuild)根据 target 或 browserslist 配置决定,打包工具仅集成执行。

await 本身不会被降级转译,而是由 async/await 语法整体被编译为 Promise 链或生成器(generator)形式的兼容代码。 打包工具如 Vite 或 Webpack 本身不直接处理语法降级,真正起作用的是它们集成的 JavaScript 编译器(通常是 Babel 或 esbuild),而降级目标由项目配置的 target(Vite)或 browserslist(Webpack + Babel)决定。
降级依赖编译器而非打包工具
Vite 默认使用 esbuild 进行快速构建和 minify,它支持现代语法但不降级(即默认输出 ES2015+)。若需兼容旧浏览器(如 IE11 或早期 Android WebView),必须显式启用降级:
- Vite 中通过
build.target配置(例如"es2015"),触发 esbuild 的降级能力(esbuild 仅支持降到 ES2015,且对 async/await 会转成基于Promise的结构,不生成 generator) - 更深度的降级(如到 ES5、支持 IE)需搭配 Babel:Vite 可通过
@vitejs/plugin-react-swc(SWC)或@vitejs/plugin-react(含 Babel)实现;Webpack 则通常用@babel/preset-env+browserslist
async/await 被转成什么?
以一段典型代码为例:
async function fetchUser() {
const res = await fetch('/api/user');
return res.json();
}
在目标设为 ES2015 时(esbuild):
- 保留
async/await关键字(因 ES2015 已支持) - 不转换——因为 ES2015 规范已原生定义了 async function 和 await 行为
在目标设为 ES5 时(Babel + preset-env):
- 整个函数被重写为返回
Promise的普通函数 -
await被展开为.then()链,可能嵌套多层回调 - 若启用
regeneratorRuntime(需引入core-js或regenerator-runtime),则可能转为function*+runtime.mark+runtime.wrap的 generator 形式
关键配置项对照
常见降级配置位置:
-
Vite:
vite.config.js中build: { target: 'es2015' };如需 Babel,安装@babel/core和@vitejs/plugin-react并启用 -
Webpack:在
.babelrc或babel.config.js中设置preset-env,并声明"targets": { "ie": "11" };同时确保core-js/stable和regenerator-runtime/runtime被正确 import -
注意 polyfill:即使语法被转译,
Promise、fetch、Array.from等运行时 API 仍需手动 polyfill(如通过core-js)
如何验证是否生效?
最直接方式是查看产物代码:
- 构建后打开
dist目录下的 JS 文件,搜索async或await—— 若仍存在,说明未降级或目标版本过高 - 若看到
Promise.resolve().then(...)嵌套或runtime.async字样,说明已启用 regenerator 转译 - 使用
npm run build -- --debug(Vite)或 source map 查看原始与输出映射关系
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











