前言
最近,在开发项目时使用到了 Top-level await 的用法,主要技术栈是 Vue 3.2.37
和 Vite 3.0.1
。
在本地开发的时候,项目运行都是很正常的,但是在部署上线之后。
出现了这样的报错:Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari13" + 2 overrides)
排错过程
因为这个问题是我第一次遇到,所以我就提出了几个可能的原因,然后逐一排查。
1. Node 版本问题
我本地运行环境为 nodejs v18
,但是线上部署为 nodejs v16
,于是我初步排查为 nodejs
版本的原因。我以为是 nodejs v16
不支持 Top-level await 的写法,于是我就打算用 Promise 代替 Top-level await 的写法。
但是,我使用 Promise 写法代替不成功,可能是我写法有问题吧,哈哈哈 🤣。
于是我就又思考了一下,这样绕开这个问题还是不行呀,还是需要去解决根本的问题 Top-level await 为什么不能运行成功。于是,我就去查了下资料,发现其实从 nodejs v14.8.0
就开始支持 Top-level await。
这样一来,我最初认为 Top-level await 报错是由于 Node 版本差异导致的设想就被推翻了。
2. 网上查资料
嘿嘿,我排除了 Node 版本的原因后,突然一下子就没有思路了,然后我又想到,这个报错信息这么明显:Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari13" + 2 overrides)
。
那我直接去网上查资料呀,所以我就直接把这么长的报错信息丢到搜索框中,发现报错信息太长,搜不到结果。
于是我就用 Top-level await is not available in the configured target environment
继续搜索,就发现了很多技术文章。我大概看了几篇后,他们都提到这个是 Vite 打包构建的问题,然后我就选定了其中一个方案后就开始在项目中验证了。
这一部分我写的挺碎碎念的,但是这个就是我在排查并解决这个问题的解决方式。
报错原因
Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari13" + 2 overrides)
,这个错误的原因是目标环境不支持 top-level await
。
top-level await
是某些特定的最新的浏览器才支持的,chrome87
、edge88
等就不支持,而且 Vite
默认打包时也不会进行转换,所以才会报这个错。
解决方案
1. 方案一
安装插件: vite-plugin-top-level-await
GitHub 地址:github.com/Menci/vite-…
安装命令:
npm:npm i -D vite-plugin-top-level-await
pnpm:pnpm add -D vite-plugin-top-level-await
yarn:yarn add -D vite-plugin-top-level-await
修改 vite.config.js
配置
import topLevelAwait from 'vite-plugin-top-level-await';
export default defineConfig({
plugins: [
topLevelAwait({
promiseExportName: '__tla',
promiseImportName: (i) => `__tla_${i}`,
}),
]
});
2. 方案二
直接修改 vite.config.js
的 build
配置
export default defineConfig({
build: {
target: 'esnext',
},
});
思考
这个问题发生的情况是,本地运行时可以正常运行,但是打包时报错。这个时候我应该马上意识到这是打包的问题,然后我使用的是 Vite 构建工具,此时应该想到是 Vite 打包构建的问题。
但是我最开始没有想到这个地方,我想到的是使用 Promise 的方式,去替换掉 top-level await 的用法,算是换一种方式解决。但是对于这样的问题,我应该第一时间想到问题产生的根本原因才行,这点我需要提高!
还是站在巨人的肩膀上方便,在网上查问题,确实能很快解决相关的一些问题,这个也是我自己写技术博客的一个原因,希望能帮助到其他遇到问题的开发者。
这个解决问题的过程,不仅让我解决了 Top-level await 的问题,同样也让我输出了一篇技术博客,这样子我的印象会更加深刻,在下次遇到这个问题时,就能够更快的解决问题了,真棒!
而且像这样子有明确报错信息的技术博客,最好尽量在标题中展示更多的报错信息,这样其他开发者在查询的时候会更加便捷,匹配度会更高。