ReferenceError:未定义regeneratorRuntime(但在作用域内工作)

Mar*_*tus 21 javascript generator babeljs

我遇到过这种奇怪的事情:

ReferenceError: regeneratorRuntime is not defined

...我设法在一个非常小的环境中重现(与同一问题上类似的SO问题相比),并且还注意到一些奇怪的行为取决于是否使用了范围.

以下代码有效:

'use strict';

require('babel-polyfill');

{  // scope A (if you remove it you observe different behavior when .babelrc is present)

    function *simplestIterator() {
        yield 42;
    }

    for (let v of simplestIterator()) {
        console.log(v);
    }

}
Run Code Online (Sandbox Code Playgroud)

包裹是:

$ npm ls --depth 0
simple-babel-serverside-node-only-archetype@1.0.0 /home/mperdikeas/regeneratorRuntimeNotDefined
??? babel-cli@6.7.5
??? babel-core@6.7.6
??? babel-polyfill@6.7.4
??? babel-preset-es2016@6.0.11
??? babel-runtime@6.6.1
Run Code Online (Sandbox Code Playgroud)

内容.babelrc是:

$ cat .babelrc 
{
    "presets": ["es2016"]
}
Run Code Online (Sandbox Code Playgroud)

但是,当移除范围并将其simplestIterator置于全局范围时,它将失败并显示:

ReferenceError: regeneratorRuntime is not defined
Run Code Online (Sandbox Code Playgroud)

更奇怪的是,如果.babelrc删除/重命名文件,则无论范围是否存在,代码都会成功.BTW无论是范围还是封装发电机的IIFE都没有区别.

最小的github repo 在这里展示了这种行为.

观察行为:

git clone https://github.com/mperdikeas/regeneratorRuntimeNotDefined.git
cd regeneratorRuntimeNotDefined/
npm install
npm run build && npm run start
Run Code Online (Sandbox Code Playgroud)

以上将42在控制台上输出.现在删除范围,看看会发生什么.然后重命名.babelrc以使其再次工作(有或没有范围).

我的问题是:

  • 为什么es2016Babel预设会触发此错误
  • 为什么将发电机放在一个范围内解决了这个问题?

更新

基于接受的答案,因为这是我写的模块的代码,我最终做了:

require('babel-polyfill');
module.exports = require('./app.js');
Run Code Online (Sandbox Code Playgroud)

log*_*yth 47

Babel假定polyfill将在应用程序中的任何其他内容之前加载,但是您正在使用一个函数声明,该声明被挂起,这意味着它在调用之前 存在并且可用require.

在发电机的情况下,则需要regeneratorRuntime由填充物提供,但是在再生器初始化时未填充聚合物填充物.

Babel团队的建议是制作两个文件:

index.js

require('babel-polyfill');
require('./app');
Run Code Online (Sandbox Code Playgroud)


Mar*_*nko 10

您还可以使用es2015预设和transform-regenerator插件执行以下操作:

.babelrc

{
  "presets": ["es2015"],
  'plugins': [
    'transform-regenerator'
  ]
}
Run Code Online (Sandbox Code Playgroud)

let regeneratorRuntime =  require("regenerator-runtime");
// You code with ES6 generators
Run Code Online (Sandbox Code Playgroud)

PS当然你应该安装babel-plugin-transform-regenerator npm包.

  • Babel为什么不自己做呢?我们必须做巴贝尔的工作吗? (4认同)
  • 更通用的解决方案是“ babel-plugin-transform-runtime”,其中包括再生器,还包括polyfill和helper,它们中的任何一个都可以通过config打开或关闭。就我而言(Babel 6+),不需要显式的“ require”。https://www.npmjs.com/package/babel-plugin-transform-runtime (2认同)