简体   繁体   中英

Script minified with bundling don't work in ASP.NET MVC 3 when debugging is disabled

My web application works fine with bundled script until <compilation debug="true" /> is set. If I set the debugging to false , my custom script become minified and then just stop working.

I can reproduce this trouble on different browsers, checked everything with F12 tools - no errors, found out whether global JavaScript variables have correct names. The only noticable difference is that the script is minified and local variable names likewise parameter names are changed which shouldn't break anything. I have also other custom scripts bundled and minified and they work correctly.

I believe that this is something stupid. I'm not expert in JavaScript and maybe I've missed something obvious to you. Could you give me a tip how to find the cause of the issue?

Regards, Ryszard

After a depper debugging, a found the error origin in slick.dataview.js script in compileFilter function. I use SlickGrid on my page and set filter in a Slick.Data.DataView object. compileFilter function performs some hardcoded string replacements against the provided filter function that fail when the filter function is bundled and then minified in release code.

I moved the filter function out of the minified script. That solved the problem.

You already figured out that the problem area was compileFilter , but your question and this post helped me figured out the root cause: https://github.com/mleibman/SlickGrid/issues/244

My guess: the author of Slick Grid would prefer that you use options.inlineFilters = false to get around this.

I wanted to understand why this issue only occurred when bundling in ASP.NET was used, and found this:

When using ASP.NET Bundling and Minification the return true and return false will be replaced with return!0 and return!1 , respectively.

(This happens even if you call Bundle.Transforms.Clear() )

Slick Grid's compileFilter and compileFilterWithCaching functions try to use regex to rewrite the filter function inside of a loop construct, and changes the return statements into continue statements.

Your solution of removing the filter functions from bundling worked for me also, but I didn't like having an exception to using bundling so I instead modified slick.dataview.js (v2.2) to handle the replacement for ASP.NET bundling:

I added these two lines to compileFilter and compileFilterWithCaching :

.replace(/return!1\s*([;}]|$)/gi, "{ continue _coreloop; }$1") // hack: .net bundling uses !1 for false
.replace(/return!0\s*([;}]|$)/gi, "{ _retval[_idx++] = $item$; continue _coreloop; }$1") // hack: .net bundling uses !0 for true

So that

  var filterBody = filterInfo.body
      .replace(/return false\s*([;}]|$)/gi, "{ continue _coreloop; }$1")
      .replace(/return true\s*([;}]|$)/gi, "{ _retval[_idx++] = $item$; continue _coreloop; }$1")
      .replace(/return ([^;}]+?)\s*([;}]|$)/gi,
      "{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2");

became

  var filterBody = filterInfo.body
      .replace(/return false\s*([;}]|$)/gi, "{ continue _coreloop; }$1")
      .replace(/return true\s*([;}]|$)/gi, "{ _retval[_idx++] = $item$; continue _coreloop; }$1")
      .replace(/return!1\s*([;}]|$)/gi, "{ continue _coreloop; }$1") // hack: .net bundling uses !1 for false
      .replace(/return!0\s*([;}]|$)/gi, "{ _retval[_idx++] = $item$; continue _coreloop; }$1") // hack: .net bundling uses !0 for true
      .replace(/return ([^;}]+?)\s*([;}]|$)/gi,
      "{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2");

Now I can continue to bundle all of my scripts using ASP.NET B&M, and slick grid is happy.

Update : compileFilterWithCaching actually is a slightly different because of the cache add step. Corrected update to function compileFilterWithCaching() is:

  var filterBody = filterInfo.body
      .replace(/return false\s*([;}]|$)/gi, "{ continue _coreloop; }$1")
      .replace(/return true\s*([;}]|$)/gi, "{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1")
      .replace(/return!1\s*([;}]|$)/gi, "{ continue _coreloop; }$1") // hack: .net bundling uses !1 for false
      .replace(/return!0\s*([;}]|$)/gi, "{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1") // hack: .net bundling uses !0 for true
      .replace(/return ([^;}]+?)\s*([;}]|$)/gi,
      "{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2");

I'm considering a pull request for this change on GitHub but I may revise it a bit first to add an option for whether to handle ASP.NET bundling... TBD. In the meantime I posted this issue to the GitHub page: https://github.com/mleibman/SlickGrid/issues/1053

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM