Runtime dynamic bundling and minifying in MVC 4 Runtime dynamic bundling and minifying in MVC 4 asp.net asp.net

Runtime dynamic bundling and minifying in MVC 4


One approach you can take is building the bundle dynamically when the application starts. So if your scripts are located in ~/scripts you can do:

Bundle bundle = new Bundle("~/scripts/js", new JsMinify());if (includeJquery == true) {       bundle.IncludeDirectory("~/scripts", "jquery-*");  bundle.IncludeDirectory("~/scripts", "jquery-ui*");} if (includeAwesomenes == true) {  bundle.IncludeDirectory("~/scripts", "awesomeness.js");}BundleTable.Bundles.Add(bundle);

Then your markup can look like this

@Scripts.Render("~/Scripts/Libs/js")

Note: I'm using the latest nuget package for system.web.optimization (now Microsoft.AspNet.Web.Optimization) located here. Scott Hanselman has a good post about it.


i wrote a helper function to dynamic minify my css & js

    public static IHtmlString RenderStyles(this HtmlHelper helper, params string[] additionalPaths)    {        var page = helper.ViewDataContainer as WebPageExecutingBase;        if (page != null && page.VirtualPath.StartsWith("~/"))        {            var virtualPath = "~/bundles" + page.VirtualPath.Substring(1);            if (BundleTable.Bundles.GetBundleFor(virtualPath) == null)            {                var defaultPath = page.VirtualPath + ".css";                BundleTable.Bundles.Add(new StyleBundle(virtualPath).Include(defaultPath).Include(additionalPaths));            }            return MvcHtmlString.Create(@"<link href=""" + HttpUtility.HtmlAttributeEncode(BundleTable.Bundles.ResolveBundleUrl(virtualPath)) + @""" rel=""stylesheet""/>");        }        return MvcHtmlString.Empty;    }    public static IHtmlString RenderScripts(this HtmlHelper helper, params string[] additionalPaths)    {        var page = helper.ViewDataContainer as WebPageExecutingBase;        if (page != null && page.VirtualPath.StartsWith("~/"))        {            var virtualPath = "~/bundles" + page.VirtualPath.Substring(1);            if (BundleTable.Bundles.GetBundleFor(virtualPath) == null)            {                var defaultPath = page.VirtualPath + ".js";                BundleTable.Bundles.Add(new ScriptBundle(virtualPath).Include(defaultPath).Include(additionalPaths));            }            return MvcHtmlString.Create(@"<script src=""" + HttpUtility.HtmlAttributeEncode(BundleTable.Bundles.ResolveBundleUrl(virtualPath)) + @"""></script>");        }        return MvcHtmlString.Empty;    }

usage

~/views/Home/Test1.cshtml

~/Views/Home/Test1.cshtml.css

~/Views/Home/Test1.cshtml.js

in Test1.cshtml

@model object@{   // init}@{}@section MainContent {  {<div>@{     if ("work" != "fun")     {        {<hr/>}     }  }</div>}}@{}@section Scripts {@{  {@Html.RenderScripts()}}@{}@section Styles {@{  {@Html.RenderStyles()}}}

but ofcoz, i put most of my sripts,styles in ~/Scripts/.js, ~/Content/.css

and register them in Appp_Start


We considered supporting dynamic bundles early on, but the fundamental issue with that approach is multi server scenarios (i.e. cloud) won't work. If all bundles are not defined in advance, any bundle requests that get sent to a different server than the one that served the page request will get 404 response(as the bundle definition would only exist on server that handled the page request). As a result, I would suggest creating all bundles up front, that's the mainline scenario. Dynamic configuration of bundles might work as well, but that is not a fully supported scenario.