55

In our ASP.NET MVC 4 web application, our BundleConfig.cs includes the following:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                        "~/Scripts/jquery-ui-{version}.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.unobtrusive*",
                        "~/Scripts/jquery.validate*"));
            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                        "~/Scripts/modernizr-*"));

When we look at the html of the home page on development server, we can see the following script tags even though the debug mode in web.config is set to true as <compilation debug="true" targetFramework="4.0" />:

<script src="/AFR/Scripts/jquery-ui-1.8.20.min.js"></script>
<script src="/AFR/Scripts/modernizr-2.5.3.js"></script>
<script src="/AFR/Scripts/jquery-1.7.1.js"></script>
<script src="/AFR/Scripts/jquery-ui-1.8.20.js"></script>
<script src="/AFR/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/AFR/Scripts/jquery.validate.js"></script>
<script src="/AFR/Scripts/jquery.validate.unobtrusive.js"></script>

But when we deploy the app on staging server and look at the html (View Source) of the home page, all of the above script tags with the exception of <script src="/AFR/Scripts/jquery-ui-1.8.20.min.js"></script> are missing. We've verified that all the files mentioned in these tags are in the script folder. The folder structure is exactly the same as on development machine. On staging server, the web.config fie has <compilation targetFramework="4.0" /> which means, by default, the debug="false".

As a result, some of the JavaScript functions are failing on staging server. Both the staging and development machines are Windows 2012.

Please help. Thanks.

nam
  • 21,967
  • 37
  • 158
  • 332
  • when you say missing, do you mean the files are not on the staging server? or the links are just not working? – JanR Jan 21 '14 at 23:18
  • @nam In your staging server, do you see a script tag like `` on your home page? – Tommy Jan 22 '14 at 00:01
  • @JanR, the files are on the staging server with exact same folder structure as in development machine. Just the above script tags are not rendered in the home page. – nam Jan 22 '14 at 00:01
  • @Tommy, yes I do see about 5 script tags like the one you mentioned. – nam Jan 22 '14 at 00:14

8 Answers8

108

Based on your comments, we need to go over how the Bundling mechanism works in MVC.

Edit: Based on the comment below by VSDev, you need to ensure WebGrease is installed into your project. NuGet would be the easiest was to install this package.

When you set a bundle configuration (Example not from above to illustrate)

bundles.Add(new ScriptBundle("~/bundles/mainJs")
      .Include("~/Scripts/mainSite.js")
      .Include("~/Scripts/helperStuff.js"));

You then, in your views, call something like @Scripts.Render("~/bundles/mainJs"). When your web.config is set into a debug compilation OR you explicitly turn off bundling using the following line in your BundleConfig.cs file

BundleTable.EnableOptimizations = false;

Then, in your view, you will see the following rendered out

<script src="/Scripts/mainSite.js" type="text/javascript"></script>
<script src="/Scripts/helperStuff.js" type="text/javascript"></script>

These are the individual items that made up our bundle, uncompressed and listed individually. The reason these list out individually in debug mode is so that you can debug your scripts and see them as you wrote them (actual variable names, etc).

Now, when we are not in a debug compilation and have not turned off the EnableOptimizations feature, MVC will combine those files in our bundles, compress (minify) them and output only a single script tag.

<script src="/bundles/mainJs?v=someBigLongNumber" type="text/javascript"></script>

Notice that the source is the same as the name of the bundle from the bundle configurations. Also, the number after the ?v= will change anytime you change a file in that bundle. This is to help prevent caching of old js and css files by the client browsers.

Your scripts are still there and being outputted, but they are being compressed and combined into a single file called /bundles/mainJs. This feature is present to

A) compress the files and reduce information being transmitted and,

B) reduce the number of calls to a website to retrieve the necessary content to render the page.

Nothing is missing, it sounds like everything is working as intended. In a production site, the minification makes these files almost impossible to read, thus why the minification does not take affect while debugging.

As to why the jQuery UI is still being a single JS file, ensure someone didn't hard code that into your layout view. As for the JS errors, it could be errors that are present on your development box or perhaps something did not compress correctly (however, in all of my MVC development, I have not seen a JS error because of bad minification).

InteXX
  • 6,135
  • 6
  • 43
  • 80
Tommy
  • 39,592
  • 10
  • 90
  • 121
  • 1
    I've done the taken these exact steps but my @Styles.Render("~/bundles/CssBundle") renders that throwes a 404. Any idea why? – Misbit Aug 25 '14 at 07:08
  • @vsdev - I think I have seen that when I tried to render a non-existent bundle. Ensure you have the correct syntax in bundle name and registration. – Tommy Aug 25 '14 at 09:43
  • 6
    Turns out you needed WebGrease. After adding the NuGet and the lines below I got it working. – Misbit Aug 25 '14 at 09:48
  • i had this issue , bootstrap datepicker didn't show up in production server, so i re - transferred all bin files , which solved the issue of edited bundle config – Shaiju T Mar 21 '15 at 14:02
  • 6
    I was getting 404 because I had a dot in bundle virtual path. Removing the dot solved the problem. – user551113 Jul 07 '15 at 14:00
  • may be not relevant, but recently i just added action method, and published the `dll` without the view in view folder, then i uploaded the view to view folder using `ftp`, but my `css` didn't get loaded with empty bundle random value in filed `v` like this: ``, but when i published with the view in project , bundle random value is not empty and css gets loaded, so does that mean that bundles are tied up with view and should be compiled ? – Shaiju T Dec 20 '15 at 12:52
  • I am having this same problem with bundling js files and i am using this theme:http://lambdathemes.in/admin1/. Can you please help me?? – I Love Stackoverflow Mar 17 '16 at 11:05
