- vừa được xem lúc

JSDoc - Quy chuẩn viết document comment trong dự án Javascript

0 0 24

Người đăng: NGO SANG

Theo Viblo Asia

Viết comment cho dự án nghe tưởng chừng như là một việc đơn giản nhưng phần lớn các developer đều bỏ qua nó. Do đó sau một khoảng thời gian có thể developer đó sẽ cần mở lại dự án để bào trì và có thể không hiểu được những dòng code mà vài tháng trước mình đã viết dù đã căng mắt ra đọc. Do vậy việc viết comment là một kỹ năng khá quan trọng giúp cho việc tái sử dụng các đoạn code cũ dễ dàng hơn, giúp dev tiết kiệm thời gian cho chính mình cũng như các dev khác bảo trì dự án của bạn. Dù chúng ta cũng từng nghe rằng nếu viết code đủ dễ hiểu thì sẽ không cần phải comment. Nhưng trong thực tế liệu lúc nào chúng ta cũng có thể làm được như vậy với một đống logic xuất phát từ yêu cầu của khác hàng? Do đó vậy việc viết comment vẫn là một kỹ năng cần thiết giúp bảo vệ bộ não của chúng ta không bị nướng chín khi đọc lại các dòng code cũ của chính mình.

1. Clarification comments và documentation comments

Có 2 loại comment thường được sử dụng:

  • Comment mang tính chất giải thích (clarification comments): Thường được sử dụng, mục đích để cho người đọc hiểu được chức năng chính của một hàm hay một đoạn code cần giải thích. Một ví dụ từ lodash:
