Gulp: Vũ khí bí mật của một web developer (P.1)

Chúng ta thường phải xử lý web base project sử dụng trong sản xuất, cung cấp nhiều dịch vụ khác nhau. Khi gặp phải với các dự án như vậy thì việc xây dựng và triển khai code nhanh chóng là điều quan trọng. Làm nhanh thì thường dẫn đến sai sót, nhất là với process lặp đi lặp lại nhiều lần, do đó cần phải thực hành nhiều để tự động hóa process tốt hơn.
Trong bài này, chúng tôi sẽ giới thiệu một tool mới, có thể sẽ là một phần cho phép thực hiện tự động hóa. Tool này là npm package có tên Gulp.js. Để biết thêm về các thuật ngữ Gulp.js cơ bản được sử dụng trong bài viết này, xin vui lòng tham khảo “An Introduction to JavaScript Automation with Gulp” đã được đăng trên blog của Antonios Minas, một trong những nhà đồng phát triển Toptal.
Bài viết dưới đây sẽ sử dụng môi trường npm để install package.
Phục vụ Front-End Asset
Trước khi tiếp tục, hãy xem lại một vài bước để có được cái nhìn tổng quan mà Gulp.js có thể giải quyết. Nhiều dự án web-based mô tả front-end JavaScript file để cung cấp các chức năng khác nhau cho trang web của khách hàng. Thông thường cũng có một set CSS stylesheet được phục vụ cho khách hàng. Đôi khi nhìn vào source code của một website hay một web application, chúng ta có thể nhìn thấy code kiểu này:
<link href="css/main.css" rel="stylesheet">
<link href="css/custom.css" rel="stylesheet">
<script src="js/jquery.min.js"></script> 
<script src="js/site.js"></script> 
<script src="js/module1.js"></script> 
<script src="js/module2.js"></script>
Có một vài vấn đề với đoạn code này. Nó có reference để hai CSS riêng biệt và bốn JavaScript file riêng. Điều này có nghĩa là, server phải thực hiển tổng cộng sáu request đến server, và mỗi request phải load resource riêng trước khi trang web sẵn sàng. Với HTTP/2 thì ít xảy ra vấn đề hơn vì HTTP/2 giới thiệu parallelism và header compression, nhưng nó vẫn còn là một vấn đề. Nó làm tăng tổng volume traffic khi bị request để load page, và làm giảm chất lượng trải nghiệm người dùng vì phải mất thời gian để load file.
Trong trường hợp của HTTP 1.1, nó cũng cắt ngắn network và làm giảm số lượng request channel hiện có. Sẽ tốt hơn khi kết hợp CSS và JavaScript file vào một gói duy nhất. Bằng cách đó, sẽ chỉ có tổng cộng hai request. Nó cũng sẽ phục vụ các phiên bản rút gọn của những file này tốt hơn, thường là nhỏ hơn nhiều so với bản gốc. Web application của chúng tôi cũng có thể phá vỡ nếu có cached asset bất kỳ, và khách hàng sẽ nhận được một phiên bản outdated.
2
Một cách tiếp cận cơ bản để giải quyết vấn đề là tự kết hợp từng loại asset vào một gói sử dụng trình text editor, và sau đó chạy kết quả thông qua một minifier service, như http://jscompress.com/. Một cải tiến nhỏ sẽ host minifier server, sử dụng một trong các package có sẵn trên GitHub. Sau đó, chúng ta có thể làm tương tự như sau:
<script src="min/f=js/site.js,js/module1.js"></script>
Nó sẽ phục vụ các minified files cho khách hàng, nhưng nó sẽ không giải quyết được vấn đề của bộ nhớ đệm (caching). Nó cũng sẽ gây ra additional load trên server.
Tự động hoá với Gulp.js
Chắc chắn chúng ta có thể làm tốt hơn so với hai phương pháp này. Những gì chúng tôi thực sự muốn là để automate bundling và gắn nó vào build phase trong dự án. Chúng tôi muốn kết thúc pre-built asset bundles đã được minified và sẵn sàng phục vụ. Đồng thời, chúng tôi cũng muốn buộc khách hàng nhận up to date version của các gói asset trong từng request, nhưng vẫn cần tận dụng bộ nhớ đệm.
May mắn là Gulp.js có thể xử lý được chuyện này. Trong phần còn lại của bài viết, chúng tôi sẽ xây dựng một giải pháp giúp tận dụng sức mạnh của Gulp.js tiếp nhau và rút gọn file.
Tạo directory và file structure như sau:
public/
|- build/
   |- js/
      |- bundle-{hash}.js
   |- css/
      |- stylesheet-{hash}.css
