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

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.

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)

How to transpile an npm dependency to es5 with babel and webpack?

I have to make our website compatible for internet explorer, and it’s quite tricky, as the browser doesn’t understand es6 (arrow functions and the like). I’ve been trying to upgrade webpack and tweak the webpack and babel config to fit our needs. This works great for our own source files, but doesn’t in the node_modules folder. The syntax is not IE compatible if we don’t include it in our babel transpiling, but it also fails if we do transpile the specific node_modules folder that fails (a dependency within the webpack-hot-middleware dependency), giving an error of Uncaught Error: ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead. I’m hoping I just have the wrong babel or webpack settings here, but I've been scraping the interwebz for answers for a while but haven't quite found the solution yet.
I'm using webpack 5 and babel-loader. I have a .babelrc and a webpack.config.js file, here is a snippet from the latter while I try to transpile the failing node_module package:
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: [
{
and: [/node_modules/],
not: [
path.resolve(
__dirname,
"node_modules/webpack-hot-middleware/node_modules/ansi-regex"
)
]
}
],
options: {
babelrc: false,
presets: [
"#babel/preset-react",
["#babel/preset-env", {
"corejs": { "version": 3 },
"useBuiltIns": "usage",
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1",
"ie": "10"
},
}]],
"plugins": [
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-proposal-optional-chaining",
"#babel/plugin-proposal-nullish-coalescing-operator",
"#babel/plugin-transform-arrow-functions"
]
}
},
[...]
]
}

How to inline Rollup/Babel polyfills for IE11

