📜 ⬆️ ⬇️

Preparing ASP.NET 5, issue number 7: more about working with Gulp

We continue our column on the topic ASP.NET 5 with a publication from Dmitry Sikorsky ( DmitrySikorsky ) - the head of the company “Yubreynyans” from Ukraine. In this article, Dmitry talks about application scenarios with ASP.NET 5 of the popular Gulp tool in more detail. Previous articles from the column can always be read on the link #aspnetcolumn - Vladimir Yunev
Before the advent of ASP.NET 5, I had never used tools like Gulp, so I had to spend some time and figure out what it was when I created my first project on this platform (true, then Grunt was still there, but it wasn’t important). I will not go into the basic things that are already described in sufficient detail everywhere (I mean that you already have Gulpfile.js in your project and you can complete tasks from it using the Task Manager of Visual Studio 2015), but I’ll go straight to the point and in practice, I’ll show how Gulp can be used to automate everything in your ASP.NET 5 project.


The article will contain fragments of the Gulpfile.js file of the AspNet5Gulpization test project, which lies entirely here: https://github.com/DmitrySikorsky/AspNet5Gulpization .

Introduction


You probably know what the new folder wwwroot is used for. In fact, with her appearance, I took a little new look at scripts, styles, and pictures. Namely, as well as the server code of the site, now I divide them into source codes and objects ready for publication.

Training

aspnetcolumngithub Tip! You can try everything yourself or by downloading the source code from GitHub https://github.com/DmitrySikorsky/AspNet5Gulpization .
First of all, we need to list in our Gulp-file all the packages that we will use in our tasks (and make sure that all of them are present in package.json):
')
var gulp = require("gulp"), autoprefixer = require("gulp-autoprefixer"), concat = require("gulp-concat"), del = require("del"), minifyCss = require("gulp-minify-css"), rename = require("gulp-rename"), runSequence = require("run-sequence"), sass = require("gulp-sass"), tsc = require("gulp-tsc"), uglify = require("gulp-uglify"); 

Further, it is very convenient to represent the paths where the source and resulting files are in the form of an object in order to be able to edit them all in one place:

 var paths = { frontend: { scss: { src: [ "styles/*.scss" ], dest: "wwwroot/css" }, ts: { src: [ "scripts/*.ts" ], dest: "wwwroot/js" } }, shared: { bower: { src: "bower_components", dest: "wwwroot/lib" } } } 

And finally, let us describe the main Gulp-task, which will rebuild all scripts and styles, process them and copy to the resulting folder:

 gulp.task( "rebuild", function (cb) { runSequence( "clean", "build", "minify", "delete-unminified", "rename-temp-minified", "delete-temp-minified", cb ); } ); 

The runSequence package allows you to perform tasks one after another, sequentially, which is very important in our case. Also, be sure to pass the cb callback function as the last task in the sequence so that the calling code can be notified of the completion of the entire process.

By the way, in order not to perform the rebuild task manually, you can either force the studio to perform it when building or opening the project, or directly in the Gulp file to add another task (and perform it automatically when you open the project), which will set listeners to change the source files and perform the task when such a change is detected.

Scripts


I loved (and continue) JavaScript for its simplicity and elegance. Now I also love TypeScript. (This is a great tool, I recommend paying attention to it.) I usually keep all ts-files in the Scripts folder, which is ignored when publishing a project. These are source codes of client scripts. I set up several tasks in my Gulp-file, which first compile TypeScript into JavaScript, then compress it, then merge it into one file, and finally copy the resulting file into the wwwroot / js folder, from where it is used in the application. (If you do not use TypeScript, you can simply skip the step of turning it into JavaScript — the remaining tasks will work without changes.)

By default, Visual Studio 2015 compiles ts-files at the moment of their saving and stores the resulting js-files in the same folder. We do not need this behavior, so disable the TypeScript compilation in the project settings.

This is what a TypeScript compilation task looks like:

 gulp.task( "frontend:build-ts", function (cb) { return gulp.src(paths.frontend.ts.src) .pipe(tsc()) .pipe(gulp.dest(paths.frontend.ts.dest)); } ); 

And this is how you can compress the resulting JavaScript and merge it into one result file:

 gulp.task( "frontend:minify-js", function (cb) { return gulp.src(paths.frontend.ts.dest + "/*.js") .pipe(uglify()) .pipe(concat("aspnet5gulpization.min.js.temp")) .pipe(gulp.dest(paths.frontend.ts.dest)); } ); 

