I've written an app using Yeoman and backbone.js. At the top of every js file I have specified 'use strict';
and when I run my grunt tasks jshint does not encounter any errors.
I am able to build my app with grunt without issue however when I try to run the uglified js I get the following error:
Uncaught SyntaxError: Strict mode code may not include a with statement
I've searched the code base and the only things using a with statement is underscore.
I'm new to strict mode so I'm not sure how I can resolve this issue. Can I not use strict mode anywhere that I use an underscorejs function?
Thanks.
EDIT:
Given the code samples below (shortened for brevity). How could I change it to resolve this issue.
'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:
Using @mu is too shorts's answer below I discovered that the best way to resolve the calls to _.template that were giving me grief was change my grunt-JST task as follows:
jst: {
compile: {
options:
{
templateSettings:
{
variable: 'data'
}
},
files: {
'.tmp/scripts/templates.js': ['<%= yeoman.app %>/scripts/templates/*.ejs']
}
}
},
And then change each of my templates to use the <%= data.templateVariable %>
format.
May not apply to others, but I ran into this issue using Yeoman with Grunt and a Backbone generator so I can't be the only one.
Underscore's
_.template
useswith
internally to allow things like<%= pancakes %>
to be resolved toobj.pancakes
. If you look inside_.template
, you'll find this:That's where the offensive
with
comes from. If you're using JST style precompiled templates, thatsource
is what you'll end up with inside yourJST
object and that makes thewith
s visible within the scope of"use strict"
. Notice thatsettings.variable
in there? The documentation says:So you can suppress the
with
s by using thevariable
option when compiling the templates; of course, this also means that you'll have to rewrite all the<%= ... %>
parts of your templates to match what thevariable
option has to say (this should also speed up your templates so it might be worth it just for that).In your case, you'd change the template to this:
and then you'd need to change the
_.template
call that is used to compile the templates to look like this:You don't have to use
data
of course, you just need to use the same thing in both the templates and the_.template
call.I don't know how you'd change how your set up calls
_.template
but it shouldn't be that difficult. I suppose you could monkey patch_.template
to have a default value forvariable
as a last resort.Here's a simple demo that should illustrate what's going on: http://jsfiddle.net/ambiguous/Az8QM/
Alternatively, if we look at how
"use strict"
is scoped, we'll see that:So you can localize your strictness with something like this:
You could also use two JavaScript files instead of just one:
"use strict"
enabled.JST
, this one would not"use strict"
.