7

Ich habe eine App mit Yeoman und backbone.js geschrieben. Am Anfang jeder js-Datei habe ich 'use strict'; angegeben und wenn ich meine Grunt-Tasks ausführe, stößt jshint nicht auf Fehler.Problem mit 'Use strict' und underscore.js

Ich bin in der Lage meine app mit Grunzen jedoch ohne Problem zu bauen, wenn ich versuche, die uglified js ich folgende Fehlermeldung erhalten auszuführen:

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

ich die Code-Basis und die einzigen Dinge gesucht haben Die Verwendung einer with-Anweisung ist ein Unterstrich.

Ich bin neu im strikten Modus, also bin ich mir nicht sicher, wie ich dieses Problem lösen kann. Kann ich den strict-Modus nicht überall verwenden, wo ich eine Funktion "underscorejs" verwende?

Danke.

EDIT:

die Codebeispiele unten (verkürzt der Kürze halber) gegeben. Wie kann ich es ändern, um dieses Problem zu beheben?

'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:

Mit @mu auch ist die Antwort von Shorts unten entdeckte ich, dass der beste Weg, um die Anrufe zu lösen, das _.template gab mir Gram war meine Grunt-JST Aufgabe ändern wie folgt:

Und dann ändern Sie jede meiner Vorlagen, um das <%= data.templateVariable %> Format zu verwenden.

Kann nicht für andere gelten, aber ich stieß auf dieses Problem mit Yeoman mit Grunt und einem Backbone-Generator, so dass ich nicht der einzige sein kann.

+0

Verwenden Sie vorkompilierte Underscore-Vorlagen irgendwo? Das einzige 'with' in Underscore befindet sich innerhalb des Codes, den' _.template' erzeugt, so dass niemand darauf achten sollte, dass 'mit' verwendet wird, es sei denn, sie sehen sich die kompilierten Template-Funktionen an, die' _.template' erzeugt. –

+0

Nur damit ich verstehe, fragen Sie, ob ich irgendwo unter _.template() verwende? Ja bin ich. Ich gehe davon aus, dass ich in dieser Datei mit dem strikten Modus selektiver sein muss? – adampetrie

+0

@mu ist zu kurz - ich habe etwas mehr gegraben. Ich verwende JST-Vorlagen in der gesamten Anwendung. Die vorkompilierte templates.js wird mit Anweisungen verwendet. Also meine Frage wird dann, wie kann ich das lösen? Wenn ich die 'use strict;' - Direktiven in den View-Dateien entferne, die JST-Templates haben und dann 'grunt --force' ausführen und die jshint-Fehler ignorieren, bekomme ich immer noch dasselbe Endergebnis mit dem minimierten js. Gedanken? Vielen Dank. – adampetrie

Antwort

17

Underscore _.template verwendet intern with, um Dinge wie <%= pancakes %> zu aufgelöst werden zu lassen. Wenn Sie look inside _.template, werden Sie diese finden:

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

Das ist, wo die Offensive with herkommt. Wenn Sie vorkompilierte Vorlagen im JST-Stil verwenden, ist das source das, was Sie innerhalb Ihres JST-Objekts sehen werden, und das macht die with s im Rahmen von "use strict" sichtbar. Beachten Sie, dass settings.variable drin ist? The documentation sagt:

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" 

So können Sie die with s unterdrücken, indem die variable Option zu verwenden, wenn die Vorlagen zu erstellen ist; Das bedeutet natürlich auch, dass Sie alle <%= ... %> Teile Ihrer Vorlagen neu schreiben müssen, damit sie mit der Option variable übereinstimmen (dies sollte auch Ihre Vorlagen beschleunigen, so dass es sich allein dafür lohnt).

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

und dann würden Sie den _.template Anruf ändern müssen, die die Vorlagen erstellen verwendet wird wie folgt aussehen:

In Ihrem Fall würden Sie die Vorlage auf diese ändern

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

Sie müssen natürlich nicht data verwenden, Sie müssen nur das gleiche in den Vorlagen und dem _.template Anruf verwenden.

Ich weiß nicht, wie Sie ändern würden, wie Ihre Einrichtung Anrufe _.template, aber es sollte nicht so schwierig sein. Ich nehme an, Sie könnten einen Patch _.template für einen Standardwert variable als letzten Ausweg haben.

Hier ist eine einfache Demo, die zeigen sollten, was los ist: http://jsfiddle.net/ambiguous/Az8QM/


Alternativ, wenn wir, wie "use strict" is scoped betrachten, werden wir sehen, dass:

Strict mode applies to entire scripts or to individual functions.

Sie können also lokalisieren Ihre Striktheit mit etwas in der Art:

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

Sie können ld verwendet auch zwei JavaScript-Dateien anstelle von nur einem:

  1. Eine für Ihre nicht Vorlage JavaScript mit "use strict" aktiviert.
  2. Eine zweite mit nur Ihrer JST, diese würde nicht"use strict".
+0

Vielen Dank für eine durchdachte Antwort. Ich glaube, dass die Lösung für mein Problem irgendwo da ist, aber ich bin nicht in der Lage, das, was Sie gesagt haben, in Arbeitscode zu übersetzen. Ich habe oben ein Beispiel dafür angegeben, woran ich arbeite. Wenn Sie möchten, zeigen Sie mir bitte, wie Sie es in eine funktionierende Lösung umwandeln können. Im Idealfall möchte ich meine Vorlagen für die Leistungsverbesserungen konvertieren. Danke noch einmal. – adampetrie

+0

Ich habe ein bisschen mehr für den ersten Ansatz hinzugefügt. Ich neige dazu, die Rails-Asset-Pipeline für solche Dinge zu verwenden, daher kann ich nicht genauer sein. –

+0

Danke nochmal. Ich konnte die _.template-Aufrufe lösen, indem ich meine grunt-Aufgabe änderte, um die templateSettings-Optionen zu verwenden. Ich habe meine Frage bearbeitet, um zu zeigen, was benötigt wurde. Prost. – adampetrie

Verwandte Themen