Viblo Learning
+2

Sử dụng npm như một Build Tool

Trong bài viết lần trước, tôi có đề cập đến việc sử dụng Buil Tool Gulp. Sử dụng Gulp rất tiện lợi, tuy nhiên cũng có rất nhiều nhược điểm.

  • Dễ phình code: Khi muốn chạy bất kỳ một task nào thì chúng ta cần cài thêm ít nhất một plugin.
  • Phụ thuộc vào plugins: không có plugin bản thân gulp không có ý nghĩa.
  • Khó khăn trong việc cập nhật: Khi muốn cập nhật phiên bản cho các plugins hay chính gulp thì việc chọn phiên bản phù hợp cũng là điều tương đối khó khăn.
  • Khi xảy ra lỗi, output file sẽ chứa log lỗi nên ứng dụng sẽ không chạy đúng cho đến khi sửa xong lỗi và build lại.

Vậy câu hỏi đặt ra là, liệu có một build tool tốt hơn nữa không. Trong bài viết này tôi sẽ giới thiệu đến một build tool như thế. Đó là sử dụng npm như một build tool.

Npm là gì?

NPM viết tắt của từ Node Packaged Modules, nôm na là quản lý và sử dụng các module được tải về và sử dụng trong dự án của bạn dưới dạng gói thông qua command hoặc các file nén từ github.

Npm scripts

Trước tiên ta cần tạo một file package.json để có thể quản lý việc build scripts.

$: npm init

sẽ tự động tạo một file package.json với các thông tin như name, version, description ... như sau

{
  "name": "blog",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "devDependencies": {
    "jshint": "latest",
    "browserify": "latest",
    "mocha": "latest"
  },
  "scripts": {
    "lint": "jshint **.js",
    "test": "mocha test/"
  }
  "repository": {
    "type": "git",
    "url": "https://github.com/tranluan91/laravel.git"
  },
  "author": "Luantv",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/tranluan91/laravel/issues"
  },
  "homepage": "https://github.com/tranluan91/laravel"
}

Nếu bạn dùng command npm run lint thì npm sẽ tạo ra một shell và chạy lệnh jshint **.js. Điều tương tự sẽ xảy ra khi bạn chạy command npm run test. Shell environment có trong thư mục node_modules/.bin. Npm sẽ tự động add dependencies đã được cài đặt và chạy trực tiếp. Nếu dùng command npm runthì npm sẽ thông báo list danh sách các command khả dụng trong project:

Available scripts in the user-service package:
  lint
    jshint **.js
  test
    mocha test/

Shortcut scripts

Npm cũng cung cấp một vài shortcuts tiện lợi: npm test, npm start, npm stop. npm test sẽ tương đường với việc chạy command npm run test. Việc sử dụng shortcuts với các lý do sau:

  • Đây là những task phổ biến mà hầu hết các project sẽ sử dụng, do việc việc type sẽ mất ít thời gian hơn.
  • Quan trọng hơn là nó cũng cấp một standard interface bên trong npm cho việc test, start hay stop một package.

Pre and post hooks

Một tính năng rất tuyệt của npm là bất kỳ một script nào có thể thực hiện với một bộ pre-post- hooks. Rất dễ định nghĩa trong scripts:

 "scripts": {
    "lint": "jshint **.js",
    "build": "browserify index.js > myproject.min.js",
    "test": "mocha test/",

    "prepublish": "npm run build # also runs npm run prebuild",
    "prebuild": "npm run test # also runs npm run pretest",
    "pretest": "npm run lint"
  }

Ví dụ như bạn thực hiện npm run lint, mặc dù npm không có định trước trong lint task, ngay lập tức nó sẽ thực hiện npm run prelint tiếp theo là npm run lint cuối cùng là npm run postlint. Tuy nhiên bạn không thể pre-pre- script, do vậy prepretest sẽ bị bỏ qua.

Passing Arguments

Một tính năng rất tuyệt của npm là thông qua arguments (từ npm 2.2.0) thiết đặt các công cụ ẩn:

"scripts": {
    "test": "mocha test/",
    "test:xunit": "npm run test -- --reporter xunit"
  }

Với config trên bạn có thể chạy npm run test một cách bình thường, nhưng có thể mở rộng với custom parameters -- prefix. Ví dụ: npm run test -- anothertest.js sẽ chạy mocha test/ anothertest.js hoặc hữu ích hơn npm run test -- --grep parser sẽ mở rộng tới mocha test/ --grep parser (sẽ chỉ chạy test với parser có trong title).

Thay thế một build tool

Sử dụng multi files

"devDependencies": {
  "jshint": "latest"
},
"scripts": {
  "lint": "jshint *.js"
}

khi chạy npm run lint npm sẽ thực hiện build với tất cả files có đuôi là .js.

Chạy với multi tasks

"devDependencies": {
  "jshint": "latest",
  "stylus": "latest",
  "browserify": "latest"
},
"scripts": {
  "lint": "jshint **",
  "build:css": "stylus assets/styles/main.styl > dist/main.css",
  "build:js": "browserify assets/scripts/main.js > dist/main.js",
  "build": "npm run build:css && npm run build:js",
  "prebuild:js": "npm run lint"
}

khi thực hiện npm run build npm sẽ thực hiện hai task được khai báo trước đó.

Clean

Nếu bạn muốn build script với một bản building sạch:

"scripts": {
  "clean": "rm -r dist/*"
}

khi chạy npm run clean npm sẽ xóa hàng loạt các files trong thư mục dist/.

LiveReload

"devDependencies": {
  "live-reload": "latest",
},
"scripts": {
  "livereload": "live-reload --port 9091 dist/",
}
<!-- In your HTML file -->
<script src="//localhost:9091"></script>

Khi có bất cứ thay đổi nào trong dist/, HTML page có thể lắng nghe livereload server và page sẽ tự động thay đổi mà không cần reload lại trang.

Hy vọng qua bài viết này có thể cho các bạn thấy khả năng của npm như một build tool, có thể thay thê được gulp hay grunt.

Tài liệu tham khảo


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.