I came across an issue and found out its because Babel does not polyfill .at
as default
According to spec , Array.prototype.at is merely stage 4, and I already set browserslist to > 0.2%, which includes Chrome 86(not supported .at yet)
Why on the earth Babel doest not polyfill .at ?
Hey guys I believe I've fond the reason;
TLDR, the CRA is setting the wrong core-js version config for babel
I'm using create-react-app to build my web app, where I fond polyfill not work properly after installing core-js and import in entry file, according to officail doc;
And the key reason is in babel-preset-react-app
, the babel config which CRA pre-configured and not easily modifiyed by users, have set 3
for cors-js version;
code is here
Whereas, the Babel doc has strongly recommanded to use minor verision , Or :
It is recommended to specify the minor version otherwise "3" will be interpreted as "3.0" which may not include polyfills for the latest features.
And in conculsion, no matter what version of corejs we installed, it always use polyfill rule with 3.0
version , which would make mistake for some feature polyfills, like Array.prototype.at
;
And there is some method to resolve this problem
if u are using pure CRA, u have to do this to import all core-js into your bundle result;
import R from "core-js/stable";
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
// eslint-disable-next-line no-unused-expressions
R;
if u work with anything like react-app-rewired or craco, u can achieve this by a more elegant way by correcting the babel-preset-react-app
code in your node_modules:
//resolve-core-js.js
const path = require("path");
const fs = require("fs");
const setBabelPresetConfig = (version = "3.24") => {
console.info(
`[cra-core-js-resolve] try set core-js to ${version} in babel-preset-react-app`
);
try {
const babelRuntimeEntry = require.resolve("babel-preset-react-app");
const babelPresetCreateAppCreate = path.resolve(
babelRuntimeEntry,
"../create.js"
);
const content = fs.readFileSync(babelPresetCreateAppCreate, {
encoding: "utf-8",
});
const template = "corejs: 3,";
if (!content.includes(template)) {
console.info("[cra-core-js-resolve] template not fond, do nothing");
return;
}
const replacedContent = content.replace(
"corejs: 3,",
`corejs: ${version},`
);
fs.writeFileSync(babelPresetCreateAppCreate, replacedContent);
if (require.cache["babel-preset-react-app"]) {
delete require.cache["babel-preset-react-app"];
}
console.info(`[cra-core-js-resolve] set core-js to ${version} .done`);
} catch (e) {
if (e.code === "MODULE_NOT_FOUND") {
console.info(
"[cra-core-js-resolve] babel-preset-react-app not fond, do nothing"
);
return;
}
console.error(
"[cra-core-js-resolve] error happened when set babel-preset-react-app "
);
console.error(e);
}
};
module.exports = setBabelPresetConfig;
//craco.config.js
const resolveCoreJs = require('/path/to/resolve-core-js.js')
resolveCoreJs()
module.exports={
//...
}