When merging many js-files into one, it is possible that they will be added to the resulting file in the wrong order and you will receive messages that something is undefined, since the definition will be located after the call. If this happens, you can easily set the order of the scripts in the resulting file manually. You can even list in the required order those scripts that should follow first, and then the last element of the array just indicate the same folder, and Gulp will guess that you need to first process the files specified in the folder, and then all the others.

By the way, if suddenly you receive an error message when you restore NPM packages (optionally, with a wording consisting of an incoherent sequence of characters), or Visual Studio 2015 just crashes when you try to restore packages, this may be due to the depth of your project in the file system. (Partially, I found information about it here: https://github.com/Microsoft/nodejstools/issues/336 .) After spending some time, I just created an empty project in a less nested folder, copied my package.json there, restored it there packages and then transferred them along with the node_modules folder to your project. Also, in the process of dropping the studio, a damaged package may get into the npm-cache folder, so you should bear this in mind and, if necessary, remove it from there.

Styles


Relatively recently, I decided to try SCSS. The main goal was to be able to edit things like colors in one place, rather than using search and replace. I also decided that it would be great, at the same time, to divide huge css-files into parts in order to make them easier to accompany (in my opinion, accompanying styles, while avoiding trash them, is quite difficult, because the result of changes is difficult to test and not always obvious at first glance). Using SCSS gave a good result.

Similar to TypeScript, my Gulp file contains tasks for compiling SCSS in CSS, adding vendor prefixes, compressing, pasting and copying the resulting file to the wwwroot / css folder.

Compiling SCSS to CSS is as follows:

 gulp.task( "frontend:build-scss", function (cb) { return gulp.src(paths.frontend.scss.src) .pipe(sass()) .pipe(gulp.dest(paths.frontend.scss.dest)); } ); 

Well, compression, gluing (with simultaneous placement of vendor prefixes):

 gulp.task( "frontend:minify-css", function (cb) { return gulp.src(paths.frontend.scss.dest + "/*.css") .pipe(minifyCss()) .pipe(autoprefixer("last 2 version", "safari 5", "ie 8", "ie 9")) .pipe(concat("aspnet5gulpization.min.css.temp")) .pipe(gulp.dest(paths.frontend.scss.dest)); } ); 

Libraries


If in a project on ASP.NET 5 you need, for example, JQuery, you will most likely load it with Bower, and, unlike NuGet, which was used earlier, you will get a little more than just jquery.min.js and a couple others. A jquery folder will be created in the bower_components folder, in which, in addition to the file mentioned above, there will be an uncompressed version of the library, as well as its source code (which, of course, will be ignored when published).

If you think about it, we can use these libraries in at least two ways.

First, you can simply connect the jquery.min.js file to the page by first copying it into the wwwroot / lib / jquery folder. I did this (I don’t know, it’s probably better to use services like Google Hosted Libraries so that in some cases the browser would take the library version cached when visiting another site and not download it again, but more often I don’t do that).

Secondly, you can take an uncompressed version of the library (jquery.js) and process it in the same way that other scripts in the application are processed. That is, as a result, add it to the only common js-file, thus reducing the number of requests to the web server.

Here is the task that copies the necessary files for the three libraries:

 gulp.task( "lib-copy", function (cb) { var lib = { "/jquery": "/jquery/dist/jquery*.{js,map}", "/jquery-validation": "/jquery-validation/dist/jquery.validate*.js", "/jquery-validation-unobtrusive": "/jquery-validation-unobtrusive/jquery.validate.unobtrusive*.js" }; for (var $package in lib) { gulp .src(paths.shared.bower.src + lib[$package]) .pipe(gulp.dest(paths.shared.bower.dest + $package)); } cb(); } ); 

findings


I like what happened in the end. I like the fact that you can easily and conveniently work with styles and scripts and just as easily and conveniently optimize them before publishing, with full control over the process. This, of course, is not the only thing that Gulp can help with, but I think this is enough to fully understand its capabilities.

To authors


Friends, if you are interested in supporting the column with your own material, please write to me at vyunev@microsoft.com to discuss all the details. We are looking for authors who can interestingly tell about ASP.NET and other topics.

about the author


Sikorsky Dmitry Alexandrovich
Jubreynians Company (http://ubrainians.com/)
Owner, Head
DmitrySikorsky

Source: https://habr.com/ru/post/273493/


All Articles