javascript - 摆脱 "regeneratorRuntime is not defined"而不导入 polyfill

标签 javascript babeljs rollup

我编写了一个元素库,并希望确保设计人员只需将正确的源文件添加到他们的 HTML 页面即可开始使用它。 我正在使用 rollup (将其汇总到一个文件)和 babel (以确保任何浏览器都可以使用它)创建一个 bundle 。

我的rollup.conf非常简单:

import resolve from 'rollup-plugin-node-resolve'
import babel from 'rollup-plugin-babel'
import minify from 'rollup-plugin-babel-minify'

module.exports = [

  // IIFE
  {
    input: './tpe.js',
    output: {
      file: 'distr/tpe.js', // IIFE ONE FILE
      format: 'iife'
    },
    plugins: [resolve({}), babel({})]
  },

  {
    input: './themes/material/material.js',
    output: {
      file: 'distr/material.js', // IIFE ONE FILE
      format: 'iife'
    },
    plugins: [resolve({}), minify({})]
  }
]

请注意,./tpe.js 包含一长串导入:

import './ee-autocomplete-input-spans.js'
import './ee-autocomplete-item-country.js'
import './ee-autocomplete-item-email.js'
import './ee-autocomplete-item-li.js'
import './ee-autocomplete.js'
import './ee-drawer.js'
import './ee-fab.js'
import './ee-header.js'
import './ee-nav-bar.js'
import './ee-network.js'
import './ee-snack-bar.js'
import './ee-tabs.js'
...

我的 babel.conf.js 更简单:

module.exports = function (api) {
  api.cache(true)

  const presets = [
    [
      '@babel/env', {
        modules: false,
        exclude: [],
        targets: {
          ie: "9"
        }
      }
    ]
  ]
  const plugins = []

  return {
    presets,
    plugins
  }

这一切都很好,除了我必须要求我的用户这样做:

<script src="https://unpkg.com/@babel/polyfill/dist/polyfill.min.js"></script>
<script src="./distr/material.js"></script>
<script src="./distr/tpe.js"></script>

<nn-input-text id="input" name="aName"></nn-input-text>

如果没有那个polyfill.min.js,我就会得到可怕的regeneratorRuntime is not Defined

我花了很多时间试图确保我不需要要求用户拥有该 polyfill.min.js

为了“解决”这个问题,我将其添加到我的 ./tpe.js 中:

import 'regenerator-runtime/runtime'
import './ee-autocomplete-input-spans.js'
import './ee-autocomplete-item-country.js'
import './ee-autocomplete-item-email.js'
import './ee-autocomplete-item-li.js'

这实际上让我可以拥有这个:

<script src="./distr/material.js"></script>
<script src="./distr/tpe.js"></script>

<nn-input-text id="input" name="aName"></nn-input-text>

问题:

  • Babel 正在编译 node_modules 中的内容,在我的例子中,它正是 lit-html 和 lit-element (都是 ES6 源代码)。我一开始遇到了问题,lit-element(在node_modules中)无法编译。然而,问题消失了,我不知道如何/为什么。

  • regenerator-runtime/runtime 是我唯一需要填充的东西吗?毕竟我的目标是 IE9...

  • 是否有更好的方法来添加 regenerator-runtime/runtime 而无需将其包含在 tpe.js 中?

  • 我读到“corejs”很重要,因为它提供了更多的填充。但是,添加这个

    useBuiltIns: "usage",
    corejs: 3
    

导致大量警告。然后,如果我在 rollup.conf.js 中添加排除,如下所示:

plugins: [resolve({}), babel({exclude: [/\/core-js\//]}), minify({})]

编译成功,但结果不起作用(未捕获的语法错误:无法在模块外部使用 import 语句)。 如果我这样做:

    useBuiltIns: "entry",
    corejs: 3

我不需要“排除”,但它似乎没有做任何事情。 我实际上需要 corejs polyfills 吗?

最佳答案

我看到了您打开的 Github 问题并链接到这篇文章。

我也一直在尝试诊断此设置以及我在尝试配置它时遇到的问题。

rollup-plugin-babel 上查看此推荐配置 repo 协议(protocol)。

我遇到了与regeneratorRuntime is not Defined相同的问题,并且无法弄清楚为什么polyfills没有按照我希望/预期的方式加载。

关键似乎是这个用例需要 3 个插件。

// We need all 3 of these to end up with the 'usage'-based babel polyfills

import babel from "rollup-plugin-babel";
import commonjs from "rollup-plugin-commonjs";
import resolve from "rollup-plugin-node-resolve";

export default [
  {
    input: "src/index.js",
    output: {
      file: "dist/index.js",
      format: "iife"
    },
    plugins: [
      resolve(),
      babel({
        exclude: "node_modules/**",
        presets: [
          [
            "@babel/preset-env",
            {
              corejs: 3,
              modules: false,
              useBuiltIns: "usage",
              targets: {
                ie: "11"
              }
            }
          ]
        ]
      }),
      commonjs()
    ]
  }
];

这是我对 package.json 的依赖:

  "scripts": {
    "start": "rollup -c --compact --watch"
  }
  "dependencies": {
    "core-js": "^3.3.4",
    "regenerator-runtime": "^0.13.3"
  },
  "devDependencies": {
    "@babel/core": "^7.6.4",
    "@babel/preset-env": "^7.6.3",
    "rollup": "^1.26.0",
    "rollup-plugin-babel": "^4.3.3",
    "rollup-plugin-commonjs": "^10.1.0",
    "rollup-plugin-node-resolve": "^5.2.0",
  }

我的输出 dist/index.js 最终包含了 regeneratorRuntime 的分配,在我拥有上述所有 3 个汇总插件之前,该分配是不存在的:

try {
  regeneratorRuntime = runtime;
} catch (accidentalStrictMode) {
  // This module should not be running in strict mode, so the above
  // assignment should always work unless something is misconfigured. Just
  // in case runtime.js accidentally runs in strict mode, we can escape
  // strict mode using a global Function call. This could conceivably fail
  // if a Content Security Policy forbids using Function, but in that case
  // the proper solution is to fix the accidental strict mode problem. If
  // you've misconfigured your bundler to force strict mode and applied a
  // CSP to forbid Function, and you're not willing to fix either of those
  // problems, please detail your unique predicament in a GitHub issue.
  Function("r", "regeneratorRuntime = r")(runtime);
}

关于javascript - 摆脱 "regeneratorRuntime is not defined"而不导入 polyfill,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58385471/

相关文章:

javascript - res.render 错误,函数未定义

babeljs - `@babel/runtime` 和 `@babel/plugin-transform-runtime` 版本

react-native - 捆绑失败 : TypeError: Cannot read property 'bindings' of null at Scope. moveBindingTo

reactjs - 当我从样式组件使用我自己的库时出现无效的钩子(Hook)调用错误

javascript - 使用 Babel 和 Rollup 转译 startsWith() 时出现问题

javascript - getBoundingClientRect 检测可见性

javascript - Google 跟踪代码管理器多次加载 Analytics.js

MySQL 只获取整体 ROLLUP

javascript - 用 css 居中 html 内容

reactjs - 使用 webpack 和 babel 时,当前未启用对实验性语法 'jsx' 的支持