Reputation: 2787
I got hit with below peculiar issue on promise polyfill that should be added by Babel's preset-env for browser compatibility.
I have a Foo.ts
file which uses the async/await
syntax to handle promises. After being processed by babel-loader
, bundled and started by Webpack dev server, the containing React web application runs successfully in Chrome, Safari, Edge(Mac) but fails in FireFox, IE11 and Edge(Windows).
The error looks like below, which is identified to be from the npm package @apollo/client
which Foo.ts
depends on. Does it indicate that the promise polyfill is missing?
TypeError: "this.fetchQuery(...).finally is not a function"
The Webpack config for babel-loader looks like below.
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'],
},
},
},
]
}
When the dev server starts, in the console output I am able to see below line that says the promise polyfill has been added to Foo.js
.
Added following core-js polyfills:
es.promise { "chrome":"45", "edge":"12", "firefox":"45", "ie":"11", "safari":"10.1" }
Hence I am confused how the problem could have occurred.
If I manually add import 'core-js/es/promise/finally';
to Foo.ts
, everything just works.
I am wondering what could be missing here and why that polyfill is not successfully added by babel-loader
.
The code portion in Foo.ts
that involves @apollo/client
looks like below. It's compiled to ES2015
target by tsc
before going through babel transformation.
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;
}
Env Info
Upvotes: 2
Views: 2125
Reputation: 2787
After further digging, I think the problem is caused by @babel/preset-env
not able to inject the correct es.promise
polyfill for Firefox. I tested with below config which isolates the target running environment to Firefox only. The issue is only observed for Firefox version set at 68 and lower.
targets: {
firefox: '68',
},
For now my workaround is:
@babel/preset-env
to purposely exclude es.promise
polyfill.exclude: ['es.promise'],
entry: ['core-js/es/promise', 'index.ts'],
Upvotes: 1