I've been working on a PHP project for a while and the client has asked for IE11 support at the last possible minute. HTML/CSS problems I can deal with but my javascript was written modern syntax.
So I install node, take my javascript, run it through Rollup & Babel the first time it's needed and cache the result for future requests.
Now the output lacks the arrow functions that were giving me a headache before but I've got a bigger problem: the polyfills are import statements and IE11 doesn't support import statements.
I feel like I need to emphasise that I'm not running a node server - it's a PHP server, I'm just using node on the backend for rollup & babel. If there's something that node does to make this work I'm not familiar with it.
Here's my rollup.config.js:
import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import minify from 'rollup-plugin-babel-minify';
export default {
input: '_dud_input.js', // These are set in the exec() call
output: {
file: '_dud_output.js', // These are set in the exec() call
format: 'iife',
strict : false
},
plugins: [
resolve({
browser: true
}),
commonjs({
sourceMap: false
}),
babel({
exclude: 'node_modules/**' // only transpile our source code
}),
minify({
"comments": false
})
]
};
And here's babel.config.js:
module.exports = {
"presets" : [
[
"#babel/preset-env",
{
"targets": {
"browsers": "> 0.5%, ie >= 11"
},
"modules": false,
"spec": true,
"useBuiltIns": "usage",
"forceAllTransforms": true,
"corejs": {
"version": 3,
"proposals": false
}
}
]
]
}
For giggles, here's the shell script I call to run the process:
#!/bin/bash
set -e
# Expected argument values:
# $1 - Path of the root directory
# $2 - Path of the node binary
# $3 - Path of the rollup binary
# $4 - Source file path
# $5 - Destination file path
if [ $# -ne 5 ]
then
exit 99
fi
ROOT_DIR=$1
NODE_BIN=$2
ROLLUP_BIN=$3
SRC_PATH=$4
DEST_PATH=$5
cd ${ROOT_DIR}
${NODE_BIN} ${ROLLUP_BIN} -c ${ROOT_DIR}/rollup.config.js -i ${SRC_PATH} -o ${DEST_PATH}
And it's linked like this:
<script defer="" type="text/javascript" src="http://example.com/site-asset/flatfile.js"></script>
With these settings, my flatfile.js outputs with the following at the top:
import"core-js/modules/es.symbol";
import"core-js/modules/es.symbol.description";
import"core-js/modules/es.symbol.iterator";
import"core-js/modules/es.array.concat";
import"core-js/modules/es.array.filter";
import"core-js/modules/es.array.find";
import"core-js/modules/es.array.for-each";
// ...etc...
Under this setup IE11's console says there's a Syntax error at the first line of every file with the import statements.
Changing useBuiltIns from usage to entry (which I understand means I'm expected to have an entry file elsewhere that adds the polyfills) and including https://polyfill.io/v3/ doesn't do anything (I get errors on Number.parseFloat() calls).
Out of desperation I even added a "core-js" route to my application, which tries to serve up the appropriate core-js file - but there's no indication that IE11 is even trying to follow the require statements.
Looking around the internet it seems like this isn't a problem for anybody else - IE11 apparently works for everybody else?
Maybe it's because I'm not using a node server, but a PHP/Apache one?
I just want the Babel to include the core-js polyfills in my files, not as require statements that IE11 doesn't know how to parse.
I had to disable the babel-minify plugin, but aside from that, copying your configuration seems to work just fine and I get a single bundled JavaScript file with no import statements.
The files are reproduced below, but the full test repo is available at https://github.com/akx/so58712204 – yarn; yarn build and look in dist/...
babel.config.js
module.exports = {
presets: [
[
"#babel/preset-env",
{
targets: {
browsers: "> 0.5%, ie >= 11"
},
modules: false,
spec: true,
useBuiltIns: "usage",
forceAllTransforms: true,
corejs: {
version: 3,
proposals: false
}
}
]
]
};
package.json
{
"scripts": {
"build": "rollup -c ./rollup.config.js -i ./src/entry.js -o ./dist/output.js"
},
"dependencies": {
"#babel/core": "^7.7.0",
"#babel/preset-env": "^7.7.0",
"core-js": "^3.3.6",
"rollup": "^1.26.3",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-babel-minify": "^9.1.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0"
}
}
rollup.config.js
import commonjs from "rollup-plugin-commonjs";
import resolve from "rollup-plugin-node-resolve";
import babel from "rollup-plugin-babel";
export default {
input: "_dud_input.js", // These are set in the exec() call
output: {
file: "_dud_output.js", // These are set in the exec() call
format: "iife",
strict: false
},
plugins: [
resolve({
browser: true
}),
commonjs({
sourceMap: false
}),
babel({
exclude: "node_modules/**" // only transpile our source code
})
]
};
src/entry.js
import { magicNumber } from "./magic";
console.log(new Set([Number.parseFloat(magicNumber)]));
src/magic.js
const magicNumber = "8.82";
export { magicNumber };

decoratorsBeforeExport Error when using electron-webpack dev

I was trying to convert my react project into an electron-app. As
the project is bundled via webpack, I began using electron-webpack for
the build. When running electron-webpack dev, neither the /main nor the /renderer compiles correctly.
Console logs throw Decorator plugin error
The decorators plugin requires a 'decoratorsBeforeExport' option,
whose value must be a boolean. If you want to use the
legacy decorators semantics, you can set the 'legacy: true' option
Sooo, why not following that wise suggestion?. Then, I updated all my dependencies and update my .babelrc file, for adding the decoratorsBeforeExport and the legacy option (false and true respectively)
"plugins": [
["#babel/plugin-proposal-decorators", {
"decoratorsBeforeExport": false,
"legacy": true,
}],
As the Error still showing after that, I open the plugin-proposal-decoratorsfolder from _/node_modules_ and added a log for the options. Apparently, it does not identify my options set. I tried
directly from the webpack loader config, but the problem still showing.
My env
Node: v11.2.0
Webpack: v4.29.0
#babel/core: v7.0.0
This .babelrc worked for me:
{
"presets": [
"#babel/preset-react",
[ "#babel/preset-env", {
"targets": {
"browsers": [ "last 1 version" ]
}
} ]
],
"plugins": [
"#babel/plugin-proposal-object-rest-spread",
["#babel/plugin-proposal-decorators", { "legacy": true }],
["#babel/plugin-proposal-class-properties", { "loose" : true }]
]
}
Mind how decorators plugin comes before class-properties.
Somehow, it didn't work for me in non-legacy mode. loose option is required if decorators runs in legacy mode, according to official docs: https://babeljs.io/docs/en/next/babel-plugin-proposal-decorators.html
It also states:
In Babel 7, transform-decorators-legacy will be the default plugin in Stage-0.
(Source: https://babeljs.io/docs/en/babel-plugin-transform-decorators.html)
More info:
Babel 7 - Decorators transform doesn't work with babel-loader
Simple ES7 decorator with babel

babel Promise polyfill not working with webpack modules: false

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?

Categories

Resources