2014-07-16 18 views
5

Sto usando il Angular version of the $q library tuttavia questo sarebbe anche rilevante per il original q library.preprocessore per sostituire le parole chiave javascript

Esempio di utilizzo:

$q 
    .when(someFunction) 
    .then(function(){ 
    // .. 
    }) 
    .catch(function(){ 
    // .. 
    }) 
    .finally(function(){ 
    // .. 
    }); 

Purtroppo alcuni nomi di funzioni (ad esempio finally) in conflitto con javascript parole chiave.
Dalla riferimento angolare:

"Perché finalmente è una parola riservata in JavaScript e parole chiave riservate non sono supportati come nomi di proprietà di ES3, avrete bisogno di invocare il metodo come promise['finally'](callback)per rendere il codice Compatibile con IE8 e Android 2.x. "

ECMA-262, lo standard ufficiale, disponibile presso http://www.ecma-international.org/publications/standards/Ecma-262.htm, afferma:

7.6.1.1 Parole

I seguenti token sono parole chiave ECMAScript e possono non essere utilizzati come Identificatori nei programmi ECMAScript.

break   do    instanceof  typeof 
case   else   new    var 
catch   finally   return   void 
continue  for    switch   while 
debugger  function  this   with 
default   if    throw    
delete   in    try 

Ciò significa che il primo esempio deve essere cambiato nel seguente codice per farlo funzionare con IE8:

$q 
    .when(someFunction) 
    .then(function(){ 
    // .. 
    }) 
    ['catch'](function(){ 
    // .. 
    }) 
    ['finally'](function(){ 
    // .. 
    }); 

Dato che questo codice è più difficile da mantenere Sto cercando un javascript preprocessore (forse un compito da grunt) che trasforma il primo esempio nella versione compatibile con IE8.

Esiste un preprocessore?

+0

Non ce n'è uno che io conosca. Probabilmente dovresti implementare il tuo. – RevanProdigalKnight

+0

@RevanProdigalKnight conosci un buon progetto di riferimento con il supporto della mappa di origine? – jantimon

+0

Sfortunatamente, non proprio. Quando ho implementato un [preprocessore C-style] (http://csserver.evansville.edu/~wg24/senior_project/other/node.js/preprocessor.js), non ho usato una mappa sorgente. – RevanProdigalKnight

risposta

8

Il tuo quartiere amichevole Stef Panner ha creato un tale strumento proprio per questo pochi mesi fa. Si chiama es3-safe-recast. C'è anche un grunt task per questo.

Esaminiamo ciò che fa. In primo luogo si richiede il pacchetto Esprima per JS analisi albero di sintassi e rifusione su di esso che è costruito per queste conversioni:

'use strict'; 
var esprima = require('esprima'); 
var recast = require('recast'); 
var Visitor = recast.Visitor; 
var types = recast.types; 
var namedTypes = types.namedTypes; 
var builders = types.builders; 

Poi contiene una grande mappa con tutti gli identificatori - proprio come la vostra lista:

identifierToLiteral.finally = true; // here is `finally` for example 

Ecco come si analizza l'albero e lo sostituisce con un visitatore:

var ES6Safe = Visitor.extend({ 
    visitProperty: function(node) { // go through all properties 
    // check if need to replace name with literal 
    if (namedTypes.Identifier.check(node.key) && identifierToLiteral[node.key.name]) { 
     node.key = builders.literal(node.key.name); 
    } 

    return this.genericVisit(node); 
    }, 

    visitMemberExpression: function(node) { // and all member expressions 
    var property = node.property; 
    var newNode; 
    // check if need to replace name with literal 
    if (namedTypes.Identifier.check(property) && identifierToLiteral[property.name]) { 
     newNode = builders.memberExpression(node.object, builders.literal(property.name), true); 
    } else { 
     newNode = node; 
    } 
    return this.genericVisit(newNode); 
    } 
}); 

Infine, viene eseguito il codice tramite rifusione:

ast = recast.parse(source, { esprima: esprima }); 
new ES6Safe().visit(ast); 
code = recast.print(ast).code; 

Produzione della versione sicura del codice sopra.

Problemi correlati