7

I have this function in CoffeeScript

render: -> 
_.each @$elements, ($el) =>
  if $el[0].id is 'tabs-div'
    emptySlate = "<div class='js-empty-slate' style='padding:40px;'><h3>no data available</h3><div>"
    @setEmptyPlacholde($el, emptySlate)
    return 

  @setEmptyPlacholde($el)


setEmptyPlacholde: ($el, emptySlate)->
emptySlateHTML = emptySlate or "<h3 class='js-empty-slate'>no data available</h3>"
if $el.hasClass('mobile-os-con') or 
   $el.hasClass('time-of-visit-con') or 
   $el.hasClass('gender-visit-con') or 
   $el.hasClass('time-redemption-sales-con') or 
   $el.hasClass('gender-redemption-con')

  $el.children().hide()
else
  $el.empty()
$el.append emptySlateHTML 

$elements is a jQuery variable which uses array like this:

$elements: [
$("#tabs-div")
$("#visits-male")
$("#visits-female")
$("#days-of-visits")
$(".time-of-visit-con")
]

When I used RequireJS optimizer r.js which uses Uglify the generated minified code .. looks like this:

render:function(){var e=this;return _.each(this.$elements,function(t){var n;if(t[0].id==="tabs-div"){n="<div class='js-empty-slate' style='padding:40px;'><h3>no data available</h3><div>",e.setEmptyPlacholde(t,n);return}return e.setEmptyPlacholde(t)})}

In the previous minified code, the $el became t .. So this refused to execute the $el as jQuery element in the production.

This is the problem but I don't know why this occurs. Can anyone explain why this happens for me, thanks.

Update: The minified code was not the problem but the script executed before the nodes in the array load properly ,however I am invoking the function after document be ready which means the DOM must be fully loaded.

Hint: I am putting the script tag in the ,and this works properly when the code is not minified.

Nouran Mahmoud
  • 309
  • 1
  • 2
  • 13
  • This is not the same code. Your minified code references a `selector` property whereas the unminified code references `id`. In addition, the unminified code indexes into the element; the minified code does not. Are you sure you posted the correct example? – dherman Feb 17 '15 at 22:47
  • Sorry, you are right. I was sharing another minified code that I was just playing with. Now, I have updated it with the right minified code. Thanks for notifying me. – Nouran Mahmoud Feb 17 '15 at 23:32
  • 3
    The minified code looks good to me, it's the exact same thing as the coffeescript code. It doesn't matter that `$el` is now `t` it's just a local name for a variable that is only in scope for the `_.each` function invocation – JoseM Feb 20 '15 at 14:25
  • Yes, this was not a problem of the minified code. But, the nodes in the array didn't load properly ,before the script being executed. so the `t` didn't work as intended as a jquery object which holds a node (this happens after minifying the code, however I am putting the script to be executed after document `ready` event) – Nouran Mahmoud Feb 21 '15 at 21:50

2 Answers2

0

First of all, your <div class='js-empty-slate' style='padding:40px;'><h3>no data available</h3><div> <- doesn't appear to be closed properly.

As far as the variable..this appears to be default behavior for UgliyJS, it's simply shortening the variable name you provided as a part of optimization. It should not cause any issue...however if you want to prevent it, try adding uglify: { no_mangle: true } to r.js optimizer settings under options:

english: {
  ..your settings...
  options: {
   ...your other options...
    uglify: {
      no_mangle: true
    },
  }
}

For Uglify2, use this instead:

uglify2: {
  mangle: false
}
webaholik
  • 1,619
  • 1
  • 19
  • 30
  • @nouran-mahmoud not sure if you down-voted or someone else...can you share your settings? – webaholik Feb 20 '15 at 22:23
  • I didn't down-vote your answer, but I believe that the point is not in not minifying the function or variable names. I want to know why it didn't work properly when it is minified ,however it should work. – Nouran Mahmoud Feb 21 '15 at 21:54
0

Just on a purely technical note you can improve the code with things like -

$elements: $("#tabs-div,#visits-male,#visits-female,#days-of-visits,.time-of-visit-con")

and

$elements.filter("#tabs-div")

As for the variable renaming - variable names make absolutely no difference to anything except when it's for a public API - so a code minifier/uglifier will change the variable names to the shortest possible, in other words starting at a single character, and often in a random order (though some start at a,b,c etc). By default the uglifier will understand that window etc is global and not rename it.

Unless you're wrapping everything in a closure you should start with something like $: window["jQuery"] so your local var $ will be correct when the variable renaming occurs and it will be pointing at the right thing.

If wrapping everything in a closure (wrap a function around everything can call it immediately) then you would pass jQuery as an argument - often you'd also pass longer named global vars that also get used like window and document.

Generally you include your script at the end of the HTML, or wrap it within a $() which is equivalent to the document.ready state.

Rycochet
  • 2,860
  • 1
  • 22
  • 39