Evolving with Web Apps Through File Bundling and Minification

Web pages have evolved from simple and static HTML pages to intricate websites with dynamic content, as well as complex web applications meant for use across devices. Making these web applications requires a variety of content including CSS styles and JavaScript. Managing files with such diverse assets require greater bandwidth from both the development team and client.

The increased complexity of web apps may even outpace the mobile capabilities of devices. Increased traffic on sites supported by a server — whether it’s shared or cloud-supported — means more expenses for the business.

Applying ASP.NET bundling and minification to these files helps development teams and their clients to overcome these problems and create impactful web pages for more platforms.

What is ASP.NET Bundling and Minification?

Bundling and minification are two techniques enabled by ASP.NET, an open-source tool for building services and web apps using .NET. ASP.NET Bundling is a simple feature that makes it easier to combine multiple files into one, while minification is a process whereby code in a script or CSS file is optimized.

Why are these two steps so important? Every developer aims to structure code to make it more readable and reusable. ASP.NET bundling and minification techniques help to reduce the number of requests made to the server and the size of requested assets. Bundling and minification ultimately reduce the request load time.

Outdated Bundling and Minification Tactics

ASP.NET bundling and minification techniques used to be applied to a file in App_Start called BundleConfig.cs. A method called RegisterBundles in ASP.NET was used to create, register and configure bundles.

The following examples demonstrate the implementation of RegisterBundles:

1

2

3

4

bundles.Add(newScriptBundle("~/bundles/js").Include(

"~/Scripts/jquery-{version}.js",

"~/Scripts/bootstrap.js"

));

and

1

2

3

bundles.Add(newScriptBundle("~/bundles/css").Include(

"~/Content/bootstrap.css"

));

Here is an example of front-end code in RegisterBundles:

1

2

3

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

…

@Styles.Render("~/bundles/css")

Outdated ASP.NET Bundling Methods Increase Runtime

While this approach looks easy to use, it’s no longer applicable in ASP.NET 5. Why? The problem with that ASP.NET bundling approach is that those files increase run-time on the web server. Caching the files from big applications compromises memory capacity and processor capabilities.

Better Bundling and Minifying with Gulp and NPM

Gulp and NPM became the default tools for bundling and minifying files when ASP.Net Core was first made available to users.

What are Gulp and NPM?

Gulp is one of the most popular JavaScript-based task runners, which are tools used to automate the routines involved in the build process (like bundling and minification, or the cleansing of the development environment) and beyond.

The main tasks one needs to complete before bundling and minification with Gulp are as follows:

Bind the Gulp tasks to different actions within Visual Studio, so that whenever there is a change in scripts and styles, the compilation will automatically run to be reflected in your browser.

Compile all of the third-party dependencies.

Compile all of your scripts and LESS files.

Put a Gulp.watch running against the Front-End folder to auto-recompile.

How to Define and Setup Tasks in Gulp

The set of Gulp tasks is defined in Gulpfile.js. It is a JavaScript file added to your project. First, we need to specify required Node modules. Modules can be located either by name or path, and each of them will be assigned to a variable.

Specify Necessary Code Modules

1

2

3

4

5

6

7

8

9

10

varGulp=require("Gulp"),

rimraf=require("rimraf"),

concat=require("Gulp-concat"),

cssmin=require("Gulp-cssmin"),

watch=require("Gulp-watch"),

uglify=require("Gulp-uglify");

varpaths={

webroot:"./wwwroot/"

};

This required function imports each module so that the dependent tasks can utilize their features. Each of the imported modules is assigned to a variable.

Assign Code Modules to Variables

1

2

3

4

5

6

paths.js=paths.webroot+"js/**/*.js";

paths.minJs=paths.webroot+"js/**/*.min.js";

paths.css=paths.webroot+"css/**/*.css";

paths.minCss=paths.webroot+"css/**/*.min.css";

paths.concatJsDest=paths.webroot+"js/site.min.js";

paths.concatCssDest=paths.webroot+"css/site.min.css";

