Format & sort .env.example | Env formatter trước khi mở PR

(Cập nhật: 19 tháng 7, 2026 ) .env dotenv env formatter .env.example format sort key PR review
Kết luận

.env.example là “hợp đồng key” của repo — phải đọc được trong 30 giây. Format = sort KEY, một key một dòng, comment mô tả chứ không dán secret. Dùng .env Formatter (local trên trình duyệt) trước PR khi file lộn A/Z hoặc nghi trùng key. Best practices bảo mật / onboard → bài .env best practices; bài này chỉ góc formatter + convention diff.

Freelance Nest/Next nhận repo khách: .env.example 80 dòng, STRIPE_* nằm giữa Z_*A_*, ba comment # TODO, hai lần DATABASE_URL=. App vẫn boot trên máy lead (last-wins lấy dòng dưới). Bạn copy example → thiếu key thật sự cần → “works on my machine” vòng hai. Env formatter không sửa bảo mật — nó làm file đọc được và so sánh được trước khi ai đó merge.

Ai nên đọc bài này

  • Dev / freelancer phải cập nhật .env.example mỗi khi thêm biến
  • Reviewer mệt vì diff env nhảy lung tung không theo alphabet
  • Lead muốn convention “sort trước khi mở PR” thay vì tranh luận style trong Slack

Nếu bạn cần checklist không commit secret / vault / validate boot — đọc best practices .env. Ở đây tập trung format & sort.


Env formatter thực sự làm gì

Tool Kawa .env Formatter xử lý trong trình duyệt:

  1. Tách dòng # comment và dòng KEY=value
  2. Sort key theo alphabet (localeCompare tiếng Anh — ổn với SCREAMING_SNAKE)
  3. Đưa toàn bộ comment lên đầu, rồi một dòng trống, rồi danh sách key đã sort
  4. Bỏ dòng trống thừa ở giữa; trim khoảng trắng quanh dòng

Không đổi tên key, không validate schema Zod, không upload server. Output chỉ sạch hơn để bạn paste lại vào repo.

# Trước — khó review
Z_FEATURE=1
DATABASE_URL=postgresql://local/db
# payment
STRIPE_SECRET_KEY=sk_test_xxx
API_URL=http://localhost:3000
DATABASE_URL=postgresql://local/db2

# Sau sort — duplicate DATABASE_URL nằm cạnh nhau
# payment
API_URL=http://localhost:3000
DATABASE_URL=postgresql://local/db
DATABASE_URL=postgresql://local/db2
STRIPE_SECRET_KEY=sk_test_xxx
Z_FEATURE=1

Hai dòng DATABASE_URL cạnh nhau = tín hiệu đỏ. Xóa một dòng trước khi commit example.

Secret production

Không dán .env production vào formatter — kể cả tool local. Chỉ dùng placeholder hoặc giá trị đã che. Lỡ dán rồi: coi như lộ → rotate key trong paste.


Vì sao sort quan trọng hơn “trông đẹp”

1. Diff PR nhỏ và ổn định

Thêm REDIS_URL vào file đã sort A–Z → diff khoảng 1–3 dòng. Thêm vào file lộn xộn → Git báo nửa file đổi chỗ, reviewer bỏ qua.

2. Last-wins im lặng

Hầu hết loader Node dotenv / nhiều framework: cùng key xuất hiện hai lần → giá trị sau thắng. Không có error. Triệu chứng:

Hiện tượngNguyên nhân hay gặp
“Đã sửa key mà không ăn”Sửa dòng trên; dòng dưới vẫn ghi đè
Local OK, CI failFile khác / thiếu key; hoặc duplicate khác nhau giữa máy
Staging ≠ prodDashboard platform ghi đè file trên một bên

Sort không “sửa” last-wins — nhưng kéo hai dòng trùng sát nhau để mắt người bắt được trước merge.

3. Onboard freelancer nhanh hơn

Example sorted + comment đầu file = checklist key trong 1 phút. Example lộn = người mới hỏi Zalo “anh gửi giúp env thật” — đúng anti-pattern bài best practices đã cảnh báo.


Convention đề xuất cho team Việt / outsourcing

Không cần quy tắc dài. Ba dòng trong README đủ:

  1. Commit .env.example, gitignore .env
  2. Key SCREAMING_SNAKE, không space quanh =
  3. Trước PR đụng env: format/sort (tool hoặc script), xóa duplicate

Tùy chọn nâng cao — nhóm theo prefix rồi sort trong nhóm (APP_*, DB_*, STRIPE_*). Formatter Kawa hiện sort toàn bộ A–Z (comment gom đầu). Nếu team giữ nhóm thủ công, sort từng khối trước khi dán, hoặc chấp nhận A–Z phẳng cho example nhỏ (dưới 40 key).

Format gì / không format gì
Nên đưa vào formatter Giữ nguyên tay Không đưa vào tool
.env.example placeholder Thứ tự nhóm theo domain (nếu team quy ước) .env production / staging thật
Bản copy đã che secret PEM/multiline phức tạp — test loader trước File vừa nhận qua Slack chưa rotate
Draft trước khi mở PR Comment giải thích nghiệp vụ dài Export chứa token live

Quy trình 5 phút trước PR

  1. Mở .env Formatter — không cần đăng ký
  2. Dán nội dung .env.example hiện tại
  3. Bấm Định dạng → xem output
  4. Quét cặp key giống nhau liền kề; xóa thừa
  5. Copy về editor → git diff → commit riêng message kiểu chore: sort .env.example

🛠️ Kiểm tra định dạng .env ngay tại đây

Kiểm tra nhanh bằng shell (optional)

# Liệt kê key trùng trong .env.example (bỏ comment)
grep -v '^#' .env.example | grep '=' | cut -d= -f1 | sort | uniq -d

Có output → còn duplicate. CI có thể fail job nếu lệnh này không rỗng.


Case study ngắn

A. Freelancer thêm Stripe

Thêm STRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRET vào cuối file 60 dòng không sort. Reviewer thấy diff “+2” nhưng không biết đã có STRIPE_SECRET_KEY ở dòng 12 với giá trị cũ sk_test_replace_me. Merge → last-wins lấy dòng cuối; lead vẫn nghĩ đang dùng placeholder cũ trên staging.

Cách tránh: sort trước → hai STRIPE_SECRET_KEY cạnh nhau → xóa một → PR sạch.

B. Repo khách Nhật, example tiếng Anh lẫn comment tiếng Nhật

Comment # 本番はVercelのEnvironment vẫn giữ được sau format (gom đầu). Giá trị vẫn placeholder. Freelancer đọc comment biết production inject từ dashboard — không xin file .env qua chat.


Quote và khoảng trắng — formatter không “đoán” giúp bạn

Sort không tự thêm/bỏ quote. Bạn vẫn phải viết đúng:

PORT=3000
DISPLAY_NAME="Ada Lovelace"
# Sai: khoảng trắng quanh = hoặc value có space không quote
# API_KEY = sk live

Sau format, boot app một lần với key throwaway; log độ dài secret (không log giá trị) nếu nghi quote thừa bám vào value. Chi tiết quote / # trong value → best practices.


Checklist trước khi merge thay đổi env

  • .env.example đã sort (hoặc nhóm ổn định theo README)
  • Không còn key trùng (uniq -d rỗng)
  • Mỗi key mới có placeholder + comment một dòng
  • .env local không stage
  • Không dán secret thật vào tool / PR / screenshot
  • README ghi rõ: copy example → điền local; prod dùng platform env

Liên kết liên quan