Giới thiệu về module

Module trong Javascript

Có thể định nghĩa module trong ngôn ngữ Javascript là tập hợp các đoạn code có thể tái sử dụng. Thêm nữa là mỗi module độc lập với một module khác. Một tính năng nữa là một module này có thể phụ thuộc vào module kia.

Định nghĩa module

Có nhiều các để định nghĩa module, cách sau đây định nghĩa module đơn giản sử dụng thư viện Jquery.

1
2
3
4
(function () {
  var $ = this.jQuery;
  this.myModule = function () {};
}());

Cách trên định nghĩa module dựa trên hàm thực thi ngay lập tức (Immediately Invoked Function Expression). Sử dụng cách này để bao đóng các biến trong module.
Cuối cùng là biến this trỏ tới đối tượng global (chính là window) trên trình duyệt.

Asynchronous module definition - AMD

AMD là định nghĩa module và load các module bất đồng bộ. Thư viện cho phép chúng ta sử dụng kiểu AMD này là requirejs. Code của AMD sẽ có dạng:

1
2
3
define(['jquery'] , function ($) {
  return function () {};
});

Trong đó hàm define sẽ được định nghĩa trong thư viện requirejs.

Định nghĩa module kiểu CommonJS

CommonJS đặc tả cách sử dụng module với hai từ khóa là requireexports. Đây là cách sử dụng mặc định của NodeJs.

1
2
3
const $ = require('jquery'); // load thư viện Jquery

exports.myModule = function () {}; // export module

Bài sau sẽ có giải thích kỹ hơn về kiểu sử dụng module của NodeJs.

ES Module

ES Module là kiểu module hổ trợ từ ES 2015. Cách viết module này được hổ trợ trên trình duyệt, NodeJs, TypeScript và các build tool như Webpack, Babel, Rollup.

ES Module sử dụng hai từ khóa là exportimport.
Ví dụ như sau:

1
2
3
4
5
// file module.js
export const age = 10;

// file main.js
import { age } from './module.js';

Trong trình duyệt thì có thể chạy ES module trong code <script src="module"></script>.
Có thể xem demo ở đây.

ES Module cũng được giải thích kỹ hơn trong bài sau.

Universal Module Definition - UMD

Kiểu cuối cùng là UMD chính là kiểu có thể kết hợp nhiều kiểu trên lại với nhau. Cụ thể bạn muốn viết một thư viện cho cả nhiều người sử dụng. Tuy nhiên mỗi người lại có kiểu sử dụng module khác nhau.

Ví dụ hãy xem mã nguồn thư viện momentjs (cũ) được viết như thế nào ở đây.
https://github.com/moment/moment/blob/develop/moment.js

Ở các dòng từ dòng 7 đến dòng 11 là khai báo hổ trợ nhiều kiểu module.

1
2
3
4
5
6
;(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? 
    module.exports = factory() :
  typeof define === 'function' && define.amd ? define(factory) :
    global.moment = factory()
}(this, (function () { 'use strict';

Trong đó global tương đương với this hay chính là window trong trình duyệt. Còn hàm factory chính là nội dung của thư viện moment. Với khai báo như vậy chúng ta có thể thoải mái dùng thư viện moment với nhiều kiểu load module khác nhau.

Thường thì khi viết thư viện chúng ta sẽ viết ES Module sau đó dùng các công cụ như Babel, Rollup để build ra mã nguồn với kiểu module là UMD.