12/08/2018, 12:52

Grunt - Javascript task runner

Trong bài viết này, tôi sẽ giới thiệu Grunt và một số task của nó giúp bạn cải thiện tốc độ tải trang. Nếu bạn đang viết những ứng dụng Javascript hoặc đang phát triển một trang Web, bạn sẽ cần đến các công cụ giúp bạn một số việc như minify css, js, hoặc biên dịch scss, coffeescript, v.v... ...

grunt-the-js-task-runner.jpg

Trong bài viết này, tôi sẽ giới thiệu Grunt và một số task của nó giúp bạn cải thiện tốc độ tải trang.

Nếu bạn đang viết những ứng dụng Javascript hoặc đang phát triển một trang Web, bạn sẽ cần đến các công cụ giúp bạn một số việc như minify css, js, hoặc biên dịch scss, coffeescript, v.v... Những công việc này hoàn toàn có thể sử dụng những công cụ riêng biệt. Tuy nhiên, nếu chỉ cần đến 1 hoặc 2 công cụ thì có thể dùng riêng được, chứ nếu có nhiều công việc cần làm thì thực hiện chúng một cách riêng rẽ đúng là cực hình. Khi đó bạn cần đến các công cụ có thể chạy các tools đó hoàn toàn tự động.

Một số framework như Rails có cơ chế assets pipline và có thể đặt rake task. Tuy nhiên không phải lúc nào framework cũng có những công cụ như vậy. Khi đó bạn cần các tools chạy task bên ngoài.

Hiện nay có nhiều công cụ khác nhau, nhưng phổ biến hơn cả là Grunt và Gulp. Grunt có khoảng 15000 download mỗi ngày. Grunt là một tasks runner cho phép bạn cấu hình và gọi các task hoàn toàn tự động.

Grunt là một task runner chạy bằng javascript đúng như tên gọi ở trên, nó là một chương trình dùng để gọi các chương trình khác. Những chương trình đó gọi là task của grunt. Thông thường các task này được sử dụng như các công cụ trong quá trình phát triển nên nó còn được gọi là build system.

Grunt là task runner nên nó phụ thuộc vào các plugin để chạy các task của mình. Công việc của nó chỉ đơn giản là gọi và thực thi các task này.

Việc config Grunt có thể hơi khó khi mới bắt đầu. Nhưng nếu đã quen rồi thì mọi chuyện rất đơn giản. Một khi đã config xong, mỗi khi cần chạy, bạn chỉ cần gõ lệnh

$ grunt

là các task sẽ được gọi là thực hiện lần lượt theo config của bạn.

Grunt là task runner chạy bằng Javascript nên để chạy được, máy bạn cần được cài Nodejs.

Cài đặt Nodejs

Cài Nodejs bằng lệnh sau:

$ sudo apt-get install nodejs

Sau khi cài Nodejs, Grunt và các plugin của nó có thể dễ dàng cài đặt thông qua npm - trình quản lý package của Nodejs. Grunt version 0.4 yêu cầu Nodejs version từ 0.8 trở nên. Trước khi cài đặt Grunt, có thể bạn cần update npm với lệnh sau:

$ npm update -g npm

Cài Grunt CLI

Để sử dụng lệnh grunt trên Terminal hoặc các trình shell khác, bạn cần cài Grunt CLI bằng lệnh sau. Có thể bạn cần đến sudo tùy vào OS của bạn:

$ npm install -g grunt-cli

Tùy chọn -g ở trên nghĩa là grunt-cli sẽ được cài cho toàn hệ thống. Bạn có thể bỏ nó đi nếu chỉ muốn cài riêng cho project của mình. Nhưng tôi nghĩ bạn nên cài nó để có thể dùng ở tất cả project.

Sau khi cài đặt, bạn có thể gọi lệnh grunt từ shell. Tuy nhiên, việc cài đặt cli hoàn toàn không liên quan đến cài dặt bản thân Grunt task runner. Grunt CLI chỉ có nhiệm vụ là gọi grunt và các task được config ở Grunfile. Với cách làm này, nó cho phép bạn sử dụng nhiều phiên bản grunt khác nhau với các project khác nhau.

Các package được cài bởi npm thường lưu trong thư mục node_packages và bạn có thể ignore nó nếu sử dụng git hoặc các trình quản lý version tương tự.

Việc config Gruntfile tôi sẽ nói ở phần tiếp theo đây.

Config grunt

Config thông thường của Grunt sẽ gồm 2 file: package.json và Gruntfile được đặt ở thư mục gốc project của bạn. Tuy nhiên bạn có thể đặt chúng ở bất cứ đâu tùy theo cấu trúc project. Khi đó, bạn cần sử dụng config grunt.file.setBase để đặt đường dẫn về thư mục gốc của project. Ví dụ tôi đặt Gruntfile và package.json Trong thư mục grunt thì config của tôi sẽ là:

grunt.file.setBase("../")

File package.json là file mà npm dùng để lưu các thông tin liên quan đến project. Nó sẽ có danh sách Grunt và các plugin cần thiết của project trong phần devDependencies.

Gruntfile là file có tên đầy đủ là Gruntfile.js hoặc Gruntfile.coffee and nó dùng để lưu các config chính liên quan đến các task của Grunt. Gruntfile có thể là một trong 2 file trên, js hoặc coffee tùy theo nhu cầu của bạn và project của bạn sử dụng javascript hay coffeescript.

