ReferenceError: regeneratorRuntime non è definito (ma lavorando all’interno di un ambito di applicazione)

Ho incontrato questo strano occorrenza di:

ReferenceError: regeneratorRuntime is not defined

… che sono riuscito a riprodurre in un minimo di impostazione (rispetto ad analoghi in MODO da domande sullo stesso argomento), e anche notato qualche comportamento strano a seconda che gli ambiti vengono utilizzati.

Il seguente codice funziona:

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

}

Pacchetti sono:

$ npm ls --depth 0
simple-babel-serverside-node-only-[email protected].0.0 /home/mperdikeas/regeneratorRuntimeNotDefined
├── babel-[email protected].7.5
├── babel-[email protected].7.6
├── babel-[email protected].7.4
├── babel-preset-[email protected].0.11
└── babel-[email protected].6.1

Contenuto di .babelrc sono:

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

Tuttavia, quando il campo viene rimosso e il simplestIterator è collocato in ambito globale è negativo con:

ReferenceError: regeneratorRuntime is not defined

Ancora più stranamente, se il .babelrc file viene rimosso/rinominato il codice ha esito positivo se l’ambito è presente o meno. BTW se si tratta di ambito o di un IIFE che incapsula il generatore non fa alcuna differenza.

Minimo repo github dimostrazione di questo comportamento qui.

Per osservare il comportamento:

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

Sopra di uscita 42 sulla console. Ora rimuovere il campo di applicazione e vedere cosa succede. Quindi rinominare .babelrc a vederlo lavorare di nuovo (con o senza scopo).

Le mie domande sono:

  • perché il es2016 Babele preset attivare questo errore
  • perché non mettere il generatore in un ambito risolve il problema?

aggiornamento

Basato sul accettati risposta, e visto che questo è il codice di un modulo scrivevo, ho finito di fare:

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



2 Replies
  1. 47

    Babele si presuppone che il polyfill verrà caricato prima di ogni altra cosa, ma stai usando una dichiarazione di funzione, che viene issata, il che significa che esiste ed è utilizzabile prima require è stato chiamato.

    Nel caso di generatori, quindi è necessario regeneratorRuntime che è fornito di polyfill, ma il polyfill non viene caricato quando il rigeneratore è inizializzato.

    Babel squadra raccomandazione è quella di fare due file:

    index.js

    require('babel-polyfill');
    require('./app');
    • yeap; solo cambiato la sintassi un po ‘ come questo era all’interno di un modulo (vedi aggiornamento alla fine della mia domanda).
    • Se stai facendo la pubblicazione di un modulo, non si dovrebbe usare babel-polyfill a tutti, si intende per top a livello di applicazioni. La libreria dovrebbe supporre che sia caricato dall’applicazione, o utilizzare babel-plugin-transform-runtime per iniettare esplicito importazioni per ES6 libreria di funzionalità. Le librerie non dovrebbe mutare lo stato globale caricando polyfills.
  2. 10

    Inoltre è possibile effettuare le seguenti operazioni con es2015 preset e trasformare-rigeneratore plugin:

    .babelrc

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

    Codice

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

    P. S.
    Naturalmente, si dovrebbe installare babele-plugin-trasformare-rigeneratore npm pacchetto.

    • Perché non Babele farlo da solo? Ci devo fare la Babele di lavoro?
    • perché solo tu conosci il modo migliore per includere il rigeneratore di runtime del programma. Per esempio utilizzando richiedono chiamata di funzione o di ES6 istruzione import. O qualche altro modulo tecniche di implementazione.
    • Una soluzione più generale è babel-plugin-transform-runtime che comprende il rigeneratore, ma anche polyfill e collaboratori, ognuno dei quali può essere attivata o disattivata tramite config. Nel mio caso (babel 6+), senza esplicita require era necessario. npmjs.com/package/babel-plugin-transform-runtime
    • commento mi ha fatto ridere 😀 😀

Lascia un commento