12/08/2018, 13:33

Automate task with gulp

Trong quá trình phát triển và xây dựng dự án, các lập trình viên frontend có thể bắt gặp những công việc lặp đi lặp lại nhiều lần như: reload lại trình duyệt khi có một file được thay đổi, compile và kiểm lỗi các file javascript, minify các file javascript, css, gộp các file css riêng lẻ thành một ...

Trong quá trình phát triển và xây dựng dự án, các lập trình viên frontend có thể bắt gặp những công việc lặp đi lặp lại nhiều lần như: reload lại trình duyệt khi có một file được thay đổi, compile và kiểm lỗi các file javascript, minify các file javascript, css, gộp các file css riêng lẻ thành một file hay compile less ra css, v.v.. Việc lặp lại các công việc này nhiều lần không những gây nhàm chán cho lập trình viên mà còn cho hiệu quả làm việc không cao. May mắn thay, các task-runner ra đời nhằm giải quyết các công việc mang tính lặp đi lặp lại này, tăng năng suất làm việc và Gulp là một công cụ như vậy.

Bản thân gulp không có gì to tát, công việc của nó đơn giản chỉ là định nghĩa ra các task và duyệt tất cả các file mà ta muốn. Tài liệu chính thức của gulp cũng chỉ cung cấp 4 API đó là gulp.src | gulp.dest | gulp.task | gulp.watch. Tuy nhiên, sức mạnh thực sự của gulp nằm kho plugin khổng lồ mà nó cung cấp, giúp cho lập trình viên có thể tự động hóa hầu hết các thao tác lặp nhàm chán khi phát triển website.

Việc cài đặt Gulp tương đối dễ dàng, bao gồm các bước như sau: (lưu ý, để cài đặt được gulp, trước hết cần đảm bào node.js và npm đã cài đặt trước đó)

  1. Cài đặt Gulp thông qua npm ở toàn cục (globally)
$ npm install --global gulp
  1. Cài đặt Gulp trong thư mục của dự án như là một dependency của dự án đó. Cần đảm bảo trong thư mục dự án đã tồn tại file package.json. File này có thể tạo bằng tay hoặc sự dụng lệnh npm init. Khi đã có file package.json rồi, tiến hành cài đặt gulp