Additionally, a series of paths are created so the locations of CSS and JavaScript files can be reused and referenced within the tasks.

The next step after importing the required modules is to specify the tasks.

Specifying the Required Tasks

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

Gulp.task("clean:js",function(cb){

rimraf(paths.concatJsDest,cb);

});

Gulp.task("clean:css",function(cb){

rimraf(paths.concatCssDest,cb);

});

Gulp.task("clean",["clean:js","clean:css"]);

Gulp.task("min:js",function(){

returnGulp.src([paths.js,"!"+paths.minJs],{base:"."})

.pipe(concat(paths.concatJsDest))

.pipe(uglify())

.pipe(Gulp.dest("."));

});

Gulp.task("min:css",function(){

returnGulp.src([paths.css,"!"+paths.minCss])

.pipe(concat(paths.concatCssDest))

.pipe(cssmin())

.pipe(Gulp.dest("."));

});

Gulp.task("min",["min:js","min:css"]);

Gulp.task('default',['min']);

Gulp.task('watch',function(){

Gulp.watch(paths.css,['min:css']);

Gulp.watch(paths.js,['min:js']);

});

First, clean the old minified versions, then execute the task that minifies and concatenates all versions.

After the Gulpfile.js is created, open package.json and add the Gulp dependances:

Add Dependencies

1

2

3

4

5

6

7

8

9

{

"devDependencies":{

"Gulp":"3.8.11",

"Gulp-concat":"2.5.2",

"Gulp-cssmin":"0.1.7",

"Gulp-uglify":"1.2.0",

"rimraf":"2.2.8"

}

}

New Methods in Bundling & Minification

A new Visual Studio extension called BundlerMinifier replaced Gulp as the default tool for ASP.NET Bundling and minifying in ASP.Net Core. Gulp must be added manually to ASP.Net Core for those who want to continue to use it.

How to use BundlerMinifier

Start by downloading and installing the BundlerMinifier extension by Mads Kristensen. Visual Studio will ask you to install it when when you create a new project in ASP.NET.

You should already have bundleconfig.json created. When you right click on a JavaScript or CSS file, the “Minify File” option should appear. Clicking it will create site.min.js and add new records in the bundleconfig.json:

1

2

3

"outputFileName":"wwwroot/js/site.min.js",

"inputFiles":[

"wwwroot/js/site.js"

When multiple files are selected, you will see the option to “Bundle and Minify files.”

There is an option to convert to Gulp. This feature makes it easy to start using Gulp based on what’s already configured in bundleconfig.json. Choosing this option will create Gulpfile.js and package.js if they don’t already exist, and then install the needed node modules using npm.

The Gulpfile.js will consume bundleconfig.json to get the input and output file paths, but will use regular Gulp plugins to do all the bundling and minification. You can modify it to use other plugins without losing its ability to read the bundleconfig.json.

Process

It is very easy — and perhaps a necessity — to automate bundling and minification as a part of the build process. To do this, just add the “dotnet bundle” command in the precompile section of your existing project.json file:

1

2

3

4

5

"scripts":{

"precompile":[

"dotnet bundle"

]

}

Gulp vs. Bundler & Minifier

In conclusion, Bundler & Minifier is an effective tool that simplifies the process of enhancing System.Web.Optimization through the ASP.NET Bundling and minimization of your files. But if your case requires more advanced processing, choose Gulp.

Consider some pros and cons of both solutions:

Bundler & Minifier:

pros:

Fast, easy and intuitive – everything can be done with just a few mouse clicks

Lyubomir applies his passion for mathematics and deep analysis to his work as a developer at MentorMate. He leads his teams through Agile sprints consulting with clients and building a solid project foundation. A highlight of Lyubomir’s work is the continued contributions he and his team have made to one of MentorMate longest and largest engagements.

With previous development experiences in companies across Europe, Lyubomir’s collaborative spirit transcends cultures. The proof is in the powerful results that MentorMate’s development teams deliver.