为什么create-react-app中的Babel不能正确地支持Array.prototype.at的polyfill?

6

我遇到了一个问题,发现这是因为Babel默认没有对.at进行polyfill。

根据规范,Array.prototype.at仅处于第4阶段,并且我已经将browserslist设置为 >0.2%,其中包括Chrome 86(尚未支持 .at)。

为什么Babel不对 .at 进行polyfill呢?

Babel Playground


1
Babel polyfill自Babel 7.4.0版本起已被弃用。我建议按照文档中的提示使用core-js。 - Dave Newton
@DaveNewton 感谢您提供的信息,但是即使我在我的 create-react-app 的入口文件的第一行添加了 'import from 'core-js/stable',[].at 仍然未定义。 - bbbbbbbboat
1个回答

3

大家好,我相信我找到了原因。

简而言之,CRA在babel中设置了错误的core-js版本配置。

我正在使用create-react-app构建我的Web应用程序,在安装core-js并将其导入入口文件后,我发现polyfill无法正常工作,根据官方文档

关键原因在于,这是CRA预先配置的babel配置,并且不易被用户修改,已将cors-js版本设置为3代码在这里

然而,Babel文档强烈推荐使用较小的版本,或者:

建议指定次要版本,否则“3”将被解释为“3.0”,这可能不包括最新功能的polyfills。

总之,无论我们安装哪个版本的corejs,它始终会使用带有3.0版本的polyfill规则,这会使某些功能的polyfills出错,例如Array.prototype.at;

有一些方法可以解决这个问题

如果您使用的是纯CRA,则必须执行此操作以将所有core-js导入到您的包结果中;

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;

如果你使用类似于react-app-rewired或craco这样的工具,你可以通过修正node_modules中的babel-preset-react-app代码,以更加优雅的方式实现此目标:

//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={
//...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接