assets/
|- js/
   |- vendor/
   |- jquery.js
   |- site.js
   |- module1.js
   |- module2.js
|- css/
   |- main.css
   |- custom.css
gulpfile.js
package.json
File gulpfile.js sẽ xác định task mà Gulp sẽ thực hiện. npm sử dụng package.json để xác định application package và track dependency (sự phụ thuộc) mà chúng ta sẽ cài đặt. Các public directory là những gì nên được configure để đối mặt với web. Các asset directory là nơi sẽ lưu source file. Để sử dụng Gulp trong project, ta sẽ cần phải cài đặt nó thông qua npm, và save lại như là một developer dependency cho dự án. Chúng tôi cũng muốn bắt đầu với các concat plugin cho Gulp, cho phép tiếp nhiều file thành một file.
Để cài đặt hai item này, chúng ta sẽ chạy lệnh sau:
npm install --save-dev gulp gulp-concat
Tiếp đến là bắt đầu viết content cho gulpfile.js.
var gulp = require('gulp');
var concat = require('gulp-concat');
 
gulp.task('pack-js', function () { 
 return gulp.src(['assets/js/vendor/*.js', 'assets/js/main.js', 'assets/js/module*.js'])
  .pipe(concat('bundle.js'))
  .pipe(gulp.dest('public/build/js'));
});
 
gulp.task('pack-css', function () { 
 return gulp.src(['assets/css/main.css', 'assets/css/custom.css'])
  .pipe(concat('stylesheet.css'))
  .pipe(gulp.dest('public/build/css'));
});
 
gulp.task('default', ['pack-js', 'pack-css']);
Và đây, chúng tôi đang load gulp library và concat plugin. Sau đó chúng tôi xác định 3 task sau.
3
Task đầu tiên (pack-js) xác định procetrure để nén nhiều source file JavaScript vào một gói. Chúng tôi liệt kê các source file sẽ được globbed, đọc, và kết nối theo thứ tự quy định. Chúng tôi đặt vào các concat plugin để có được một tập tin cuối cùng được gọi là bundle.js. Cuối cùng, chúng tôi lệnh cho Gulp để viết file thành public/build/js.
Task thứ hai (pack-css) làm điều tương tự như trên, nhưng là với CSS stylesheet. Nó sẽ lệnh cho Gulp để lưu trữ concatenated output như stylesheet.css trong public/build/css.
Task thứ ba (default) là điều mà Gulp sẽ chạy. Trong tham số thứ hai, chúng tôi đưa danh sách các task khác để thực thi khi default task đã chạy.
Paste đoạn code này vào gulpfile.js, sử dụng bất kỳ source code editor mà chúng tôi thường sử dụng, và sau đó lưu file vào application root.
Tiếp theo, chúng tôi sẽ mở command line và chạy:
gulp
Nếu nhìn vào các file sau khi chạy lệnh này, bạn sẽ tìm thấy hai file mới: public/build/js/bundle.js và công public/build/css/stylesheet.css. Đây là những concatenations của các source file, nó sẽ giải quyết một phần của các vấn đề ban đầu. Tuy nhiên nó không bị giảm bớt và không có bộ nhớ cache busting nào.
Trong phần tiếp theo, chúng ta sẽ tiếp tục với Optimizing Built Assets và Cache Busting.

No comments:

Post a Comment

The Ultimate XP Project

  (Bài chia sẻ của tác giả  Ryo Amano ) Trong  bài viết  số này, tôi muốn viết về dự án phát triển phần mềm có áp dụng nguyên tắc phát triển...