Bundling & Minification in ASP.NET Core MVC Application

Bundling is the process of concatnating a set of files into one single file and Minification is removing all the whitespaces and comments in the code, removing extra statements to make the file smaller in size. By doing bundling and minification in our application will reduced the request payloads as well as the number of requests to the server for downloading the assets such as CSS and JS files.

.NET Framework had an in-built bundling and minification feature for sometime and since the advent of .NET Core they moved to use Grunt and Gulp for doing the same in both the RC versions. These tools primarily used JavaScript for operations such as file manipulation, automation, bundling and minification. Using these tools, we can also schedule tasks to run during a build or a publish event and is very useful in setting up a workflow for these opertions. The only downfall of these were we need to have some knowledge of programming in JavaScript and if you are not a fan of JavaScript then you will have some difficulties playing with it.

So Mads Kristensen created an extension which automates these processes and the functionality can be achieved with no code. So when Microsoft released .NET Core 1.0 they integrated this into the ASP.NET Core Web project template and is now available for you out of the box, if you are using Visual Studio 2015 for your developement. Basically it supports

  • Bundling your assets into a single file
  • Minification of your assets
  • Create triggers for doing re-bundling automatically
  • Globbing patterns
  • MSBuild support

Also the same is available as a NuGet package so that non Visual Studio users will also be able to use that in their projects. In this post, I am going to show how to do this a ASP.NET Core MVC project using Visual Studio Code and .NET CLI tools.

Adding Reference & Configuring BundlerMinifier

The first is to add the BundlerMinifier package in your json file as shown below

tools": {
    "BundlerMinifier.Core": "2.0.238",
    "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final",
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
  },

Now we need to add a configuration file in which we will specifiy the files that needs to be bundled and minified. The default name for the config file is bundleconfig.json, the advantage being that the tool will take it automatically by the bundle command. If we specify a different filename, then we need to set it explicitly while executing the command for bundling.

As you can see from the above snippet, we can specify multiple files that needed to be bundled into a single file as input and when the bundling operation is completed the unified file will be named using the value set in the outputFileName property. To minify the files, just set the value as true for the enabled property in the minify element.

Bundling & Minifying

Given below is the folder structure of the project in which I am going to do bundling and minification of JS and CSS files.

As you can see from the screenshot that under both js and css folder there are couple of files each. I am goint to make use of the dotnet bundle command to do both bundling and minification in the project. It uses the bundleconfig.json file for the options and in this case, I have set options for bundling both JS and CSS files and minification is enabled only for CSS file.

So we have sucessfully completed the bundling and minification process as shown in the above image. If you look at the screnshot closely you can see that when the css files are processed only bundling was done and in the case of JS files, both bundling as well as minification was done. This was due to the configuration we have in the bundleconfig.json which disables minification for css files. If you look in the folder structure you can see that two new files are created in both the js and css folders. Those files site.min.css and site.min.js were created during the bundling operation using the configuration from bundleconfig.json file.

Given below is the code used for bundling and minification and the minified file. You can see that in the minified files, contents from both files are added after removing all the whitespaces, empty lines and comments and all is in one line.

Bundling in Minification in Action

Before doing the operation, you need to restore the package first by executing the dotnet restore command.

Normally we want to serve minified version of files in environments such as production or staging and full version of the files in the developement environment. We can achieve this in .NET Core by specifying it in your cshtml file itself. The _layout.cshtml is file is used for adding all the references for the assets which needs to be there in all the pages in an application, let's specify the references for different environments as shown in the snippet below

If you run the application in the developement environment, .NET won't bundle or minify the files and there will be seperate requests for each of the resources.

But when the application is run in the production environment, only the minified version will be served and the number of requests will be less because of the bundling.

Note : 

Dealing with Environment Variable

ASP.NET Core uses an environment variable ASPNETCORE_ENVIRONMENT for determining the current hosting environment, you can use the below command to find out the one configured in your machine

> set | findstr "ASPNETCORE_ENVIRONMENT"

To set the variable

> SET ASPNETCORE_ENVIRONMENT=Production

To clear the value

> SET ASPNETCORE_ENVIRONMENT=

Automating Bundling process

Also we can automate the bundling process by including the following information in the project.json file, so whenever we run the application .NET Core will autmatically execute the bundle command during the prepublish event

"scripts": {
    "prepublish": [  "dotnet bundle" ],
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }

Full source code for example used in this post is available here at GitHub.


No Comments

Add a Comment