12/08/2018, 12:23

Tìm hiểu về Grunt

1. Giới thiệu chung Grunt là 1 công cụ dòng lệnh dựa trên các task dùng để hỗ trợ các project javascript. Grunt được sử dụng trong nhiều công ty, dự án như Twitter, Adobe, jQuery Chúng ta có thể coi Grunt là 1 công cụ để build code cũng như tự động các task lặp đi lặp lại (task runner). Công ...

1. Giới thiệu chung

Grunt là 1 công cụ dòng lệnh dựa trên các task dùng để hỗ trợ các project javascript.

Grunt được sử dụng trong nhiều công ty, dự án như Twitter, Adobe, jQuery

Chúng ta có thể coi Grunt là 1 công cụ để build code cũng như tự động các task lặp đi lặp lại (task runner). Công việc của task runner có thể kể đến như nén, biên dịch các file css, javascript, chạy unit test.

Tại sao nên sử dụng grunt

  • Hệ sinh thái Grunt rất lớn và phong phú
  • Số lượng plugin lớn, hỗ trợ tốt việc chạy tự động các task

2.Cài đặt grunt

Để cài đặt grunt trước hết chúng ta cần cài đặt nodejs. Hướng dẫn cài đặt node.js cóp thể tham khảo tại đây. Sau khi cài đặt xong nodejs việc tiếp theo là cài đặt grunt trên terminal.

npm install grunt-cli -g

Tiếp đó là khởi tạo dự án

npm init

Sau lệnh này file package.json được tạo ra để lưu thông tin của dự án và các thư viện phụ thuộc.

Dưới đây là 1 file package.json ở dạng rất đơn giản

{
  "name": "grunt",
  "version": "1.0.0",
  "description": "test grunt",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "demo author",
  "license": "ISC"
}

Trên thực tế sau khi cài đặt các thư viện, package liên quan, keyword, các ràng buộc phụ thuộc về các phiên bản thư viện được sử dụng 1 file package.json hoàn chỉnh sẽ trông như thế này

{
  "name": "grunt",
  "description": "test grunt",
  "version": "1.0.0",
  "author": "demo author",
  "repository": "gruntjs/grunt",
  "engines": {
    "node": ">=0.8.0"
  },
  "scripts": {
    "test": "grunt test",
    "test-tap": "grunt test:tap"
  },
  "main": "lib/grunt",
  "keywords": [
    "task",
    "async",
    "cli",
    "minify",
    "uglify",
    "build",
    "lodash",
    "unit",
    "test",
    "qunit",
    "nodeunit",
    "make",
    "jake",
    "tool"
  ],
  "dependencies": {
    "async": "~0.1.22",
    "coffee-script": "~1.3.3",
    "colors": "~0.6.2",
    "dateformat": "1.0.2-1.2.3",
    "eventemitter2": "~0.4.13",
    "exit": "~0.1.1",
    "findup-sync": "~0.1.2",
    "getobject": "~0.1.0",
    "hooker": "~0.2.3",
    "nopt": "~1.0.10",
    "rimraf": "~2.2.8",
    "underscore.string": "~2.2.1",
    "which": "~1.0.5"
  },
  "devDependencies": {
    "difflet": "~0.2.3",
    "grunt-contrib-jshint": "~0.6.4",
    "grunt-contrib-nodeunit": "~0.4.1",
    "grunt-contrib-watch": "~0.5.3",
    "grunt-jscs": "~1.5.0",
    "semver": "2.1.0",
    "shelljs": "~0.2.5",
    "temporary": "~0.0.4"
  },
  "files": [
    "lib"
  ]
}

Sau khi cấu hình xong chúng ta cần chạy lệnh

npm install

để cài đặt các plugin và module cần thiết cho dự án

npm_install

3. Cấu hình grunt

Grunt sử dụng Gruntfile.js (cùng thư mục với package.json) để đọc các thông tin cấu hình cho các task runner.

Trong file Gruntfile.js này chúng ta sẽ định nghĩa công việc của các task runner (ví dụ như minify các file css và js, chạy 1 số unit test).

