VS2012 - Web Forms - Bundling Confusion

ClearCloud8 picture ClearCloud8 · Sep 6, 2012 · Viewed 17.4k times · Source

I created a new ASP.NET Web Forms Project through Visual Studio 2012. Unfortunately, the default Site.Master file is very confusing. (I am posting these questions together because they are very related and reference the same code quite a bit.)

First off, I already understand the purpose of bundling and minification, so no need to discuss that. However I do not understand what is going with the way the scripts are being included in the default master page.

Question 1:
Why is a bundle called "~/bundles/WebFormsJs" being created in the BundleConfig.cs file, and yet in the master page, each of these same individual .js files are being listed out one by one in the ScriptManager?

Inside BundleConfig.cs:

bundles.Add(new ScriptBundle("~/bundles/WebFormsJs").Include(
              "~/Scripts/WebForms/WebForms.js",
              "~/Scripts/WebForms/WebUIValidation.js",
              "~/Scripts/WebForms/MenuStandards.js",
              "~/Scripts/WebForms/Focus.js",
              "~/Scripts/WebForms/GridView.js",
              "~/Scripts/WebForms/DetailsView.js",
              "~/Scripts/WebForms/TreeView.js",
              "~/Scripts/WebForms/WebParts.js"));

Inside Site.Master:

<body>
<form runat="server">
<asp:ScriptManager runat="server">
    <Scripts>
        <%--Framework Scripts--%>
        <asp:ScriptReference Name="MsAjaxBundle" />
        <asp:ScriptReference Name="jquery" />
        <asp:ScriptReference Name="jquery.ui.combined" />
        <asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebForms.js" />
        <asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebUIValidation.js" />
        <asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Scripts/WebForms/MenuStandards.js" />
        <asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Scripts/WebForms/GridView.js" />
        <asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Scripts/WebForms/DetailsView.js" />
        <asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Scripts/WebForms/TreeView.js" />
        <asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebParts.js" />
        <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" />
        <asp:ScriptReference Name="WebFormsBundle" />
        <%--Site Scripts--%>

    </Scripts>
</asp:ScriptManager>

As you can see.... each of those same .js files are individually listed in the ScriptManager. I don't even see a reference to the "WebFormsJs" bundle that was created anywhere outside of BundleConfig.cs. Why was that bundle ever created if each of these javascript files were going to be referenced individually here in the ScriptManager?

Question 2:
Why is a ScriptManager being used in this way at all? I was under the impression ScriptManager was required for Microsoft's version of Ajax such as using UpdatePanels. What is the purpose of using ScriptManager here... just to simply register javascript files?

Question 3:
What is the difference in registering javascript files through the ScriptManager versus up at the top of Site.Master where it uses the following approach instead?

<%: Scripts.Render("~/bundles/modernizr") %>

Question 4:
Inside the ScriptManager I also noticed these:

        <asp:ScriptReference Name="MsAjaxBundle" />
        <asp:ScriptReference Name="jquery" />
        <asp:ScriptReference Name="jquery.ui.combined" />

... I can at least recognize "MsAjaxBundle" from BundleConfig.cs, but where are jquery and jquery.ui.combined defined? I did a search and found a reference to them in packages.config.

<package id="jQuery" version="1.7.1.1" targetFramework="net45" />
<package id="jQuery.UI.Combined" version="1.8.20.1" targetFramework="net45" />

But I don't understand what is going on here either. I thought packages.config was used for NuGet. Plus... I don't even see a path listed here for the location of these jQuery .js files. They are just listed here and strangely associated with a particular version of the .NET Framework (4.5 in my case). Why a javascript resource would be associated with a version of the .NET Framework is beyond me.

Anyway, question 4 is this: How is the resource "jquery" in the ScriptManager being added/used? Why don't I see the jQuery .js files being bundled up together in BundleConfig.cs like all the other bundles??

Question 5:
Can I remove the following script reference from Site.Master if I am not planning on using UpdatePanel and those sort of Microsoft Ajax controls? I am a little confused as to why this is even included here by default.

<asp:ScriptReference Name="MsAjaxBundle" />

Answer

Hao Kung picture Hao Kung · Sep 6, 2012

UPDATE: This is a new blog post which also talks about this more: ASP.NET article

Basically webforms + bundling looks like this due to a bunch of legacy behavior that we weren't able to change in scriptmanager.

In regards to your specific questions:

  1. Basically this is so deduping works correctly, script manager has a limitation for the origional script resources which prevents them from being scriptmapped, so they need to be mapped to disk which then gets properly deduped because the files are already included in the bundle. The WebformsBundleJs is a script mapping that is created inside of the PreAppStart code inside of the ScriptManager nupkgs. (I agree this is nearly impossible to discover)

  2. New 4.5 features like unobtrusive validation required jquery(via scriptmanager), which is why script manager was used to ensure jquery doesn't get rendered out twice.

  3. This will work fine, but it will never dedupe with ScriptManager. So for modernizr it won't be an issue.

  4. The jquery packages drop the jquery files to disk in your Scripts folder.

  5. That reference pulls in the msajaxbundle which contains all of the ajax scripts, if you don't need/want them, I think its safe to remove.