Web developer’s work is becoming more and more concentrated on the browser side. Nowadays, applications have extensive business logic on the client side, validations, and data download from multiple sources. This is particularly evident in SPA applications (Single Page Application), in which sole function of the server may be returning the page sources and responding to the requests from the application only. Current solutions used in ASP.NET offered modest mechanisms to empower front-end developer’s work.
For example, the Bundle mechanism (combining multiple files into one to optimize page load time) is good for a small number of .js files, but the requirement to compile application to show new .js files in the .html file lowers the efficiency of the developer. The most popular .NET library to compile on server side .less files to.css (dotless) still does not support Less 2.0 version introduced more than a year ago. More comprehensive management of client files from the ASP.NET is very complicated. I think that ASP.NET supports well the back-end mechanisms, while in the front-end side we have great external tools.
I would like to present some of the problems which we encountered during our writing of SPA application in Angular and show how Gulp libraries made it easy to resolve them.
Gulp – short description:
Gulp is a tool for automation of our work. It operates on streams – Gulp reads selected files, makes transformation on every element in the stream and then writes to disk the result of our processes.
Installation of Gulp and its plugins is done by writing in the console:
Plugins can be searched for the in repository website at www.npmjs.com. Almost all Gulp plugins are prefixed with gulp- * e.g. gulp-less.
Tasks are declared in the gulpfile.js file and run by writing in the console gulp and name of the task (empty gulp starts the default task ). Sample file gulpfile.js:
A more detailed instruction is available on the Gulp pane at the Github platform, documentation tab.
Using Gulp in the project:
Task Runner Explorer window has been added to Visual Studio, in which we have access to all tasks declared in a gulpfile.js file. We can start them manually or attach them to the process of application building by adding jobs to build stages of the project.
Less / TypeScript Compilation
- Problem: We started writing application using such front-end technologies as Less and TypeScript. Unfortunately, Visual Studio 2015 does not have support for automatic compilation of these files during build, but requires installation of additional tools that are not trivial to use. We wanted a simple mechanism that will allow us to compile these files to their counterparts.
- Used libraries: gulp-less, gulp-typescript
- Solution: Both of these libraries are compiling files found in the given path, and then put them to the destination folder. They have a great configuration possibilities, but the basic usage requires only a few lines of code.
Minification and files merge
- Problem: A standard mechanism for ASP.NET Bundle requires to build the entire application even after adding one of .js or .css files. In addition, the ability to manage bundles is very limited. We wanted to have more control over the process.
- Used libraries: gulp-uglify, gulp-minify-css, gulp-concat, gulp-inject
- Solution: The first two libraries minify .js / .css files. gulp-concat combines minified files into one. gulp-inject is able to list all the files to .html. This allows us to react to the configuration of the build (Debug / Release) and to list either all files or only those minified.
- Problem: We use third-party libraries from the Bower package manager. We wanted to be able to add them automatically to .html file instead of adding entries manually.
- Used Library: main-bower-files, gulp-inject
- Solution: The main-bower-files allows to read dependences of our project on bower.json and retrieve a list of paths to the files. Then, by a gulp-inject, we are able to list them to our main .html file or join them to previously written minify mechanism.
Include static files
- Problem: In the application we had .html view files, and .json translation files that were downloaded by the application during the use. However, there were plenty of these files and it caused an avalanche of HTTP requests. We wanted to have them merged into one file so that the application would work faster.
- Libraries: gulp-angular-template cache, gulp-angular-translate
- Solution: Both of the libraries search the catalogs of the project and load all of the required signature files (first *.html, second * .lang.json). Then each plugin creates a file that, when loaded into the application, will provide cache for Angular for all views and translations so that we eliminate unnecessary requests.
- Problem: We noticed decrease in the speed of launching application due to slow downloading of minified files. After investigation, we found that downloading files from the Azure application Azure website, with a large number of requests, took too long and delayed the start. We decided to put these files in CDN (large, distributed system of proxy server) to speed up the downloading and to disburden application servers.
- Used libraries: gulp-deploy-azure-cdn
- Solution: Plugin puts files to a previously created container (Azure Blob). It has extensive configuration options and allows e.g. start ‘dry’ run, which in the Debug configuration will not send files to the container. After adding indication from Azure CDN to our blob we have fast file sharing mechanism that accelerates application performance.
- Problem: It turned out that Azure CDN, for files with the same filename, returns older versions of files despite the existence of newer in the container. We decided to add file version to each file to avoid problematic caching.
- Libraries: gulp-rev
- Solution: Library calculates the hash of the content and adds it to the end of the file name. As a result, after every change of the content, filenames are different and they are separately available from the CDN. At the same time, unchanged files are still cached and available more quickly for the application.
- gulp-load-plugins – simplifies the usage of plugins by loading them into a single object. Instead of loading all plugins by require you load gulp-load-plugins once, and then you have access to all plugins available from package.json file
- gulp-plumber – allows you to continue stream processing when error occurs
- gulp-task-list – lets you to list task from the console with their comments
- gulp-watch – allows listening to changes in the folders and responding to them e.g. created .less file is automatically recompiled to .css
- gulp-jshint – automates code quality check by the JSHint tool
There is a very large number of gulp plugins and I presented only a few of them. I invite you to seek and use them, because they will reduce the time to solve your problems and automate your work.
Gulp is a very powerful tool and using it can greatly simplify your work on the web-based project. Moreover, I even know people who use Gulp in building C# projects (gulp-msbuild). At the same time you need to be aware that it is a tool that has its own limitations and with certain complexity class’ problems (e.g. huge number of processed files, advanced graphics operations) you should look for more efficient tools. But for most cases Gulp suits perfectly and its implementation in the project gives us meaningful benefits. I would recommend everyone to get familiar with this tool.
npm install gulp
P.S. The article was published in Programista magazine no 12/2015.