How to bundle, minify web resources in ASP.NET MVC app using Areas?

When a new ASP.NET MVC project is created using the default project templates in Visual Studio, all the work required for bundling & minification is already available. But if you create separate logic groupings within your application using Areas, there are some manual steps that are required to set up this feature for web resources like CSS, JavaScript source files. In this post, I’ll tell you how to bundle, minify web resources in ASP.NET MVC app using Areas.

What is Bundling and Minification?

Bundling and minification are two techniques you can use in ASP.NET 4.5 to improve request load time.  Bundling and minification improves load time by reducing the number of requests to the server and reducing the size of requested assets (such as CSS and JavaScript.)
– ASP.NET Docs

In other words, Bundling is a feature available in ASP.NET MVC 4.5 that makes it easy to combine or bundle multiple files into a single file. You can create web resources like CSS, JavaScript and other bundles. Fewer files means fewer HTTP requests and that can improve first page load performance.

Minification helps us to perform a variety of different code optimizations to scripts or CSS, such as removing unnecessary white space and comments and shortening variable names to one character. This results in reducing the size of that source-code which will be sent to the browser through wire.

First Approach

You can question here that your main application has all the requirements already then why not just create bundle configuration in the main app, paste all the web resources from Areas to main application’s Content and Scripts folders and specify the virtual path of these resources based on the main application.

This works and you can still deploy your amazing application to production. But there are some downsides that I’ve notices when using this way of bundling & minification.

Firstly, we actually create Areas to logically group a part/feature of our whole application which we expect to encapsulate everything. This should also include web resources so that the main application should not need to care about bundle configurations for Areas and use the files that were copied using a post-build event.

Secondly, if you have this setup, it is high likely you will setup pre/post build event to copy those files. The reason you will do this is because Visual Studio and CI Server can do this tedious process automatically for you. But say suppose, in development time you are making changes to these resources and you would like to see the changes in browser straightaway to test what you have modified. Here you only have three choices – either to rebuild/restart your application so that the build events can work or manually copy/paste those files or use a folder monitoring/watcher application (if you found a stable app!!) that will do this on the basis of some rules like file extensions (.js, .css), if modified, etc.. Believe me this is really time-consuming!!!

Second Approach

So, the solution to two of the issues above is to give bundling and minification responsibility to Areas. They already own routing requirements and are capable enough to handles web resources as well because it is the same ASP.NET MVC application as you main application.

The nuget package that provides this amazing feature is Microsoft.AspNet.Web.Optimization. Use nuget package manager to install this package in your Area project(s). Let’s say we are doing this for an area named Media.

To register this area, we have MediaAreaRegistration class file that inherits System.Web.MVC.AreaRegistration class. Here we can define any area level configuration. The code is mentioned below:

I’ve created a RegisterBundles method that uses BundleConfig class to call RegisterBundles method and also passes the bundles collection and area-name. This setup is similar to what you will see in the main application’s BundleConfig.cs file. Below is the code in this file:

I’ve created two bundles above which just two files in each just to illustrate how can you can add multiple files. Both bundles have unique names. Notice the base source that is populated using the area-name. We need this to include the correct file path in the bundle’s include part that needs the actual path of the files.

I first tried to directly use ~/Content/... and ~/Scripts/... above but that resulted in framework looking for files inside the main MVC app’s folder structure. But when I includes the code above, framework was pointed in the correct direction.

So now we have registered our bundles. Let’s see how we can use this.

How to use bundles in Razor Views?

First add System.Web.Optimization namespace to Web.Config file under your area’s Views folder like this:

The reason we need to add this is so that our views can directly use the members in the namespace above without referring to the namespace every-time. This way above namespaces are registered for all the views in Views folder. This is already done for us when we create an MVC application using templates.

Now, we can consume the registered bundles in our views with the help of static classes that are defined in System.Web.Optimization namespace as shown below:

Control Bundling and Minification

We can enable or disable Bundling and Minification by setting the value of the debug attribute in the compilation element in the main Web.Config file. In the following XML, debug is set to true so bundling & minification is disabled.

To enable bundling & minification, set the debug value to false. This setting can also be overridden with the EnableOptimizations property on the BundleTable class. The follow code enabled bundling & minification and overrides any setting in the Web.Config file.

Note as per official docs:

Note: Unless EnableOptimizations is true or the debug attribute in the compilation Element  in the Web.config file is set to false, files will not be bundled or minified. Additionally, the .min version of files will not be used,  the full debug versions will be selected. EnableOptimizations  overrides the debug attribute in the compilation Element  in the Web.config file

Also, when you set the debug to false just to make this amazing feature work, you will not be able to debug. You can also use the #if compiler directive to get the best of both worlds inside RegisteredBundles method like this:

This sums up my post that tells you everything to how to bundle, minify web resources in ASP.NET MVC app using Areas. Read the official documentation to explore more about this feature.

Siddharth Pandey

Siddharth Pandey is a Software Engineer with thorough hands-on commercial experience & exposure to building enterprise applications using Agile methodologies. Siddharth specializes in building, managing on-premise, cloud based real-time standard, single page web applications (SPAs). He has successfully delivered applications in health-care, finance, insurance, e-commerce sectors for major brands in the UK. Other than programming, he also has experience of managing teams, trainer, actively contributing to the IT community by sharing his knowledge using Stack Overflow, personal website & video tutorials.

You may also like...

Advertisment ad adsense adlogger