Question

I would like to run JSHint on all my Javascript source files but several of them have some embedded Django template markup. JSHint throws a ton of errors on this markup.

Is there a way to either...

  1. Tell JSHint to ignore this markup
  2. Run the Djnago template parser with some dummy data to generate all permutations of the rendered js file and then run JSHint on that?

I assume I could write a bunch of code to do #2 but i'm wondering if there's an easier way.

Was it helpful?

Solution

Depending on a markup you can get away with "hiding" Django markup with JavaScript comments. We do this, for example:

// {% if cond %}
someJavaScriptCode();
// {% else %}
somethingElse();
// {% endif %}

// {% include "script.js" %}

The only thing is that you have start script.js with a blank line—otherwise // will eat the first legitimate line of JavaScript code you have there. I wrote a simple helper {% includejs %} that does that for me automatically.

OTHER TIPS

Actually there is a canonical way to hide Django markup (or any other content) from JSHint:

/* jshint ignore:start */
javascript_var = {{ context_json_string_var }};
/* jshint ignore:end */

The same for JSLint would be:

/*ignore jslint start*/
javascript_var = {{ context_json_string_var }};
/*ignore jslint end*/

You could also use this ugly solution. jslint thinks that "stuff =" is part of the comment.

var stuff;
/* {{ '*' + '/' }}
stuff = {{ variable_containing_json_object_or_list }};                      
// */

I've found that using the --extract flag tends to work. It also gets rid of any html code you may have in the template.

jshint --extract=always your_template_file.html

Personally, I encountered 3 problems when passing django javascript templates through the jslint tool:

Control structures

They can be easily hidden in javascript comments, just as Anton Kovalyov proposed:

// {{ if some_flag }}
console.log("Conditional log");
// {{ endif }}

String variables

The obvious solution is to enclose django tag in double quotes. It is however worth to remember that the generated code may be invalid if the variable content isn't properly escaped:

var javascript_var = "{{ context_var|escapejs }}";

Complex structures serialized to json

Edwin's trick works:

var javascript_var;
/* {{ '*' + '/' }}
javascript_var = {{ context_json_string_var }};                      
// */

If you include the javascript source template in the html template, you can declare a "getter" function there and access it from the javascript script:

<script type="text/javascript">function getIt() { return {{ context_var }}; };</script>
<script type="text/javascript">{% include 'script.js' %}</script>

In such case the javascript source would look pretty acceptable:

/*global getIt*/
var haveIt = getIt();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top