【问题标题】:Get rid of "regeneratorRuntime is not defined" without importing the polyfill在不导入 polyfill 的情况下摆脱“regeneratorRuntime is not defined”
【发布时间】:2019-10-15 00:01:17
【问题描述】:

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

我的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”的重要性在于它提供了更多的 polyfill。但是,添加这个

    useBuiltIns: "usage",
    corejs: 3
    

导致很多警告。然后,如果我像这样在rollup.conf.js 中添加排除项:

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

事情编译了,但结果不起作用(Uncaught SyntaxError: Cannot use import statement outside a module)。 如果我改为这样做:

    useBuiltIns: "entry",
    corejs: 3

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

【问题讨论】:

    标签: javascript babeljs rollup


    【解决方案1】:

    我看到了你打开的 Github issue 并链接到这篇文章。

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

    rollup-plugin-babel repo 上查看这个推荐的配置。

    我在使用 regeneratorRuntime is not defined 时遇到了同样的问题,无法弄清楚为什么 polyfill 没有按我希望/预期的方式加载。

    关键似乎是这个用例需要 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-12-03
      • 1970-01-01
      • 1970-01-01
      • 2020-03-10
      • 1970-01-01
      • 2021-10-18
      • 2021-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多