8

I ran into the same problem, and I'm not sure why, but it turned out to be that the script link generated by Scripts.Render did not have a .js extension. Because it also does not have a Type attribute the browser was just unable to use it (chrome and firefox).

To resolve this, I changed my bundle configuration to generate compiled files with a js extension, e.g.

            var coreScripts = new ScriptBundle("~/bundles/coreAssets.js")
            .Include("~/scripts/jquery.js");

        var coreStyles = new StyleBundle("~/bundles/coreStyles.css")
            .Include("~/css/bootstrap.css");

Notice in new StyleBundle(... instead of saying ~/bundles/someBundle, I am saying ~/bundlers/someBundle.js or ~/bundles/someStyles.css..

This causes the link generated in the src attribute to have .js or .css on it when optimizations are enabled, as such the browsers know based on the file extension what mime/type to use on the get request and everything works.

If I take off the extension, everything breaks. That's because @Scripts and @Styles doesn't render all the necessary attributes to understand a src to a file with no extension.

Avi Turner
  • 10,234
  • 7
  • 48
  • 75
Ryan Mann
  • 5,178
  • 32
  • 42
  • 4
    This is not a typical issue that developers see with the bundling mechanisms. You may have some other issue(s) with your project. – Tommy Jun 18 '15 at 02:01
  • 2
    Brilliant - this worked for me in an Umbraco project. I thought it may be something to do with mime types, as the url for the script/style bundles was actually working if you pasted it in the address bar, but 404'ing when the browser loaded the page. – Hywel Rees Mar 14 '16 at 11:12
  • 4
    @Tommy - as you suggested, there was another underlying problem. It turns out, for Umbraco you simply need to add the ~/bundles/ path to the umbracoReservedPaths key/value pair in teh web.config, as described here: https://our.umbraco.org/forum/umbraco-7/using-umbraco-7/61511-Visual-Studio-2013-bundling-not-working – Hywel Rees Mar 14 '16 at 11:20
  • 1
    @HywelRees - Nice find! That's one of those really important yet hard to find / remember steps I would think! – Tommy Mar 14 '16 at 11:23
  • 1
    Yeah, this answer of mine is misleading because I was wrong. Most browsers don't care if it has a .js or .css extension. It will consider a script tag a script and a link tag a style sheet. In this scenario, as mentioned, it was because umbraco needs the reserved path set for the bundles path, per @Hywel Rees above. – Ryan Mann Sep 14 '17 at 21:45
  • By default, using a .js extension means that IIS will try - and fail - to serve a physical js file from the bundle url being requested, and will return a 404. – Chris F Carroll Sep 17 '18 at 09:38
8

By adding following code of line in bundle to config it works for me

bundles.IgnoreList.Clear();  

Follow the link for more explanation

zaheer ahmad
  • 294
  • 4
  • 16
  • This was it for me. Already-minified JS files seem to be ignored by default, so if your bundles include minified third-party libs (like jQuery) they're excluded and your site doesn't work anymore. – KeithS Oct 27 '17 at 22:35
  • This was also my problem, but only with scripts. The style bundles worked as expected even though files were pre-minimized. So the link information above might be incorrect saying it applies to both .min.css and .min.js. Up voted. – Yogi Dec 10 '17 at 05:25
4

Whenever I set debug="off" in my web.config and run my mvc4 application i would end up with ...

<script src="/bundles/jquery?v=<some long string>"></script>

in my html code and a JavaScript error

Expected ';'

There were 2 ways to get rid of the javascript error

  1. set BundleTable.EnableOptimizations = false in BundleConfig.cs

OR

  1. I ended up using NuGet Package Manager to update WebGrease.dll. It works fine irrespective if debug= "true" or debug = "false".
Sunil Johnson
  • 1,059
  • 8
  • 6
3

For me, the fix was to upgrade the version of System.Web.Optimization to 1.1.0.0 When I was at version 1.0.0.0 it would never resolve a .map file in a subdirectory (i.e. correctly minify and bundle scripts in a subdirectory)

PBMe_HikeIt
  • 659
  • 8
  • 24
2

I used Identity2 then Scripts didn't load for anonymous user then I add this code in webconfig and Sloved.

<location path="bundles">
<system.web>
  <authorization>
    <allow users="*" />
  </authorization>  
</system.web>
 </location>
leyla azari
  • 913
  • 11
  • 20
2

Things to check when enabling the bundle optimization;

BundleTable.EnableOptimizations = true;

and

webconfig debug = "false"

  1. the bundles.IgnoreList.Clear();

this will ignore the minified assets of your bundles like *.min.css or *.min.js which can cause an undefine error of your script. To fix is to replace the .min asset with the original. if you do this you may not need the bundles.IgnoreList.Clear(); e.g.

bundles.Add(new ScriptBundle("~/bundles/datatablesjs")
       .Include("~/Scripts/datatables.min.js") //<-- change and point this to your (original) non minified ver.
  1. Make sure the names of the bundles of your css and js are unique.

bundles.Add(new StyleBundle("~/bundles/datatablescss").Include( ...) );

bundles.Add(new ScriptBundle("~/bundles/datatablesjs").Include( ...) );

  1. Make sure you use the Render name of your @Script.Render and Style.Render are the same on your bundle config. e.g.

@Styles.Render("~/bundles/datatablescss")

@Scripts.Render("~/bundles/datatablesjs")

Julius Limson
  • 526
  • 9
  • 29
1

add to your global file this action.

protected void Application_Start() {
   BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Srikrushna
  • 4,366
  • 2
  • 39
  • 46