Khi config 2 file trên, chạy npm install nó sẽ tự động cài đặt các package cần thiết để có thể chạy các task của Grunt. Có 1 số cách để tạo file package.json như sau:

  • Sử dụng grunt-init nó sẽ tự động tạo file package.json cho project của bạn, sau khi bạn confirm một số thông tin cần thiết.
  • Sử dụng npm init sẽ tạo ra một file package.json đơn giản.
  • Tùy vào nhu cầu của bạn, bạn có thể tự viết file package.json cho mình hoặc edit file được tạo ra từ 2 cách trên.

Dưới đây là một ví dụ của file package.json

{
  "name": "my-project-name",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-jshint": "~0.10.0",
    "grunt-contrib-nodeunit": "~0.4.1",
    "grunt-contrib-uglify": "~0.5.0"
  }
}

Config package.json và cài Grunt cùng các plugin

Có một cách khá dễ dàng để cài đặt Grunt và các plugin của nó. Đó là sử dụng lệnh:

$ npm install <module> --save-dev

Sử dụng lệnh trên, không chỉ các gói cần thiết được cài đặt, mà nó còn tự động thêm module và phần devDependencies của file package.json.

Ví dụ, lệnh dưới đây sẽ cài đặt Grunt và thêm vào devDependencies:

$ npm install grunt --save-dev

Sử dụng lệnh tương tự với các plugin của Grunt. Nếu như bạn làm việc với một project đã có sẵn config của Grunt. Đơn giản, bạn chỉ cần chạy lệnh

$ npm install

trong cùng thư mục với config đó. Nó sẽ tự động đọc file package.json và cài đặt các gói cần thiết đã được định nghĩa trong đó.

Config Gruntfile

Gruntfile (Gruntfile.js hoặc Gruntfile.coffee) là một file javascript (hoặc coffeescript) dùng để config cho việc hoạt động của Grunt.

Một Gruntfile cần có các thành phần sau:

  • Hàm wrapper
  • Config cho project và các task
  • Load các plugin và tasks
  • Tùy biến task.

Dưới đây là một ví dụ của Gruntfile. Các thông tin của project được đọc từ file package.json. Gruntfile định nghĩa task uglify để nén các file Javascript. Khi chạy lênh grunt thì default task uglify sẽ được gọi.

module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */
'
      },
      build: {
        src: 'src/<%= pkg.name %>.js',
        dest: 'build/<%= pkg.name %>.min.js'
      }
    }
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');

  // Default task(s).
  grunt.registerTask('default', ['uglify']);
};

Bây giờ, tôi sẽ giải thích từng thành phần của Gruntfile thông qua ví dụ trên.

Hàm wrapper

Tất cả các Gruntfile để được config với mẫu như trên, cho dù nó thay đổi tùy theo project. Bạn có thể tự viết config cho riêng mình, vì suy cho cùng thì đây cũng là code Javascript mà nó hoạt động như những file Javascript khác. Tuy nhiên, không nên làm như vậy ví đó không phải là con đường dễ dàng và việc config Grunt cũng không phải là ưu tiên của project.

Hàm wrapper là hàm sẽ bao trọn toàn bộ hoạt động của Grunt. Tất cả các config của Grunt và các task của nó đề đặt ở trong hàm này. Hàm này sẽ như sau:

module.exports = function(grunt) {
  Các config khác của Grunt đặt ở đây
};

Config của project và các task

Các task Grunt đề phụ thuộc vào config được định nghĩa bên trong grunt.initConfig.

Trong ví dụ của chúng ta, grunt.file.readJSON('package.json') sẽ đọc thông tin JSON từ file package.json. Trong file, các block <% %> là template engine của riêng Grunt và bạn có thể đặt trong đó các biến, tương tự như template engine của các framework lập trình Web thông thường.

Các task của Grunt, trong trường hợp của chúng là uglify, cần được config mới có thể hoạt động được. Trong trường hợp của chúng ta, task này nhận tùy chọn là thêm banner lên trên cùng của file kết quả.

// Project configuration.
grunt.initConfig({
  pkg: grunt.file.readJSON('package.json'),
  uglify: {
    options: {
      banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */
'
    },
    build: {
      src: 'src/<%= pkg.name %>.js',
      dest: 'build/<%= pkg.name %>.min.js'
    }
  }
});

Load Grunt và các plugin

Rất nhiều công cụ liên quan đến quá trình phát triển như cssmin, jsmin, linter, v.v... đều có sẵn các plugin của Grunt tương ứng. Và nếu chúng được định nghĩa trong package.json thì chúng sẽ được npm cài đặt.

Để gọi chúng, ở Gruntfile chúng ta cần load Grunt và các plugin này.

// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');

Trên đây tôi đã giới thiệu Grunt và cách config chúng cho project của bạn. Tùy vào nhu cầu của bạn, bạn có thể sử dụng nó tùy ý để phục vụ cho công việc của mình. Phần tiếp theo, tôi sẽ giới thiệu một số task của Grunt giúp cải thiệu hiệu suất của trang Web, cụ thể là cải thiện tốc độ tải trang.

Dưới đây tôi sẽ giới thiệu một số task thông dụng và rất hữu ích để cải thiện hiệu suất trang Web của bạn.

  • grunt-contrib-imagemin
  • grunt-contrib-uglify
  • grunt-contrib-cssmin
  • grunt-uncss
  • grunt-contrib-htmlmin

Bạn có thể tìm hiển các task trên từ chính trang chủ của chúng. Trong bài viết tiếp theo, có thể tôi sẽ dành thời gian để viết chi tiết về các task này.

Bài viết gốc: https://manhhomienbienthuy.bitbucket.io/2015/Nov/15/grunt-and-5-tasks-to-improve-web-performance.html (đã xin phép tác giả             </div>
            
            <div class=

0