In ASP.NET MVC project we can have BundleConfig.cs class within App_Start folder. In the class we generally have RegisterBundles method to bundle Scripts/CSS. To minify the Scripts and CSS at runtime we need to use BundleTable.EnableOptimizations = true;
Now we will see instead of using ASP.Net RegisterBundles how we can achieve bundling and minification functionalities by using NPM Grunt package.
So, first we need to install nodejs 32 bit installer from: https://nodejs.org/dist/v4.4.6/node-v4.4.6-x86.msi
Visual Studio 2015 has great support for managing packages via NPM and for running Grunt and Gulp tasks.
Let me first create a MVC project named as “GruntJSBundlingMinificationDemoMVC”
Install NPM Task Runner to run/watch the grunt task execution
Right click on the Solution and click on Quick Install Package and then type grunt and click on install
It will internally run npm command to install grunt component
After installation is successful one package.json file and gruntfile.js will be added within the solution
Another way is you can directly add the package.json file and gruntfile.js by right click on the solution — > add new item — > Add “NPM configuration file” and “Grunt configuration file”.
Within the Package.json I have added the below piece of code
{
"name": "myproject",
"version": "1.0.0",
"dependencies": {
"time-grunt": "1.3.0"
},
"devDependencies": {
"grunt": "^1.0.1",
"grunt-contrib-clean": "~1.0.0",
"grunt-contrib-uglify": "~1.0.1",
"grunt-contrib-cssmin": "~1.0.1",
"grunt-filerev": "~2.3.1",
"grunt-filerev-assets": "~1.0.0",
"grunt-contrib-watch": "~1.0.0",
"grunt-timer": "0.6.0"
},
"-vs-binding": { "BeforeBuild": [ "install" ] }
}
Package.json is nothing but the references we need to add to install the grunt components whatever is needed. “We have added “BeforeBuild” event which signifies that the grunt components will be installed before the solution build started.
Within the Gruntfile.js file I have added the below piece of code
/// <binding BeforeBuild='build' Clean='clean' ProjectOpened='watch:bundles' />
/*
This file in the main entry point for defining grunt tasks and using grunt plugins.
Click here to learn more. http://go.microsoft.com/fwlink/?LinkID=513275&clcid=0x409
*/
module.exports = function (grunt) {
require('time-grunt')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: {
build: ['bundles']
},
uglify: {
options: {
sourceMap: false
},
build: {
files: {
'bundles/jquery.js': ['Scripts/jquery-*.min.js'],
'bundles/jqueryval.js': ['Scripts/jquery.validate*.min.js'],
'bundles/modernizr.js': ['Scripts/modernizr-*.js'],
'bundles/bootstrap.js': ['Scripts/bootstrap.js', 'Scripts/respond.js'],
'bundles/site.js': ['Scripts/site.js']
}
}
},
cssmin: {
options: {
sourceMap: true
},
build: {
files: {
'bundles/main.css': ['Content/bootstrap.css', 'Content/site.css']
}
}
},
watch: {
bundles: {
files: ['Scripts/**/*.js', 'Content/**/*.css'],
tasks: ['build']
}
}
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-filerev');
grunt.loadNpmTasks('grunt-filerev-assets');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('build', ['uglify', 'cssmin']);
};
At the top of the files I have specified the bindings. It signifies that the Grunt Build task and clean task will be triggered before solution build started. And as soon as project is opened it will start watching on the bundles.
Clean task will be used to clean up the bundles.
Uglify task will be created the JS bundle.
Cssmin task will created the CSS bundle.
Now we are ready to build the Gruntfile.js from Task Runner Explorer
Right click on the solution and go to Task runner explorer
We can run any task by right click on the task and click on Run
Here I am running Build task which will run uglify and cssmin task to bundle and minify JS and CSS
We should Comment out all the default bundle configuration in BundleConfig.cs file as we are no more using Asp.Net bindings
So, our Bundles scripts and css will be created after running the above task. The above steps are for manually running Grunt Task. As we have already specified the bindings details on top of Grunfile.js, so accordingly before solution build start the Build task will be executed.
Now in _Layout.cshtml page changed the bundling references
@using GruntJSBundlingMinificationDemoMVC
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@*@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")*@
<link href="~/bundles/main.css" rel="stylesheet" />
<script src="~/bundles/modernizr.js"></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
@*@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")*@
<script src="~/bundles/jquery.js"></script>
<script src="~/bundles/bootstrap.js"></script>
<script src="~/bundles/site.js"></script>
</body>
</html>
Now build the solution and run
In the output we can see that the page has been rendered with CSS and JS properly. While going to the page source we can see the scripts and css all are minified properly.
Hope this article helps you to understand the basic idea about NPM grunt package, purpose of using and the implementation.
Happy Coding
Tarun Kumar Chatterjee
Leave a comment