ReferenceError: регенератор Runtime не определен (но работает внутри области видимости)

Я столкнулся с этим странным явлением:

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);
    }

}

Пакеты являются:

$ 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

Содержание .babelrc являются:

$ cat .babelrc 
{
    "presets": ["es2016"]
}

Тем не менее, когда объем удаляется и simplestIterator помещается в глобальную область, с которой не получается:

ReferenceError: regeneratorRuntime is not defined

Еще более странно, если .babelrc Файл удаляется / переименовывается, код успешно выполняется независимо от того, присутствует ли область действия. КСТАТИ, будь то сфера или IIFE, который содержит генератор, не имеет значения.

Минимальный репозиторий Github демонстрирует это поведение здесь.

Для наблюдения за поведением:

git clone https://github.com/mperdikeas/regeneratorRuntimeNotDefined.git
cd regeneratorRuntimeNotDefined/
npm install
npm run build && npm run start

Выше будет выводить 42 на консоли. Теперь удалите сферу и посмотрите, что произойдет. Тогда переименуй .babelrc чтобы увидеть, как это работает снова (с или без области).

Мои вопросы:

  • почему es2016 Предустановка Babel вызывает эту ошибку
  • почему установка генератора в прицел решает проблему?

Обновить

Основываясь на принятом ответе, и так как это был код для модуля, который я писал, я в итоге сделал:

require('babel-polyfill');
module.exports = require('./app.js');

2 ответа

Решение

Babel предполагает, что polyfill будет загружен раньше, чем что-либо еще в вашем приложении, но вы используете объявление функции, которое поднято, то есть оно существует и может быть использовано до require был вызван.

В случае генераторов, то нужно regeneratorRuntime который предоставляется полифилом, но полифилл не загружается при инициализации регенератора.

Команда Babel рекомендует сделать два файла:

index.js

require('babel-polyfill');
require('./app');

Также вы можете сделать следующее с пресетом es2015 и плагином transform-Регенератор:

.babelrc

{
  "presets": ["es2015"],
  'plugins': [
    'transform-regenerator'
  ]
}

Код

let regeneratorRuntime =  require("regenerator-runtime");
// You code with ES6 generators

PS Конечно, вы должны установить пакет npm для babel-plugin-transform-Регенератор.

Я знаю, что на это был дан ответ, но, к сожалению, они не устранили проблему для меня. Решено было импортировать Babelbabel-polyfills внутри файла

import "core-js/stable";
import "regenerator-runtime/runtime";

вы можете найти его в официальной документации babeljs или в этой статье

Другие вопросы по тегам