问题描述
我遇到了关于Promfill的以下特殊问题,该问题应该由Babel的预置环境添加,以实现浏览器兼容性。
我有一个Foo.ts
文件,该文件使用async/await
语法来处理promise。由babel-loader
处理,由Webpack开发服务器捆绑并启动后,包含的React Web应用程序在Chrome,Safari,Edge(Mac)中成功运行,但在FireFox,IE11和Edge(Windows)中失败。
错误如下所示,该错误来自@apollo/client
所依赖的npm软件包Foo.ts
。它是否表明没有应允polyfill?
TypeError: "this.fetchQuery(...).finally is not a function"
babel-loader的Webpack配置如下所示。
module: {
rules: [
{
test: /\.(jsx?|tsx?)$/,exclude: /node_modules\/.*/,use: {
loader: 'babel-loader',options: {
presets: [
'@babel/preset-react','@babel/preset-typescript',[
'@babel/preset-env',{
useBuiltIns: 'usage',corejs: '3.6',debug: true,},],plugins: ['react-hot-loader/babel'],]
}
开发服务器启动时,在控制台输出中,我可以看到下面的一行显示诺言polyfill已添加到Foo.js
。
Added following core-js polyfills:
es.promise { "chrome":"45","edge":"12","firefox":"45","ie":"11","safari":"10.1" }
因此,我很困惑该问题是怎么发生的。
如果我将import 'core-js/es/promise/finally';
手动添加到Foo.ts
,则一切正常。
我想知道这里可能缺少什么,为什么babel-loader
无法成功添加该polyfill。
Foo.ts
中涉及@apollo/client
的代码部分如下所示。在进行babel转换之前,它已由ES2015
编译为tsc
目标。
try {
const response: ApolloQueryResult<QueryType> = await this.apolloClient.query(
{
query,fetchPolicy: 'no-cache',errorPolicy: 'all',variables,);
return response.data;
} catch (e) {
console.error(e);
throw e;
}
环境信息
- Firefox:68.8.0esr
- @ babel / preset-env:7.9.5
- core-js:3.6.5
- Webpack:4.29.6
- babel-loader:8.0.5
解决方法
进一步研究之后,我认为问题是由@babel/preset-env
无法为Firefox注入正确的es.promise
polyfill引起的。我使用下面的配置进行了测试,该配置将目标运行环境仅隔离到Firefox。仅对于设置为68及更低版本的Firefox版本才观察到该问题。
targets: {
firefox: '68',},
目前,我的解决方法是:
- 配置
@babel/preset-env
以故意排除es.promise
填充。
exclude: ['es.promise'],
- 通过Webpack的入口点配置添加它,因为仍然需要它。
entry: ['core-js/es/promise','index.ts'],