MVC4 bundling javascript or css files from a different domain?

2.3k views Asked by At

In MVC4's Web.Optimization bundling / minimization, is it possible to register a bundle on one site (our static cookieless domain) and then use that bundle on another site (our webapp domain)?

eg static.myapp.com has a BundleConfig.cs with

public static void RegisterBundles(BundleCollection bundles)
{
    bundles.Add(new ScriptBundle("~/Scripts/static")
                .Include("~/Scripts/*.js"));
}

Can that bundle be used in a view on the webapp's domain, eg www.myapp.com has this in Site.Master

<%= Scripts.Render("static.myapp.com/Scripts/static") %>

Can this be done with MVC4 bundling? Serving static files from a cookieless static domain is a well known performance improvement.

3

There are 3 answers

2
Claies On

Bundling in ASP.net MVC allows you to optimize the deployment of scripts and stylesheets by replacing the placeholder Scripts.Render() at Runtime rather than at Design time. When the page is parsed and pushed to the client, the bundles registered to the calling server are parsed into the output buffer. Therefore the app serving the content must be running the bundler service. If a web app not running bundling encountered the Scripts.Render() element, it would either output null or throw an exception.

you can, however, use CDN references in your RegisterBundles method, like:

bundles.UseCdn = true;   //enable CDN support

//add link to jquery on the CDN
var jqueryCdnPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js";

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

In the code above, jQuery will be requested from the CDN while in release mode and the debug version of jQuery will be fetched locally in debug mode. When using a CDN, you should have a fallback mechanism in case the CDN request fails.

Edit

You could use ASP.Net MVC to serve as a CDN from static.myapp.com something like

routes.MapRoute(
    "CDN",
    "cdn",
    new { controller = "Webpage", action = "Fetch" }
);

[OutputCache(Duration=300, Location=OutputCacheLocation.Any)]
public ActionResult Fetch()
{
    return new FileStreamResult(
                       GetScriptBundle(Request.QueryString["url"]),
                       "text/javascript");
}
0
adam0101 On

Yes, see my answer here: How to make bundles unminify and list individual files when using a cookieless static content server?

Not only can you reference a different domain, but if you use a custom VirtualPathProvider like the one I provided, you can also keep the ability to list the files individually while in DEBUG mode.

Besides being easier to debug in the browser, you also won't have to rebuild to update the bundles every time you make a JS or CSS change while developing (just when adding or removing files).

0
cirrus On

So I just ran into this requirement and I solved it neatly in the page effectively similar to this;

<%
string jsStore = Context.IsDebuggingEnabled ? "~" : "static.mydomain.com";
string scriptTagFormat = Scripts.DefaultTagFormat.Replace("{0}", Url.Content(jsStore).TrimEnd('/') + "{0}");
%>

and

<%=Scripts.RenderFormat(scriptTagFormat, "~/bundles/allMyJS")%>

Of course you could also use DefaultTagFormat in RegisterBundles() but this offered more flexibility because;

  1. You can read jsStore from alternate web.configs for different environments.
  2. You can modify jsStore at runtime to match different {SERVER_NAME} hosts if you have dev, test sites etc.
  3. You can also use it with static tags like this;

    <script src='@Url.Content(jsStore + "/scripts/etc/lt-ie10.min.js")'></script>
    

The same approach can be used for the CSS.