$ npm install --save-dev gulp
  1. Cuối cùng, ta cần tạo file gulpfile.js chứa các task cần chạy trong thư mục gốc của dự án. Đồng thời để tiện theo dỗi và log ra việc thực thi task, mình sẽ add thêm plugin `gulp utilites
$ npm install --save-dev gulp-util

Trong fule gulpfile.js, ta sẽ tạo ra một task đơn giản log ra việc thực thi Gulp

// File: gulpfile.js

// include library
var gulp  = require('gulp'),
gutil = require('gulp-util');

// tạo ra task default để log message
gulp.task('default', function() {
  return gutil.log('Gulp is running!')
});

Thực thi file bằng cách chạy câu lẹnh gulp, kết quả thu được sẽ tương tự như sau:

> gulp
[23:08:25] Using gulpfile ~/06_2016/gulpfile.js
[23:08:26] Starting 'default'...
[23:08:26] Gulp is running
[23:08:26] Finished 'default' after 6

Sơ qua về Gulp

Gulp API bao gồm 4 function chính là

  • gulp.task
  • gulp.src
  • gulp.dest
  • gulp.watch

gulp.task định nghĩa ra task cần thực hiện. Các tham số của function này bao gồm name, deps và fn. Trong đó name là tên task, deps là danh sách các task phụ thuộc (tham số này có thể có hoặc không) và fn chính là nội dung task thực hiện

gulp.task('mytask', function() {
  //thực hiện task
});

gulp.task('dependenttask', ['mytask'], function() {
  //thực hiện task sau khi thực hiện xong 'mytask'
});

gulp.src trỏ tới danh sách các file đầu vào. Tham số của function này là globs và một options object (có thể có hoặc không).

gulp.dest dùng để trỏ tới thư mục output.

gulp.src và gulp.dest có thể được sử dụng cùng nhau để copy file như sau:

gulp.task('copyHtml', function() {
  // copy bất kỳ html files từ source/ tới public/
  gulp.src('source/*.html').pipe(gulp.dest('public'));
});

Để thực hiện các task một cách tự động, gulp cung cấp function là gulp.watch. Với function này, ta có thể cài đặt để các task trong gulp tự động được thực hiện khi nội dung của các tâp tin mà ta cần theo dõi thay đổi.

gulp.task('watch', function(){
  gulp.watch('app/scss/*.scss', ['sass']);
});

Câu lệnh này thông báo với Gulp rằng nó sẽ cần phải theo dõi tất cả các tập tin có đuôi là .scss đặt trong thư mục app/scss và khi nào có thay đổi nội dung của 1 trong các tập tin trong thư mục thì task được đặt tên là sass sẽ được thực hiện.

Cấu trúc thư mục project demo trong bài viết

public/
  |  assets/
  |  |  stylesheets/
  |  |  |  style.css
  |  |  javascript/
  |  |  |  vendor/
  |  |  |  |  jquery.min.js
  |  |  |  bundle.js
source/
  |  javascript/
  |  |  courage.js
  |  |  wisdom.js
  |  |  power.js
  |  scss/
  |  |  styles.scss
  |  |  grid.scss
gulpfile.js
packages.json

Trong đó, source là thư mục mà dev thực sự làm việc. assets/styles.css sẽ được tạo ra bởi gulp khi ta xử lý và nối tất cả các file SASS trong thư mục source/scss thành 1 file duy nhất. Tương tự bundle.js được tạo ra bởi gulp khi ta thực hiện minify và nối tất cả các file js thành 1 file duy nhất.

Thực hiện task với gulp

Trong phần sau, ta sẽ cùng nhau thực hiện cài đặt một số task đơn giản mà thực sự hữu ích (yeah)

Jshint on save

Trong task này, ta sẽ thực hiện check lỗi trong file javascript mỗi khi file đó được lưu, sử dụng plugin jshint.

Trước khi bắt đầu, ta sẽ cài đặt gói gulp-jshint với npm, đồng thời format output cho nó có màu mè một chút với plugin jshint-stylish =))

$ npm install --save-dev jshint gulp-jshint jshint-stylish

Thực hiện cài đặt task như sau:

var gulp = require('gulp'),
    jshint = require('gulp-jshint');

// tao task default, va them task 'watch', task nay se duoc thuc hien cung task default
gulp.task('default', ['watch']);

// config task jshint, no se detech bat cu file .js  nao trong thu muc javascript va check loi roi cho ra output ket qua cua viec kiem tra
gulp.task('jshint', function() {
  return gulp.src('source/javascript/**/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
});

// config file ma ta can theo doi su that doi va task se thuc hien khi phat hien thay doi
gulp.task('watch', function() {
  gulp.watch('source/javascript/**/*.js', ['jshint']);
});

Sau đó chỉ việc chạy task bằng lệnh sau

$ gulp

hoặc chạy bằng quyền sudo nếu báo lỗi về quyền.

Thực hiện thay đổi file js bất kỳ trong thư mục source/javascript và xem thành quả đạt được trong console (yeah)

Biên dịch Sass với libsass

SASS là một CSS Prepocessor (như LESS) giúp viết CSS nhanh hơn và có cấu trúc rõ ràng hơn. Với SASS, ta có thể viết CSS theo thứ tự rõ ràng, quản lý các biến đã được định nghĩa sẵn, có thể tự động nén tập tin CSS lại để tiết kiệm dung lượng. SASS có hai loại chính đó là Sass và SCSS và mỗi loại có một cách viết khác nhau, xem code dưới đây để dễ hiểu hơn.

Sass:

#menu
    li
        background: red
        color: #FFF
    a
        color: yellow
        padding: 20px

SCSS:

#menu{
    li {
        background: red;
        color: #FFF;
    }
    a{
        color: yellow;
        padding: 20px;
    }
}

Cả hai ví dụ trên khi biên dịch sẽ cho ra kết quả như sau:

#menu li {
  background: red;
  color: #FFF;
}

#menu a {
  color: yellow;
  padding: 20px;
}

Khi sử dụng SASS thì trình duyệt sẽ không hiểu được nên ta phải thông qua giai đoạn biên dịch file SASS thành file CSS và công việc này đòi hỏi ta phải cài đặt một thư viện hoặc phần mềm thứ ba. Vì vậy trong phần tiếp theo đây, ta sẽ viết task sử dụng gulp-sass để biên dịch SASS:

/* file: gulpfile.js */

var gulp   = require('gulp'),
    jshint = require('gulp-jshint'),
    sass   = require('gulp-sass');

/* jshint task */

gulp.task('build-css', function() {
  return gulp.src('source/scss/**/*.scss')
    .pipe(sass())
    .pipe(gulp.dest('public/assets/stylesheets'));
});

/* cập nhật thêm task build-css */

gulp.task('watch', function() {
  gulp.watch('source/javascript/**/*.js', ['jshint']);
  gulp.watch('source/scss/**/*.scss', ['build-css']);
});

Javascript concat và minify

Khi phải làm việc với nhiều file javascript, sẽ tới một thời điểm nào đó (deploy production, ..) mà ta cần 'nén' lại tất cả các file javascript lại thành một file duy nhất nhằm tiết kiệm băng thông và tăng tốc độ tải của trang web. Điều này có thể được thực hiện dễ dàng với plugin gulp-concat:

gulp.task('build-js', function() {
  return gulp.src('source/javascript/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(concat('bundle.js'))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('public/assets/javascript'));
});

Trên đây mình đã giới thiệu sơ qua về task runner gulp. Hi vọng bài viết sẽ giúp ích phần nào cho bạn đọc khi phải làm việc nhiều với front-end. (yeah)(lay2).

Nguồn tham khảo

  1. cotch.io
  2. Gulp API doc
  3. http://www.hoclaptrinh.org/bai-viet/Tim-Hieu-Ve-Gulp-js
0