When bundling AngularJS controllers, MVC 4 optimization best optimizes by renaming variables. Shrinking of variables reduces file size, however, when incorporating AngularJS and creating a controller, the $scope variable can NOT be renamed.
Not a big fan of third party scripts, yet the company that I was employed with, I had to find a work around.
This is why I enjoy .Net MVC, because I’m not stuck with a deterministic framework. MS MVC offers many tools. Below is how I got Angular to be minified.
Create a new C# class (NoRenameTransform.cs) and extended the IBundleTransform interface.
Include these namespaces:
System.Web.Optimization
Microsoft.Ajax.Utilities
using System;
using Microsoft.Ajax.Utilities;
using System.Web;
using System.Web.Optimization;
And implement the IBundleTransform interface
public class NoRenameTransform : IBundleTransform
{
protected static Minifier compiler = new Minifier();
public void Process(BundleContext context, BundleResponse response)
{
var codeSettings = new CodeSettings
{
NoAutoRenameList = "$scope"
};
response.Content = compiler.MinifyJavaScript(response.Content, codeSettings);
}
}
The Micorsoft.Ajax.Utilities exposes the Minifier / Minifer ASP.NET object, which has a MinifyJavascript method. MinifyJavaScript method optimizes the file’s contents.
Micorsoft.Ajax.Utilities also exposes the CodeSettings object.
Create a field instantiating Minifier object.
Within the Process method, create a variable instantiating CodeSettings object. Set the NoAutoRenameList property to an array of strings of the item(s) that shouldn’t be changed. The $scope variable will not be minified.
var codeSettings = new CodeSettings
{
NoAutoRenameList = "$scope"
};
IBundleTransform contract expects a Process method, and the Process method arguments expose BundleContext and BundleResponse.
Within the registered bundle configuration file, instantiate a new ScriptBundle class. ScriptBundle inherits from the Bundle class.
ScriptBundle exposes a Generic IList Transforms property.
Clear Transform
Add a new reference to the NoRenameTransform class.
var scriptBundleCore = new ScriptBundle"~/bundles/Modules/EventsApp");
scriptBundleCore.Include("~/Scripts/Modules/EventsApp/app.js");
scriptBundleCore.IncludeDirectory("~/Scripts/Modules/EventsApp/controllers", "*.js", true);
scriptBundleCore.Transforms.Clear();
scriptBundleCore.Transforms.Add(new NoRenameTransform());
bundles.Add(scriptBundleCore);
Bundle lifecycle:
Global.asax, Application_Start, Bundles are registered
BundlesConfig.RegisterBundles(BundleTable.Bundles);
BundlesConfig.RegisterBundles is called and ScriptBundle objects are added to the BundleTable.
ScriptBundles exposes a default transform property, which can be cleared.
scriptBundleCore.Transforms.Clear();
Add new behavior with how the bundle should be minified.
scriptBundleCore.Transforms.Add(new NoRenameTransform());
The transform Process method is called from when the razor view is rendered.
@Scripts.Render("~/bundles/Modules/EventsApp")
Complete Code
Razor View
@{
ViewBag.Title = "Index";
}
<div ng-app class="container">
<div ng-controller="EventController">
{{name}}
</div>
</div>
@section scripts {
@Scripts.Render("~/bundles/Modules/EventsApp")
}
Config.asax
using FileUpload_MVC.App_Start;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace FileUpload_MVC
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundlesConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
BundleConfig.cs
using FileUpload_MVC.Models;
using System.Web.Optimization;
namespace FileUpload_MVC.App_Start
{
public class BundlesConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Clear();
BundleTable.EnableOptimizations = true;
var scriptBundleCore = new ScriptBundle("~/bundles/Modules/EventsApp");
scriptBundleCore.Include("~/Scripts/Modules/EventsApp/app.js");
scriptBundleCore.IncludeDirectory("~/Scripts/Modules/EventsApp/controllers", "*.js", true);
scriptBundleCore.Transforms.Clear();
scriptBundleCore.Transforms.Add(new NoRenameTransform());
bundles.Add(scriptBundleCore);
}
}
}
NoRenameTransform.cs
using System;
using Microsoft.Ajax.Utilities;
using System.Web;
using System.Web.Optimization;
namespace FileUpload_MVC.Models
{
public class NoRenameTransform : IBundleTransform
{
protected static Minifier compiler = new Minifier();
public void Process(BundleContext context, BundleResponse response)
{
context.UseServerCache = false;
response.Cacheability = HttpCacheability.NoCache;
var codeSettings = new CodeSettings
{
NoAutoRenameList = "$scope"
};
response.Content = compiler.MinifyJavaScript(response.Content, codeSettings);
}
}
}
This post is for the purpose of my notes only and sometimes a rant.
“I invented nothing new. I simply assembled the discoveries of other men behind whom were centuries of work. Had I worked fifty or ten or even five years before, I would have failed. So it is with every new thing. Progress happens when all the factors that make for it are ready and then it is inevitable. To teach that a comparatively few men are responsible for the greatest forward steps of mankind is the worst sort of nonsense.”
Henry Ford