Comments & Formatting
Comments
Bắt buộc comment cho function và API; Function Component có thể bỏ qua
Mọi function và API (exported function, public method) cần có comment mô tả (JSDoc hoặc block comment). Function Component (React) có thể không cần nếu tên component và props đã rõ nghĩa. Comment cho type phức tạp / khó hiểu; type đơn giản, tên biến/callback dễ hiểu thì không bắt buộc.
// ✅ Tốt: function/API có JSDoc
/**
* Parse query string thành object. Hỗ trợ array (key[]=a&key[]=b) và nested.
* @param search - Chuỗi query (vd. "?a=1&b=2")
* @returns Object key-value
*/
export function parseQueryString(search: string): Record<string, string | string[]> {
// ...
}
// ✅ Tốt: Function Component có thể không comment nếu tên + props rõ
type UserCardProps = { name: string; avatar?: string };
export function UserCard({ name, avatar }: UserCardProps) {
return <div>{name}</div>;
}
// ✅ Tốt: type phức tạp nên có comment
/**
* Map locale -> override cho từng key. Key rỗng = dùng default.
*/
type LocaleOverrides = Record<string, Record<string, string> | null>;
// không bắt buộc: type đơn giản, tên rõ
type Id = string;
const onSave = (value: string) => {};
Comment nhiều dòng: dùng /** ... */ (JSDoc cho function/API)
// ❌ Tránh: nhiều dòng bằng //
// make() returns a new element
// based on the passed-in tag name
function make(tag: string): Element {
return document.createElement(tag);
}
// ✅ Tốt
/**
* Tạo element mới theo tag name.
* @param tag - Tên thẻ HTML (vd. 'div', 'span')
* @returns Element đã tạo
*/
function make(tag: string): Element {
return document.createElement(tag);
}
Comment một dòng: dùng //, đặt ở dòng trên; có dòng trống trước (trừ dòng đầu block)
// ❌ Tránh: comment cùng dòng
const active = true; // is current tab
// ✅ Tốt
// is current tab
const active = true;
// ✅ Tốt: trong function, có dòng trống trước comment
function getType(): string {
console.log("fetching type...");
// set the default type to 'no type'
const type = this.type ?? "no type";
return type;
}
Bắt đầu comment bằng một space (dễ đọc)
// ❌ Tránh
//is current tab
const active = true;
// ❌ Tránh
/**
*make() returns a new element
*/
function make(tag: string): Element {
return document.createElement(tag);
}
// ✅ Tốt
// is current tab
const active = true;
// ✅ Tốt
/**
* make() returns a new element based on the passed-in tag name.
*/
function make(tag: string): Element {
return document.createElement(tag);
}
Dùng // FIXME: cho vấn đề cần xử lý, // TODO: cho việc cần làm
class Calculator {
total: number;
constructor() {
// FIXME: shouldn't use a global here
this.total = 0;
}
}
class Calculator {
constructor() {
// TODO: total should be configurable by an options param
this.total = 0;
}
}
Dưới directive 'use client' , 'use server' phải có một dòng trống
Sau dòng 'use client' hoặc 'use server' (dòng đầu file) bắt buộc phải có một dòng trống rồi mới đến các câu lệnh import hoặc code tiếp theo. Giúp dễ đọc và tránh lỗi tooling.
// ❌ Tránh: không có dòng trống sau directive
"use client";
import { useState } from "react";
// ✅ Tốt
"use client";
import { useState } from "react";
// ❌ Tránh
"use server";
import { db } from "@/lib/db";
// ✅ Tốt
"use server";
import { db } from "@/lib/db";
Whitespace
Indent: soft tabs 2 spaces
// ❌ Tránh: 4 spaces hoặc tab
function foo() {
let name: string;
}
// ✅ Tốt
function foo(): void {
let name: string;
}
Một space trước { (block)
// ❌ Tránh
function test(){
console.log("test");
}
if (isJedi){
fight();
}
// ✅ Tốt
function test(): void {
console.log("test");
}
if (isJedi) {
fight();
}
Không space giữa tên hàm và (; có space sau if/while/for
// ❌ Tránh
if( isJedi){
fight();
}
function fight() {
console.log("Swooosh!");
}
// ✅ Tốt
if (isJedi) {
fight();
}
function fight(): void {
console.log("Swooosh!");
}
Có space hai bên toán tử (trừ unary)
// ❌ Tránh
const x=y+5;
// ✅ Tốt
const x = y + 5;
Cuối file: một newline
// ✅ Tốt: kết thúc file bằng một dòng trống
export default foo;
// (EOF newline)
Method chain dài (> 2): xuống dòng, dấu . ở đầu dòng
// ❌ Tránh
$("#items").find(".selected").highlight().end().find(".open").updateCount();
// ✅ Tốt
$("#items")
.find(".selected")
.highlight()
.end()
.find(".open")
.updateCount();
Sau block: một dòng trống trước câu lệnh tiếp theo
// ✅ Tốt
if (foo) {
return bar;
}
return baz;
Không thêm dòng trống thừa trong block (no padded-blocks)
// ❌ Tránh
function bar(): void {
console.log(foo);
}
// ✅ Tốt
function bar(): void {
console.log(foo);
}
Không nhiều dòng trống liên tiếp
// ❌ Tránh
const x = 1;
const y = 2;
// ✅ Tốt
const x = 1;
const y = 2;
Không space trong () và []
// ❌ Tránh
function bar( foo: string ): string {
return foo;
}
const arr=[1, 2, 3];
console.log(arr[0]);
// ✅ Tốt
function bar(foo: string): string {
return foo;
}
const arr = [1, 2, 3];
console.log(arr[0]);
Có space trong {} của object literal
// ❌ Tránh
const foo = {clark: "kent"};
// ✅ Tốt
const foo = { clark: "kent" };
Dòng code không nên quá dài (vd. 100–120 ký tự); chuỗi dài có thể ngoại lệ
// ❌ Tránh
const foo =
jsonData &&
jsonData.foo &&
jsonData.foo.bar &&
jsonData.foo.bar.baz &&
jsonData.foo.bar.baz.quux;
// ✅ Tốt
const foo = jsonData?.foo?.bar?.baz?.quux;
Có space trong computed property
// ❌ Tránh
obj[foo ]
obj[ "foo"]
var x = {[ b ]: a}
obj[foo[ bar ]]
// ✅ Tốt
obj[foo]
obj["foo"]
var x = { [b]: a }
obj[foo[bar]]
Không space giữa tên hàm và lời gọi: func()
// ❌ Tránh
func ();
func
();
// ✅ Tốt
func();
Có space giữa key và value trong object literal
// ❌ Tránh
var obj = { foo : 42 };
var obj2 = { foo:42 };
// ✅ Tốt
const obj = { foo: 42 };
Không trailing space ở cuối dòng
Chỉ một newline ở cuối file; không newline thừa ở đầu file
Commas
Không dùng leading comma
// ❌ Tránh: dấu phẩy ở đầu dòng
const story = [
once
, upon
, aTime
];
// ✅ Tốt: dấu phẩy ở cuối dòng
const story = [
once,
upon,
aTime,
];
Có trailing comma khi list nhiều dòng
Dễ đọc diff và tránh lỗi khi thêm phần tử.
// ✅ Tốt
const hero = {
firstName: 'Dana',
lastName: 'Scully',
};
const heroes = [
'Batman',
'Superman',
];
Semicolons
Có dấu chấm phẩy (semicolons)
Tránh lỗi do Automatic Semicolon Insertion (ASI).
// ❌ Tránh: ASI có thể chèn sai chỗ
const luke = {}
const leia = {}
[luke, leia].forEach((jedi) => jedi.father = "vader")
// ❌ Tránh: return xuống dòng → return undefined
function foo(): string {
return
"search your feelings, you know it to be foo";
}
// ✅ Tốt
const luke = {};
const leia = {};
[luke, leia].forEach((jedi) => {
jedi.father = "vader";
});
// ✅ Tốt
function foo(): string {
return "search your feelings, you know it to be foo";
}