Bundling and Minifying an AngularJS Application with ASP.NET MVC

March 22, 2016 by Anuraj

AngularJS Optimization Minification Bundling DI ASP.NET MVC

Bundling and minifying an application scripts and CSS reduces page load time and asset size. This post is about the challenges and solutions while enabling bundling and minification in your aspnet mvc application. ASP.NET MVC comes with ASP.NET Web Optimization Framework which helps to combine and minify CSS and JS files. You can specify the script directory or files based on your convenience. This is important because identifying and troubleshooting script errors with bundling and minification enabled app is hard.

Here is the minimal bundling information, which bundles the Angular Framework and client scripts.

BundleTable.Bundles.Add(new ScriptBundle("~/scripts/angular")
    .Include("~/scripts/angular.js", "~/scripts/angular-route.js"));
BundleTable.Bundles.Add(new ScriptBundle("~/scripts/client")
    .IncludeDirectory("~/Client", "*.js"));

In the first line, I am bundling angular framework related files. In the next line, I am including all the script files under Client directory.

You can use the bundles in the _Layout.cshtml page using Scripts.Render method.

@Scripts.Render("~/scripts/angular", "~/scripts/client")

And here is my minimal Angular app and controller. As I am developing an Enterprise application, I am seperating the app and controller in two different files. Here is the app

var myApp = angular.module("myApp", []);

And here is the controller code.

var HelloController = myApp.controller("HelloController", function ($scope) {
    $scope.name = "";
});

Here is the HTML which will use the app and controller.

<div ng-app="myapp">
    <div ng-controller="HelloController">
        <label>Name </label>
        <input type="text" ng-model="name" placeholder="Name"/>
        <hr/>
        <h2 ng-show="name">Hello </h2>
    </div>
</div>
  • For script files order is important - If you run the application with bundling and minification enabled, you will get the first error.

Angular Minification Error

If you look at the HTML source, you will find something like this.

Angular Script Order

In this controller loaded first then the app file. Unlike .NET references, Javascript files need to load based on the order. Angular App should be loaded first, then the related components. You can fix it by including the app file using Include method instead of IncludeDirectory method. ASP.NET Framework will load the file only once.

BundleTable.Bundles.Add(new ScriptBundle("~/scripts/client")
    .Include("~/Client/MyApp.js")
    .IncludeDirectory("~/Client", "*.js"));

This will resolve the script order problem. Here is the HTML source generated.

Angular Script Order fixed

  • Dependency Injection - So far you haven’t enabled the bundling and minification, you can do it various ways, either by changing the configuration to Release mode or by setting BundleTable.EnableOptimizations to True.
BundleTable.EnableOptimizations = true;

Once you do this and run the application again you will find some other like this.

Angular DI Error

And if you look at the source code of the combined javascript file, you could see something like this.

Angular Scope variable renamed

It because the ASP.NET Web Optimization Framework renamed the ‘$scope’ variable to ‘n’. You can fix this issue using different DI syntax.

Using Inline Array Annotation

var HelloController = myApp.controller("HelloController", ['$scope', function ($scope) {
    $scope.name = "";
}]);

Or using $inject Property Annotation.

var HelloController = function ($scope) {
    $scope.name = "";
};

HelloController.$inject = ['$scope'];
myApp.controller("HelloController", HelloController);

The above methods will help you to minify your code without breaking the application behavior.

Happy Programming :)

Copyright © 2024 Anuraj. Blog content licensed under the Creative Commons CC BY 2.5 | Unless otherwise stated or granted, code samples licensed under the MIT license. This is a personal blog. The opinions expressed here represent my own and not those of my employer. Powered by Jekyll. Hosted with ❤ by GitHub