jetheredge / SquishIt

Lets you *easily* bundle some css and javascript! Check out the Google group if you have questions!
http://groups.google.com/group/squishit
MIT License
459 stars 119 forks source link

Several different (!) bundle files created for a single bundle definition #323

Closed teamaton closed 8 years ago

teamaton commented 8 years ago

I'm seeing some really weird things happening with SquishIt, using version 0.9.8. We bundle our scripts inside an ASP.NET WebForms MasterPage during the OnPreRender event handler. Here's what I found on our server's disk today:

Multiple script bundles

This happened last tonight after an application pool recycle at 3am, but I can see in the folder with generated bundles that it's been happening for a few days now - after an update from version 0.8.6. With the older version, this problem did not exist. With the new version, we also switched to using the YUI minifiers:

// SquishIt configuration
Bundle
    .ConfigureDefaults()
    .UseYuiForCssMinification()
    .UseYuiForJsMinification()
    .UseConditionToForceDebugging(() => HttpContext.Current.Request.QueryString["debug"] == "secret");

But it gets even worse! Some of the bundles are completely broken!

I'll give one example:

scripts_jquery.Text =
    Bundle.JavaScript()
            .Add("/scripts/jquery-1.8.3.js")
            .Add("/scripts/jqpl/jquery.tn.loadAsync.js")
            .Render("/_generated/jquery_#.js");

master_scripts.Text =
    Bundle.JavaScript()
            .Add("/scripts/bugsnag-2.min.js")
            .Add("/scripts/log.js")
            .Add("/scripts/jqpl/jquery.tn.webForms.js")
            // adding a lot more files
            .WithOutputBaseHref(Settings.CookielessDomain)
            .Render("/_generated/master_#.js");

Looking at the two jquery bundles I can see that the first one generated correctly contains the two files I've added to the bundle, jQuery-1.8.3.js and jquery.tn.loadAsync.js, but the second one contains minified versions of log.js and jquery.tn.loadAsync.js! log.js was added to a completely different bundle!

At the same time, in the first master bundle I can see (parts of) the jQuery library included, but with the first line being completety broken. It starts like this:

(,eu=.document,c3.location,c4.navigator,bZ.jQuery,e=Array=Array=Array=Object=Object,co.prototype.trim,c2)

That was the file that was actually referenced in our HTML which brought my attention to these problems in the first place.

To me, it looks a lot like a threading bug. Are we doing bundling wrong? It's obvious that having the bundling code inside a MasterPage will execute it for every single request. Might this be the culprit? If it is, then it's something that used to work in 0.8.6 though.

Please advise!

AlexCuse commented 8 years ago

Definitely roll back to 0.8.6. There should be measures in place to prevent threading bugs like this, but I have not used the async stuff in the newer versions of ASP.net, it might be causing problems.

I have not touched webforms in ~5 years. Any chance you could try to get me a sample project that suffers from the problem?

If not, I can try to find time to get to this but I'm pretty slammed lately, and I'm pretty sure its going to be a nightmare trying to reproduce without setting up a server somewhere. Would need the following info:

.net version ASP.net version (any of the newer async stuff in play?) IIS version + app pool settings anything else updated around the same time? are you seeing the same problem with CSS bundles? are you ever adding a whole folder at once? any preprocessors or is it all plain javascript/css?

You may try just moving away from doing it in OnPreRender - if you are using async I could see that causing problems for sure (maybe even without?). When I want to include bundles via the master page, I typically just define them in the view itself. Another option is pre-rendering your bundles on startup and then accessing by name when you need them.

AlexCuse commented 8 years ago

What trust level is your site running under?

teamaton commented 8 years ago

We run in Full Trust.

Anyway, I wanted to let you know that the problem went away after dropping the use of the YUI minifier:

// SquishIt configuration
Bundle
    .ConfigureDefaults()
    // .UseYuiForCssMinification()
    // .UseYuiForJsMinification()
    .UseConditionToForceDebugging(() => HttpContext.Current.Request.QueryString["debug"] == "secret");

Now, it works as smoothly as before.