module.exports = function (grunt) {

    // Load the Grunt plugins.
    require('matchdep')
        .filterDev('grunt-*')
        .forEach(grunt.loadNpmTasks);
    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'), cssmin: {
            sitecss: {
                options: {
                    banner: '/* LicenseMgr Minified css file */'
                }, files: {
                    'client/public/css/site.min.css': [
                        'client/public/stylesheets/app.css',
                        'client/public/stylesheets/appgrid.css',
                        'client/public/stylesheets/carousel.css',
                        'client/public/stylesheets/forms.css'
                    ]
                }
            }
        }, uglify: {
            options: {
                report: 'min',
                compress: true,
                mangle: true
            },
            'ng-app-min': {
                files: {
                    'client/public/js/ng/site.min.js': [
                        'client/scripts/home/site.js',
                        'client/scripts/home/one.js'
                    ],
                    'client/public/js/ng/licensemgr.min.js': [
                        'client/scripts/models/routingConfig.js',
                        'client/scripts/licensemgr/one.js'
                    ]
                }
            }
        }, ngAnnotate: {
            options: {
                singleQuotes: true
            },
            app1: {
                files: {
                    'client/scripts/home/one.js': [
                        'client/scripts/home/app.js',
                        'client/scripts/home/services.js',
                        'client/scripts/home/controllers.js',
                        'client/scripts/home/filters.js',
                        'client/scripts/home/directives.js'
                    ]
                }
            }
        }
    });

    // Register the default tasks.
    grunt.registerTask('default', ['ngAnnotate', 'uglify', 'cssmin']);
};

Phần require('matchdep') có nhiệm vụ load toàn bộ các module được khai báo trong file package.json. Nếu không có phần này, chúng ta cần phải load các module 1 cách thủ công hơn bằng cách sử dụng

grunt.loadNpmTasks(Module name)

Trong ví dụ trên có thể thấy có những task sau được định nghĩa

  • CSSmin: build và minify các file css
  • Uglify: build và minify các file js
  • ngAnnotate: thêm xóa các kí pháp của Angular

Trong phần định nghĩa các task, các file resource đầu vào cũng như file đầu ra sau quá trình chạy task sẽ được chỉ rõ, ngoài ra có thêm 1 số tùy chọn khác (ví dụ như có thực hiện nén file hay không)

Ở phía cuối file định nghĩa mức độ ưu tiên, thứ tự thực hiện các task tại

grunt.registerTask('default', ['ngAnnotate', 'uglify', 'cssmin']);

Các task runner sẽ được thực hiện theo đúng thứ tự được khai báo tại đây để cho ra kết quả cuối cùng.

4. Grunt vs Gulp

Giống như grunt, gulp cũng là 1 công cụ để hỗ trợ việc tự động hóa các task và cũng đang được sử dụng khá nhiều. Vậy điểm khác biệt giữa grunt và gulp là gì

4.1 Cộng đồng phát triển, người sử dụng

Grunt được phát triển từ sớm hơn và có được số người sử dụng nhiều hơn. Số lượt tải về của Grunt là nhiều hơn hẳn.

Cũng do được phát triển từ sớm nên grunt hỗ trợ nhiều plugin hơn (4000 so với 1200 của gulp).

4.2 Tốc độ

Grunt sử dụng các file trung gian tạm thời trong quá trình biên dịch các file css và js trong khi Gulp xử lí các thao tác đó trong bộ nhớ. Do đó Gulp có lợi thế hơn hẳn trong cuộc đua vầ tốc độ.

Với các dự án qui mô nhỏ, sự khác biệt về tốc độ là không đáng kể nhưng đối với các dự án lớn thì sử dụng gulp đem lại sự khác biệt đáng kể về hiệu năng.

4.3 Cấu hình

Gulp là 1 ví dụ tốt về "code over configuration", việc cấu hình trong gulp đơn giản hơn, dễ đọc, dễ debug hơn, và file cấu hình ngắn gọn hơn.

Kết luận

Nếu muốn sử dụng được nhiều plugin hơn được hỗ trợ tốt hơn bạn nên dùng grunt còn nếu dự án cần ưu tiên tốc độ xử lí hơn và không yêu cầu quá nhiều các thư viện phức tạp hãy chọn gulp

0