function addSetEntry(set, value) { // Don't return `set.add` because it's not chainable in IE 11. set.add(value); return set; }
  • Comment mang tính chất tài liệu (documentation comments): Thường được sử dụng để định nghĩa chi tiết cho một hàm hay một biến nào đó, bao gồm cả chức năng, kiểu dữ liệu, input/output như thế nào, kiểu dữ liệu trả về,... Một ví dụ khác từ lodash:
/** * Creates an object composed of keys generated from the results of running * each element of `collection` thru `iteratee`. The corresponding value of * each key is the number of times the key was returned by `iteratee`. The * iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 0.5.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The iteratee to transform keys. * @returns {Object} Returns the composed aggregate object. * @example * * _.countBy([6.1, 4.2, 6.3], Math.floor); * // => { '4': 1, '6': 2 } * * // The `_.property` iteratee shorthand. * _.countBy(['one', 'two', 'three'], 'length'); * // => { '3': 2, '5': 1 } */
var countBy = createAggregator(function(result, value, key) { if (hasOwnProperty.call(result, key)) { ++result[key]; } else { baseAssignValue(result, key, 1); }
});

Documentation comments thường sử dụng các ngôn ngữ đánh dấu như JSDoc (Javascript), phpDoc (PHP) làm quy chuẩn giúp cho việc đọc hiểu các comment này trở nên dễ dàng hơn.

Việc sử dụng kết hợp thành thục hai loại comment này sẽ giúp source code của bạn dễ đọc dễ hiểu hơn rất nhiều trong các dự án thực tế.

2. Dynamically typed và strongly typed

Javascript là một ngôn ngữ lập trình sử dụng dynamically typed (biến kiểu động - một biến có thể sử dụng cho nhiều kiểu dữ liệu khác nhau) tương tự với một số ngôn ngữ thông dịch khác như PHP, Python,... Điều này giúp việc lập trình dễ dàng hơn cho những người mới học lập trình hay trong các dự án nhỏ nơi mà việc tuân theo quy chuẩn không quá khắc khe vì một người có thể bao quát toàn bộ dự án. Nhưng đối với những dự án lớn ta cần phải đặt ra những quy chuẩn cho input/output hay định nghĩa chức năng của từng hàm thì việc chúng ta lập trình với những biến kiểu động như thế này phần lớn sẽ gây ra sự bối rối không hề nhẹ cho những dev bảo trì dự án vì có thể họ không biết được kiểu dữ liệu của input như thế nào để sử dụng các hàm xử lí phù hợp và có thể gây ra bug tiềm năng.

Ví dụ trong Javascript chúng ta có thể sử dụng một biến cho 2 kiểu dữ liệu stringnumber như thế này:

let message = "Hello";
message = 2;

Đó là một trong những lí do chính mà Typescript với kiểu khai báo strongly typed ra đời giúp chúng ta khai báo kiểu dữ liệu cho biến một cách tường minh hạn chế việc sử dụng kiểu dữ liệu tràn lan cho một biến:

let message: string = "Hello";
message = 2; // <-- Báo lỗi "Type 'number' is not assignable to type 'string'"

Nhưng nếu dự án ở công ty mà bạn làm việc không sử dụng Typescript hoặc đơn giản bạn cần một công cụ giúp cho việc comment chi tiết cho các thành phần trong dự án của bạn một cách dễ dàng hơn? Đó là lúc chúng ta cần đến JSDoc!

3. Giới thiệu về JSDoc

JSDoc là một loại ngôn ngữ đánh dấu sử dụng comment trong dự án Javascript, là loại documentation comment có chức năng chú thích chi tiết các thành phần của dự án Javascript. Do tính chất mạnh mẽ và phổ biến của nó, JSDoc còn được nhiều công cụ sử dụng để tạo ra documentation cho dự án. Ngoài JSDoc sử dụng cho Javascript ra ta còn có phpDoc (PHP), Javadoc (Java),... Hiện nay JSDoc đã được tích hợp vào các text editor/IDE phổ biến như Sublime Text, VSCode, Intellij,...

Ví dụ ta có một đoạn code Javascript sau đây được viết trong VSCode, khi di chuột vào hàm ta có thể thấy mô tả của hàm:

Ta có thể thấy hàm printMessage có thể nhận đầu vào msg là bất cứ kiểu dữ liệu gì, nhưng nếu chúng ta muốn cho người khác biết rằng hàm printMessage chỉ nhận msg là kiểu dữ liệu string ta có thể khai báo nó bằng JSDoc. Để viết JSDoc ta cần viết trong cặp dấu /** */:

/** * Hàm này dùng để in ra tin nhắn * @param {string} msg */
function printMessage(msg) { console.log("Message: " + msg);
}

Khi di chuột vào lần hàm lần nữa ta có thể thấy giờ đây hàm đã có khai báo chi tiết hơn:

Ngoài sử dụng cho hàm thì JSDoc còn có thể sử dụng cho biến:

/** @type {string} Biến này chứa tin nhắn cần hiển thị */
let helloMessage = "Hello";

4. Type-checking với JSDoc và VSCode

Nhưng trong một số trường hợp chúng ta vẫn có thể mắc một chút sai sót như sử dụng sai kiểu dữ liệu cho hàm như thế này:

let helloMessage = 2;
printMessage(helloMessage);

Lúc đó chúng ta cần đến type-checking được tích hợp sẵn vào VSCode để giúp thể hiện lỗi lên text-editor khi chúng ta sử dụng sai kiểu dữ liệu. Để sử dụng nó ta cần thêm // @ts-check vào đầu file:

// @ts-check /** * Hàm này dùng để in ra tin nhắn * @param {string} msg */
function printMessage(msg) { console.log("Message: " + msg);
} let helloMessage = 2;
printMessage(helloMessage);

Giờ đây khi sử dụng sai kiểu dữ liệu cho hàm printMessage thì VSCode sẽ báo lỗi trực quan hơn:

Nhưng trong một dự án lớn gồm cả trăm, ngàn file .js thì việc thêm // @ts-check vào đầu từng file có vẻ không phải là một biện pháp tốt. Lúc đó ta cần sử dụng đến file jsconfig.json được tạo ra ở root-folder (thư mục gốc) của dự án:

Trong file jsconfig.json ta thêm nội dung như sau:

{ "compilerOptions": { "checkJs": true }
}

Tiếp theo nhấn tổ hợp Ctrl + Shift + P để mở hộp command của VSCode. Tìm và mở setting:

Trong setting ta tìm JS/TS > Implicit Project Config: Check JS và bật chức năng đó lên, giờ đây VSCode có thể đọc và sử dụng các config trong file jsconfig.json:

Giờ đây toàn bộ những file .js trong thư mục của dự án đều đã được bật type-checking mà không cần phải thêm // @ts-check vào đầu từng file, nếu VSCode chưa kịp update thì ta cần tắt đi và mở lại VSCode:

Nhưng nếu teammate của bạn không dùng VSCode hoặc IDE của họ không hỗ trợ mà vẫn muốn sử dụng type-checking thì phải làm sao? Lúc đó ta cần thay file jsconfig.json thành file tsconfig.json với nội dung như sau:

{ "compilerOptions": { "allowJs": true, "checkJs": true }
}

Mở command line ở thư mục gốc của dự án và chạy câu lệnh:

npx tsc --noEmit

Ta đã có thể sử dụng chức năng type-checking cho toàn bộ dự án bằng command line:

5. Các thẻ khác của JSDoc

Ngoài các thẻ @type@param đã giới thiệu ở trên ta còn có một số thẻ cơ bản khác:

  • Thẻ @async: Chi định hàm đó là asynchronous.
  • Thẻ @returns: Chỉ định giá trị trả về cho function.
  • Thẻ @version: Chỉ định phiên bản của một danh mục.
  • Thẻ @see: Tham chiếu tới một liên kết để biết thêm thông tin.

Các bạn có thể tham khảo thêm ở đây.

Ví dụ:

/** * `fetchData` lấy dữ liệu từ url đưa vào function * @async * @param {string} url - url để lấy dữ liệu * @returns {Promise<string>} dữ liệu được lấy từ url * @version 1.1 * @see https://viblo.asia/ */
export async function fetchData(url) { const result = await fetch(url); return result;
}

Popup hiển thị khi đưa chuột vào hàm:

6. Tổng kết

Với việc sử dụng JSDoc kết hợp VSCode và tsc CLI, ta có thể thấy code dự án Javascript của chúng ta đã chặc chẽ và dễ hiểu hơn rất nhiều, dễ đọc hơn khi gặp lại nó ở những lần sau. Và quan trọng hơn hết là những người khác đọc code của bạn. Họ sẽ hiểu được bạn đang viết cái gì.


Tài liệu tham khảo:

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 499

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 414

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 136

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 117

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 93

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 229