7

Ho scritto un'app utilizzando Yeoman e backbone.js. Nella parte superiore di ogni file js ho specificato 'use strict'; e quando eseguo le mie attività grunt, jshint non incontra errori.Problema con con 'use strict' e underscore.js

sono in grado di costruire la mia app con grugnito senza problema tuttavia quando provo a fare funzionare i js uglified ottengo il seguente errore:

Uncaught SyntaxError: Strict mode code may not include a with statement

Ho cercato la base di codice e le uniche cose l'utilizzo di un'istruzione with è underscore.

Sono nuovo in modalità rigorosa quindi non sono sicuro di come sia possibile risolvere questo problema. Posso usare la modalità strict ovunque non utilizzi una funzione underscorejs?

Grazie.

EDIT:

dato il codice campioni sottostanti (abbreviato per brevità). Come posso cambiarlo per risolvere questo problema.

'use strict'; 

/*global, Backbone, JST*/ 

var MyView = Backbone.View.extend({ 

    template: JST['app/scripts/templates/MyView.ejs'], 

    initialize: function() 
    { 
     this.render(); 
    }, 

    render : function() 
    { 
     this.$el.html(this.template(this.templateVariables())); 
     return this; 
    }, 

    templateVariables: function() 
    { 
     return {var1 : 'Hello', var2 : 'World'}; 
    } 
}); 

in MyView.ejs

<p><%= var1 %><%= var2 %>!</p> //<p>Hello World!</p> 

EDIT 2:

utilizzando @mu è troppo la risposta di pantaloncini di seguito ho scoperto che il modo migliore per risolvere i chiamate a _.template che mi stava dando il dolore era cambiare il mio compito grint-JST come segue:

jst: { 
     compile: { 
      options: 
      { 
       templateSettings: 
       { 
        variable: 'data' 
       } 
      }, 
      files: { 
       '.tmp/scripts/templates.js': ['<%= yeoman.app %>/scripts/templates/*.ejs'] 
      } 
     } 
    }, 

E quindi modificare ciascuno dei miei modelli per utilizzare il formato <%= data.templateVariable %>.

Potrebbe non essere applicabile ad altri, ma mi sono imbattuto in questo problema utilizzando Yeoman con Grunt e un generatore Backbone, quindi non posso essere l'unico.

+0

Si sta utilizzando i modelli Underscore precompilati da qualche parte? L'unico 'with' in Underscore è all'interno del codice che' _.template' genera, quindi nessuno dovrebbe nemmeno sapere che 'with' viene usato a meno che non stiano guardando le funzioni del template compilato che' _.template' produce. –

+0

Solo così ho capito, mi stai chiedendo se sto usando sotto _.template() ovunque? Sì, lo sono. Suppongo quindi di dover essere più selettivo con la modalità rigorosa in quel file? – adampetrie

+0

@mu è troppo corto - ho scavato un po 'di più. Sto usando i modelli JST in tutta l'applicazione. Templates.js precompilato utilizza con istruzioni in tutto questo. Quindi la mia domanda diventa quindi come posso risolvere questo? Se rimuovo le direttive 'use strict;' nei file di visualizzazione che hanno template JST e poi eseguo 'grunt --force' e ignoro gli errori jshint, ottengo lo stesso risultato finale con il js minificato. Pensieri? Grazie. – adampetrie

risposta

17

Underscore _.template utilizza with internamente per consentire la risoluzione di <%= pancakes %> a obj.pancakes. Se look inside _.template, troverete questo:

if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; 

Ecco dove l'offensiva with viene da. Se stai utilizzando modelli precompilati in stile JST, è lo source che ti ritroverai all'interno dell'oggetto JST e che rende visibile lo with nell'ambito di "use strict". Si noti che settings.variable in là? The documentation dice:

By default, template places the values from your data in the local scope via the with statement. However, you can specify a single variable name with the variable setting. This can significantly improve the speed at which a template is able to render.

_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'}); 
=> "Using 'with': no" 

in modo da poter sopprimere i with s utilizzando l'opzione variable quando la compilazione dei modelli; ovviamente, questo significa anche che dovrai riscrivere tutte le parti dei tuoi modelli <%= ... %> per corrispondere a ciò che l'opzione variable ha da dire (questo dovrebbe anche velocizzare i tuoi modelli in modo che valga la pena solo per quello).

Nel tuo caso, devi cambiare il template a questo:

<p><%= data.var1 %><%= data.var2 %>!</p> //<p>Hello World!</p> 

e poi avresti bisogno di modificare la chiamata _.template che viene utilizzato per compilare i modelli per assomigliare a questo:

var compiled_template = _.template(raw_template, null, { variable: 'data' }); 

Non è necessario utilizzare data ovviamente, è sufficiente utilizzare la stessa cosa in entrambi i modelli e la chiamata _.template.

Non so come si cambierà il modo in cui si effettua il set up _.template ma non dovrebbe essere così difficile. Suppongo che potresti usare la patch scimmia _.template per avere un valore predefinito per variable come ultima risorsa.

Ecco un semplice demo che dovrebbe illustrare quello che sta succedendo: http://jsfiddle.net/ambiguous/Az8QM/


In alternativa, se guardiamo a come "use strict" is scoped, vedremo che:

Strict mode applies to entire scripts or to individual functions.

in modo da poter localizzare il vostro severità con qualcosa del genere:

(function() { 
    "use strict"; 
    // All your non-JST JavaScript goes here. 
})(); 
// Append your JST out here. 

You cou Utilizzate anche due file JavaScript invece di uno solo:

  1. Uno per il codice JavaScript non modello con "use strict" abilitato.
  2. Un secondo con solo il tuo JST, questo sarebbe non"use strict".
+0

Grazie mille per una risposta ben ponderata. Credo che la soluzione al mio problema sia lì da qualche parte, ma non sono in grado di tradurre ciò che hai detto in codice funzionante. Ho fornito un esempio sopra di ciò su cui sto lavorando. Se lo desideri, per favore mostrami come convertirlo in una soluzione funzionante. Idealmente mi piacerebbe convertire i miei modelli per i miglioramenti delle prestazioni. Grazie ancora. – adampetrie

+0

Ho aggiunto un po 'di più per il primo approccio. Io tendo ad usare la pipeline di asset Rails per questo genere di cose quindi non posso essere più specifico. –

+0

Grazie ancora. Sono stato in grado di risolvere le chiamate _.template modificando il mio task grunt per utilizzare le opzioni templateSettings. Ho modificato la mia domanda per mostrare ciò che era necessario. Saluti. – adampetrie

Problemi correlati