babel Promise polyfill not working with webpack modules: false - javascript

Here is my .babelrc.
{
"presets": [
"react",
["env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 9"]
},
"useBuiltIns": true,
"modules": false
}]
],
"plugins": ["transform-object-rest-spread", "transform-class-properties"]
}
In my code I've included the polyfill module.
import 'babel-polyfill'
Running my app in IE11 results in the following error.
SCRIPT5009: 'Promise' is undefined
When I remove "modules": false everything works fine. I thought this option simply tells webpack not to transpile ES6 into ES5 modules which is required for treeshaking.
Why do the polyfills stop working?

Related

Babel support for Object.fromEntries

I am running a React web app inside React Native via WebView.
The website uses Object.fromEntries which doesn't appear to be available to the browswer on the device I am using and causes my webapp to crash (with no error) when I try call Object.fromEntries.
The device is running Android 8.1.0 so I assume it will be using an older Android browser that doesn't support Object.fromEntries.
In my web app babel config I am trying to target Android 8.0 but the app still crashes when Object.fromEntries gets called.
{
"presets": [
[
"#babel/preset-env",
{
"loose": true,
"modules": false,
"shippedProposals": true,
"targets": {
"Android": "8.0",
"browsers": ["last 2 version"]
}
}
],
[
"#babel/preset-react",
{
"useBuiltIns": true,
"pragma": "React.createElement"
}
],
"#babel/preset-typescript"
],
"plugins": [
[
"#babel/plugin-proposal-class-properties",
{
"loose": true
}
],
"#babel/plugin-syntax-dynamic-import",
"babel-plugin-macros",
[
"#babel/plugin-transform-runtime",
{
"helpers": true,
"regenerator": true
}
]
]
}
Is there something else I need to include in the babel config or perhaps something that overrides it (i.e. Typescript)?
I had a similar issue when loading a webpage in an Android 8 Chrome browser. These two changes helped fix it for me:
1. Manually adding polyfills
https://github.com/es-shims/Object.fromEntries
https://github.com/facebook/create-react-app/tree/main/packages/react-app-polyfill
Add your dependencies
yarn add react-app-polyfill
yarn add object.fromentries
Then, at the root of your app (index.js), add these two imports:
import 'react-app-polyfill/stable';
import fromEntries from 'object.fromentries';
fromEntries.shim(); // will be a no-op if not needed
2. Changing the build target
I'm using create-react-app and not directly configuring babel so this may be different for you, but I changed my browserslist setting to
">0.2%",
"not dead",
"not op_mini all"
(This may not be required at all)

preset-env and core-js don't seem to use browserslist

Using the official docs I've been trying to setup an optimal build config using: #babel/preset-env and core-js with a .browserslist file.
As far as I understand the docs, they say that preset-env with useBuiltins:"usage" will update the import 'core-js/stable' statement in my code, to only include the required functions.
However, no matter if I set last 1 chrome version or >1% in NL (which are considerably more and older browsers), the build file is the same size (about 3MB).
What am I missing?
I have a test repo available here: https://github.com/publicJorn/jorns-react-starter
For quick reference, the relevant files:
.babelrc
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": { "version": 3, "proposals": true }
}
],
"#babel/preset-react"
],
"plugins": [
[
"#babel/plugin-proposal-object-rest-spread",
{
"useBuiltIns": true
}
],
["#babel/plugin-proposal-class-properties"],
["#babel/plugin-syntax-dynamic-import"],
["babel-plugin-styled-components"]
]
}
webpack part
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader']
}
]
},
.browserslistrc
> 1% in NL
ie 11
not ie < 11
index.js
import 'core-js/stable'
// etc..
If propertie useBuiltIns was usage, core-js will bundle polyfill code what you are using in project.
If useBuiltIns was entry, it will bundle polyfill code by browserslist setting. don't forget import core-js manually.
import 'core-js/stable';
import 'regenerator-runtime/runtime';
Now, usage and entry are both bundle polyfill by browser setting above #babel/core>=7.18

babel without transpiling async await (no polyfill)

This is the error:
Uncaught ReferenceError: regeneratorRuntime is not defined
Every question I've found suggest to install a polyfill which will increase the bundle size.
Since I'm targeting latest Chrome, I want to use async/await as is. No polyfill. How to explain that to babel?
.babelrc:
{
"presets": [
[
"env",
{
"targets": {
"browsers": [
"last 2 versions",
"Chrome >= 59"
]
}
}
],
"react",
"stage-0"
]
}
using chrome > 59 did not work.
Your problem is
"last 2 versions"
which tells Babel to transpile (amongst others) for IE 10.

Set version of EcmaScript generated by Babel, in react app

I'm using the latest ES8 features in my react code, for example, async and await. Because of misconfiguration problem in my webpack config, I cannot use source maps, and this slows down debugging.
A quick solution could be to locally compile source code into ES7 or ES8, and test in the latest Chrome. How can I set this in .babelrc? Here's my current .babelrc:
{
"presets": [
"react-app"
]
}
Answered here,
{
"presets": [
"react",
["env", {
"targets": {
"chrome": 67
}
}]
]
}
As of Jul 2018, the above setting would not support spread operator in objects. To enable it,
npm install --save-dev babel-plugin-transform-object-rest-spread
Use the following configuration in .babelrc:
{
"presets": [
"react",
["env", {
"targets": {
"chrome": 67
}
}]
],
"plugins": ["transform-object-rest-spread"]
}

Consts still in bundle even though using babel env preset safari >= 7

I have a client that has employees working on older iPads and they can't update their safari versions to 10.x+ so they're stuck w/ safari 9.x. And I keep getting the following error when I try to load my browser app in Safari 9.x on an iPad:
SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode.
I'm using babel-loader in my webpack config and I have the following babel options that I'm setting on the loader's options property:
{
presets: [
[
"env",
{
targets: {
browsers: ["last 3 versions", "safari >= 8"]
},
debug: true
}
],
// `es2015`,
`stage-1`
],
retainLines: true,
plugins: [
"syntax-jsx",
"transform-react-jsx",
"transform-react-display-name",
"transform-react-require",
"transform-es2015-destructuring",
"transform-es2015-parameters",
"transform-object-rest-spread",
"transform-class-properties",
// "check-es2015-constants",
// "transform-es2015-block-scoping",
["transform-runtime", {
"polyfill": false,
"regenerator": true
}]
]
}
In my console when I do the build, it EVEN SAYS:
Using targets:
{
"chrome": "59",
"android": "4.4",
"edge": "13",
"firefox": "54",
"ie": "9",
"ios": "10",
"safari": "8"
}
And:
Using plugins:
check-es2015-constants {"android":"4.4","edge":"13","ie":"9","safari":"8"}
transform-es2015-block-scoping {"android":"4.4","edge":"13","ie":"9","safari":"8"}
But there are STILL const declarations (65 to be exact) throughout my bundle. And no, they aren't all node_module imports... Most are my own React component files.
How do I get babel to just replace ALL instances of const w/ var?
I'm on webpack 3.7.1 and babel-loader 7.1.2 and babel-core 6.26
Turns out I was using a Webpack alias for this project still: https://github.com/njl07/rx-http-request/issues/15#issue-273561398
Apparently babel transformations aren't applied to aliases for some reason.
Updated to the latest package and all is good now.

Categories

Resources