Bundling and minification improves the speed and rendering performance of any web application. Bundling combines multiple JavaScript or CSS files into a single file where Minification reduces the size of the JavaScript or CSS file by removing white space and commented code without altering functionality. This not only reduces the number of requests to the server, also reduces the size of data transfer from the server to the browser. Both the techniques when used together can help in improving the performance of your web app. Bundling and minification can be done at design time and also at runtime. This post talks about 6 tools for bundling and minification in ASP.NET Core.
Tools for bundling and minification in ASP.NET Core
ASP.NET supports bundling and minification out of the box, but same is not true for ASP.NET Core. But the good thing about ASP.NET Core is, support for the open source technologies. This opens a pool of tools/techniques for the developers to select the tool/technique they are most comfortable with. The tools mentioned below are a mixture of open source technologies and developed by Microsoft. All these tools are easy to set up and helps to complete the whole process with few lines of codes. Let’s begin.
-
BundlerMinifier
BundlerMinifier is the default choice for ASP.NET Core application for bundling and minification. It is a simple package bundler integrated with the ASP.NET Core project build system. It was designed to avoid dependencies on other libraries and task runners such as Gulp. It’s a Visual Studio extension that lets you configure bundling and minification of JS, CSS and HTML files. It features:
- Bundle CSS, JavaScript or HTML files into a single output file
- Supports MSBuild for CI scenarios
- Minify individual or bundled CSS, JavaScript and HTML files
- Task Runner Explorer integration
- Command line support
- Support for converting to Gulp
If you are using VS 2015, then install this extension. Visual Studio 2017 comes with this extension. Today, when you create an ASP.NET Core MVC or Razor pages in VS 2017, you will find
bundleconfig.json
file present at the root of your project. This file defines configuration settings for each bundle. Below is the default code ofbundleconfig.json
file.// Configure bundling and minification for the project. // More info at https://go.microsoft.com/fwlink/?LinkId=808241 [ { "outputFileName": "wwwroot/css/site.min.css", // An array of relative input file paths. Globbing patterns supported "inputFiles": [ "wwwroot/css/site.css" ] }, { "outputFileName": "wwwroot/js/site.min.js", "inputFiles": [ "wwwroot/js/site.js" ], // Optionally specify minification options "minify": { "enabled": true, "renameLocals": true }, // Optionally generate .map file "sourceMap": false } ]
Simple and self-explanatory code. This code has 2 set of configuration rule. The first rule is for CSS file and the other is for JavaScript file. The first rule selects the CSS file,
wwwroot/css/site.css
; minifies it; and saves the minified version to an output file calledwwwroot/css/site.min.css
. The second rule selects the JavaScript filewwwroot/js/site.js
, minifies it and saves the minified output file towwwroot/js/site.min.js
.There are several options specified for minifications in JavaScript section. The first option is to enable the minification which is true by default. The second option is,
renameLocals
to rename all the local variables to a new shorter name to save some space. The final option is,sourceMap
which tells not to create a source map. A source map provides a way of mapping code within a compressed file back to its original position in a source file.This extension is fast and helps to complete everything with just a few mouse clicks. It also doesn’t require any JavaScript experience. You can read more about this here.
-
Gulp
Gulp is a JavaScript-based build system and JavaScript task runner which can automate common tasks of any website like minification, checking js errors, bundling of various js and CSS files, compiles SASS, optimizes images, creates sprites, concatenate files and various other tasks. In fact, Gulp was the preferred choice for bundling and minification in ASP.NET Core till RC2 release.
Gulp is fast as it prefers code over configuration approach and uses the power of node streams to reduce file I/O operations while performing any task. Once installed, it requires only 2 files for setting up things.
- package.json:This file is used by npm to store metadata for projects published as npm modules. You will list gulp and the gulp plugins your project needs.
- Gulpfile.js: This is the place to define gulp tasks.
Read Introduction to using Gulp in ASP.NET Core to know more. Gulp is suited for a big project, unlike BundlerMinifier. BundlerMinifier is unfit for complex tasks and Gulp offers much more than bundling and minifying.
-
Webpack
Webpack is a static module bundler for modern applications. When it processes your application, it recursively builds a dependency graph that includes every module your application needs, then packages all of those modules into one or more bundles. Along with JavaScript, it can also handle CSS, LESS, TypeScript, CoffeeScript, images, web fonts and more.
Once installed, it depends on
webpack.config.js
file for all the configurations. You need to add this file at the root of your project. Here is a samplewebpack.config.js
file.var path = require('path'); var webpack = require('webpack'); module.exports = { entry: { "main": './wwwroot/js/site' }, output: { publicPath: "/js/", path: path.join(__dirname, '/wwwroot/js/'), filename: "[name].js" } };
The main parts in the webpack configuration are the “entry” and the “output” fields. Webpack will analyze the entry file, resolve all the references from there, write everything together to the “wwwroot/js” folder with the name of the entry as the file name (“main.js”).
If you are new to webpack, read about the concepts and about configurations. Though Webpack is a module bundler, it can do most of the tasks you’d otherwise do through a task runner such as Gulp or Grunt. For example, Webpack already provides options for minification and source maps for your bundle. Webpack can also be run as a middleware to use Hot Module Replacement (HMR) feature. This feature is already used by Angular 4 template in VS 2017.
-
WebOptimizer
WebOptimizer is an ASP.NET Core middleware for bundling and minification of CSS and JavaScript files at runtime. It supports full server-side and client-side caching to ensure high performance and takes away all the complicated build process for bundling and minifying. It sets up a pipeline for static files so they can be transformed (minified, bundled, etc.) before sent to the browser. This pipeline is flexible enough to combine many transformations to the same files. The pipeline is set up when the ASP.NET web application starts, but no output is being generated until the first time they are requested by the browser. The output is then being stored in memory and served very fast on all subsequent requests. This also means that no output files are being generated on disk.
- Install the package from Nuget.
Install-Package LigerShark.WebOptimizer.Core
- Add the WebOptimizer to your services in Startup.cs:
services.AddWebOptimizer()
The service contains all the configuration used by the middleware and allows your app to interact with it.
- Add the middleware in
Configure
method:app.UseWebOptimizer(); app.UseStaticFiles();
Make sure to add the middleware before
app.UseStaticFiles
(if present).
That’s it. With just 2 lines of code, automatic CSS and JavaScript minification is enabled. You can control the minification in more detail, by interacting with the pipeline that manipulates the file content. Like,
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddWebOptimizer(pipeline => { pipeline.MinifyJsFiles("js/a.js", "js/b.js", "js/c.js"); }); }
Bundling can be enabled in following way,
services.AddWebOptimizer(pipeline => { pipeline.AddCssBundle("/css/bundle.css", "css/a.css", "css/b.css"); });
I recommend you to read the official documentation for all the details.
- Install the package from Nuget.
-
Grunt
Like Gulp, Grunt is also a JavaScript-based task runner, a tool used to automatically perform frequent tasks such as minification, compilation, unit testing, and linting. Grunt and Grunt plugins are installed and managed via npm, the Node.js package manager. The Grunt ecosystem is huge and it’s growing every day. With literally hundreds of plugins to choose from, you can use Grunt to automate just about anything with a minimum of effort. Similar to Gulp, Once installed, it requires only 2 files for setting up things.
- package.json:This file is used by npm to store metadata for projects published as npm modules. You will list grunt and the grunt plugins your project needs.
- Gruntfile.js: This is used to configure or define tasks and load grunt plugins.
Read Using Grunt in ASP.NET Core to know more. You may find Grunt and Gulp similar but they are different.
- Gulp prefers code over configuration approach, which makes the thing more efficient and manageable.
- Gulp is fast as it uses node stream to reduce file I/O operations while performing any task. On the other side, grunt performs more file I/O operations.
- Being old, Grunt has a great community support and has more plugins compare to gulp.
-
Smidge
The last in this list is Smidge. Smidge is a lightweight runtime CSS/JavaScript file minification, combination, compression & management library for ASP.Net Core. It has properly configured client-side caching, persistent server-side caching (no re-bundling unnecessarily), supports fluent syntax for creating and configuring bundles, cache busting and file watchers to auto invalidate/refresh a processed bundle. The latest version 3.0 is targeted at .NET Standard 2.0 and ASP.NET Core 2.0. Using Smidge with ASP.NET Core is simple and straightforward.
- Install Smidge from Nuget.
Install-Package Smidge
- Add Smidge configuration section to appsettings.json:
"smidge": { "dataFolder" : "App_Data/Smidge", "version" : "1" }
The
dataFolder
is where the cache files are stored and the version number is appended to the bundled scripts and stylesheets. - Add smidge to your services in Startup.cs
services.AddSmidge(Configuration.GetSection("smidge"));
- Create a bundle in your configure method.
app.UseSmidge(bundles => { bundles.CreateCss("my-style", "~/css/site.css"); bundles.CreateJs("my-application", "~/js/site.js", "~/js/app"); });
- Add the Smidge tag helpers to your
_ViewImports.cshtml
file like this:@addTagHelper *, Smidge
- Render your bundle via modifying the
_layout.cshtml
like this:<link rel="stylesheet" href="my-style" /> <script src="my-application" type="text/javascript"></script>
Smidge is extensible and allows you to create a custom pre-processing pipeline. It’s easy to customize how your files are processed. This can be done at a global/default level, at the bundle level or at an individual file level. You can read more here about the custom pre-processing pipeline.
- Install Smidge from Nuget.
I would prefer Gulp over Grunt.
Summary
To conclude, this post talks about 6 tools for enabling bundling and minification in ASP.NET Core application. Each of the tools has its pros and cons. Webpack, Gulp and Grunt requires JavaScript knowledge where for the other 3 JavaScript experience is not needed. Out of these tools, Gulp is the preferred choice because it is fast, supports code over configuration, brings a lot more to the table and great community support. But again, it’s an individual choice. If you know any other tools, please let me know in the comments section and I will include in this list.
Thank you for reading. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in the comments section.
what will be the final size of my 1MB application if i try to bundle dotnet 3.5?