Tạo .prettierrc và xem trước ngay đoạn mã được định dạng lại theo lựa chọn của bạn
Công cụ bày đủ mười bốn tùy chọn của Prettier, từ printWidth và tabWidth cho tới singleAttributePerLine, kèm khung xem trước dựng lại một đoạn mã mẫu theo đúng lựa chọn hiện tại nên bạn thấy khác biệt ngay thay vì phải đoán. Kèm theo là khối overrides cho từng loại tệp và một mẫu .prettierignore dùng được ngay.
Tính năng nổi bật
- Đủ mười bốn tùy chọn của Prettier, mỗi tùy chọn có một dòng giải thích hệ quả thực tế chứ không chép lại tài liệu
- Khung xem trước hai cột đặt cạnh nhau: mã gốc viết lộn xộn và mã sau khi định dạng theo lựa chọn hiện tại
- Đoạn mã mẫu được chọn để mọi tùy chọn đều có chỗ thể hiện, kể cả quoteProps và embeddedLanguageFormatting
- Thanh trượt cho printWidth và tabWidth, kéo tới đâu khung xem trước bẻ dòng lại tới đó
- Năm khối overrides dựng sẵn cho Markdown, JSON, YAML, tệp giao diện và thư mục mã cũ
- Mẫu .prettierignore đầy đủ, đã loại sẵn tệp khóa phiên bản và ảnh chụp kết quả kiểm thử
- Đếm số tùy chọn đang khác giá trị mặc định để bạn biết cấu hình của mình lệch chuẩn bao nhiêu
- Chạy hoàn toàn trong trình duyệt, có nút chép riêng cho tệp cấu hình và cho tệp bỏ qua
Vì sao nên xem trước thay vì chỉnh rồi chạy thử
Cách làm thông thường là sửa một dòng trong .prettierrc, chạy lệnh định dạng lên cả dự án, mở tệp ra xem, rồi lại sửa tiếp. Vòng lặp đó tốn thời gian và tệ hơn là nó tạo ra những bản vá khổng lồ chạm vào hàng nghìn dòng mà bạn phải hoàn tác. Với một số tùy chọn thì đọc tên là hiểu, chẳng hạn semi hay singleQuote. Nhưng có những tùy chọn mà chỉ nhìn kết quả mới quyết định được: quoteProps có ba giá trị và khác biệt chỉ lộ ra khi object có một khóa chứa dấu gạch ngang; bracketSameLine chỉ đổi đúng một ký tự nhưng đổi hẳn cảm giác khi đọc một khối JSX dài; singleAttributePerLine làm tệp dài thêm bao nhiêu thì phải nhìn mới ước lượng được; còn printWidth thì tác động dây chuyền tới mọi chỗ bẻ dòng. Khung xem trước ở đây dựng lại đoạn mã theo đúng lựa chọn hiện tại, nên bạn chốt được cả bộ cấu hình trước khi chạy lệnh định dạng lần đầu. Điều đó quan trọng vì lần chạy đầu tiên trên một dự án đang có mã sẽ tạo ra một bản vá rất lớn, và bạn chỉ muốn làm việc đó đúng một lần.
Lợi ích khi sử dụng
- Thấy ngay khác biệt của từng tùy chọn thay vì chạy thử rồi hoàn tác
- Chốt được cả bộ cấu hình trước lần chạy định dạng đầu tiên trên dự án đang có mã
- Có sẵn khối overrides cho Markdown và YAML, hai loại tệp hay bị định dạng hỏng
- Mẫu .prettierignore loại sẵn tệp khóa phiên bản và ảnh chụp kết quả kiểm thử
- Biết cách để Prettier và ESLint không sửa ngược nhau ở mỗi lần lưu tệp
Cách tạo tệp .prettierrc bằng công cụ này
- 1Kéo thanh trượt printWidth tới mức đội bạn thấy dễ đọc, khung xem trước bên phải bẻ dòng lại ngay theo mốc mới.
- 2Chọn kiểu dấu câu và nháy: có chấm phẩy hay không, nháy đơn hay nháy kép cho JavaScript và cho JSX, cách xử lý khóa của object.
- 3Quyết định nhóm tùy chọn JSX gồm bracketSameLine và singleAttributePerLine, so hai phương án ngay trên khung xem trước.
- 4Bật các khối overrides cần thiết nếu dự án có tệp Markdown, YAML hay thư mục mã cũ cần đối xử khác.
- 5Chép nội dung .prettierrc vào thư mục gốc dự án, chép luôn mẫu .prettierignore, rồi chạy lệnh định dạng toàn bộ trong một lần gộp mã riêng.
printWidth không phải giới hạn cứng, nó là mốc để cân nhắc bẻ dòng
Hiểu nhầm phổ biến nhất về Prettier là coi printWidth như giới hạn tuyệt đối, kiểu như quy tắc tám mươi cột của các trình soạn thảo đời cũ. Thực tế Prettier hoạt động theo cách khác hẳn: nó phân tích mã thành một cây, rồi với mỗi nhóm nó thử in ra trên một dòng, nếu vượt quá printWidth thì bẻ nhóm đó ra thành nhiều dòng, và lặp lại việc đó cho các nhóm con. Vì vậy có những dòng vẫn dài hơn mốc bạn đặt, điển hình là một chuỗi ký tự dài hay một đường dẫn nhập dài, đơn giản vì không có chỗ nào để bẻ. Hệ quả thực tế của việc chọn mốc là nó tác động dây chuyền: hạ printWidth từ 100 xuống 80 không chỉ làm vài dòng ngắn lại mà làm hàng loạt lời gọi hàm và thẻ JSX chuyển từ dạng một dòng sang dạng nhiều dòng, khiến tệp dài thêm đáng kể. Mặc định của Prettier là 80, con số kế thừa từ thời màn hình đầu cuối. Nhiều đội frontend chọn 100 hoặc 120 vì thẻ JSX kèm chuỗi lớp CSS rất dài, để 80 thì gần như thẻ nào cũng bị bẻ. Điều quan trọng hơn con số là cả đội dùng chung một con số, vì mỗi lần đổi mốc là một lần cả kho mã bị định dạng lại.
Cách để Prettier và ESLint không sửa ngược nhau
Đây là tình huống rất hay gặp: bạn lưu tệp, Prettier viết lại cách xuống dòng theo bộ luật của nó, ngay sau đó ESLint gạch đỏ đúng dòng vừa viết lại và đề nghị sửa theo hướng khác. Nguyên nhân là cả hai công cụ đều có ý kiến về hình thức mã, mà ý kiến của chúng không giống nhau. Cách phân vai đúng rất đơn giản và cần được cả đội thống nhất: Prettier là công cụ duy nhất được quyền quyết định mã trông thế nào, còn ESLint chỉ giữ phần lỗi logic và quy ước, tức những chuyện như gọi hook sai chỗ hay thiếu phụ thuộc trong useEffect. Để thực thi, hãy cài gói eslint-config-prettier và đặt nó ở vị trí cuối cùng trong mảng flat config hoặc cuối trường extends của định dạng cũ. Gói này không thêm quy tắc nào, nó chỉ tắt toàn bộ quy tắc định dạng của ESLint. Vị trí cuối là bắt buộc vì trong ESLint thì cấu hình đứng sau ghi đè cấu hình đứng trước. Có một cách thứ hai là chạy Prettier như một quy tắc của ESLint qua gói eslint-plugin-prettier, khi đó mọi khác biệt định dạng hiện thành lỗi đỏ; cách này gọn ở chỗ chỉ cần một lệnh nhưng làm lint chậm hơn và làm nhiễu danh sách lỗi thật, nên phần lớn đội chọn cách thứ nhất rồi chạy Prettier riêng ở bước lưu tệp.
Ba nhóm tùy chọn ảnh hưởng tới bản vá nhiều hơn bạn nghĩ
Có ba tùy chọn tuy nhỏ nhưng ảnh hưởng trực tiếp tới chất lượng bản vá khi duyệt mã. Thứ nhất là trailingComma. Khi đặt giá trị all, mọi khối bị bẻ dòng đều có dấu phẩy sau phần tử cuối, nên thêm một phần tử mới chỉ tạo ra một dòng thêm vào; nếu để none thì dòng cuối cũ phải sửa để thêm dấu phẩy, và bản vá hiện thành một dòng bị xóa cùng hai dòng thêm mới, khiến lịch sử thay đổi của dòng đó bị gán nhầm cho người thêm phần tử mới. Thứ hai là arrowParens. Để always thì hàm mũi tên một tham số vẫn giữ cặp ngoặc, nên khi bạn thêm chú thích kiểu hoặc thêm tham số thứ hai, bản vá chỉ chạm vào phần thật sự đổi; để avoid thì mã ngắn hơn vài ký tự nhưng mỗi lần thêm tham số là phải viết lại cả cặp ngoặc. Thứ ba là singleAttributePerLine. Bật lên thì mỗi thuộc tính JSX một dòng, tệp dài hơn hẳn nhưng đổi một thuộc tính chỉ hiện đúng một dòng thay đổi thay vì cả thẻ. Ba lựa chọn này không có đáp án đúng tuyệt đối, nhưng nếu đội bạn duyệt mã kỹ thì cả ba nên nghiêng về phía tạo bản vá gọn.
Khối overrides và tệp .prettierignore: hai chỗ hay bị bỏ quên
Một tệp .prettierrc phẳng áp cùng bộ luật cho mọi loại tệp, và điều đó gây rắc rối ngay khi dự án có nhiều loại tệp. Tệp Markdown chứa văn xuôi chứ không phải mã, nên mốc bẻ dòng của mã áp lên đoạn văn sẽ cho ra kết quả khó đọc, và tùy chọn proseWrap mới là thứ quyết định đoạn văn có bị bẻ hay không. Tệp YAML thì cực kỳ nhạy với thụt lề và tuyệt đối không được dùng ký tự tab, nên nếu dự án của bạn đặt useTabs thì phải có khối overrides ép YAML về dấu cách, nếu không mọi tệp cấu hình quy trình tích hợp sẽ hỏng. Khối overrides trong .prettierrc nhận một mảng, mỗi phần tử gồm mẫu đường dẫn ở trường files và các tùy chọn ghi đè ở trường options, và phần tử đứng sau thắng khi có nhiều mẫu cùng khớp. Song song với đó là tệp .prettierignore dùng cú pháp giống .gitignore. Những thứ bắt buộc phải liệt kê trong đó là thư mục sinh tự động, tệp khóa phiên bản của trình quản lý gói, tệp đã nén, và thư mục chứa ảnh chụp kết quả kiểm thử. Định dạng lại tệp khóa phiên bản là kiểu bản vá vô nghĩa nhưng rất to, còn định dạng lại ảnh chụp kết quả kiểm thử sẽ làm hỏng phép so sánh và khiến bộ kiểm thử đỏ hàng loạt.
Đưa Prettier vào một dự án đang có mã mà không làm loạn lịch sử thay đổi
Chạy lệnh định dạng lần đầu trên một kho mã đã lớn sẽ tạo ra một bản vá chạm vào gần như mọi tệp. Nếu trộn lẫn bản vá đó với một thay đổi chức năng, người duyệt mã không còn cách nào tách được phần nào là logic mới và phần nào chỉ là dấu cách. Cách làm đã thành chuẩn gồm ba bước. Bước một là gộp riêng một lần chỉ chứa việc định dạng lại, không kèm bất kỳ thay đổi logic nào, và ghi rõ điều đó trong mô tả. Bước hai là tạo tệp khai báo các lần gộp cần bỏ qua khi truy vết dòng, thường đặt tên là .git-blame-ignore-revs, ghi mã băm của lần gộp vừa rồi vào đó rồi cấu hình cho công cụ quản lý mã dùng tệp này; nhờ vậy lệnh truy vết vẫn chỉ đúng người thật sự viết dòng mã chứ không chỉ vào người chạy lệnh định dạng. Bước ba là gắn Prettier vào quy trình: đặt lệnh kiểm tra định dạng trong bước tích hợp để bản vá mới không lọt qua, và cấu hình trình soạn thảo tự định dạng khi lưu tệp cho cả đội. Nếu dự án quá lớn để định dạng một lần, có thể dùng công cụ chỉ định dạng phần đã thay đổi, nhưng cách đó khiến kho mã ở trạng thái nửa vời khá lâu.
Câu hỏi thường gặp (FAQ)
Khung xem trước có dùng đúng Prettier thật không?
Khung xem trước dựng lại đoạn mã mẫu theo đúng mười bốn tùy chọn bạn chọn, chạy hoàn toàn trong trình duyệt và không tải thêm thư viện nào. Nó bám sát cách Prettier xử lý đoạn mã đó, đủ để bạn so sánh các phương án. Kết quả cuối cùng trên dự án thật vẫn do Prettier cài trong dự án quyết định.
printWidth nên đặt bao nhiêu?
Mặc định là 80. Dự án frontend nhiều JSX thường nới lên 100 hoặc 120 vì thẻ kèm chuỗi lớp CSS rất dài, để 80 thì thẻ nào cũng bị bẻ thành nhiều dòng. Quan trọng hơn con số là cả đội thống nhất một con số, vì mỗi lần đổi mốc là một lần cả kho mã bị định dạng lại.
Vì sao có dòng vẫn dài hơn printWidth?
Vì printWidth là mốc để cân nhắc bẻ dòng chứ không phải giới hạn cứng. Khi một dòng không có chỗ nào bẻ được, ví dụ một chuỗi ký tự dài hay một đường dẫn nhập dài, Prettier để nguyên. Đây là hành vi có chủ đích chứ không phải lỗi cấu hình.
trailingComma nên chọn es5 hay all?
Chọn all nếu dự án chạy trên môi trường hiện đại, vì nó thêm dấu phẩy cả trong danh sách tham số hàm, giúp bản vá gọn hơn khi thêm tham số mới. Giá trị es5 chỉ thêm phẩy ở những chỗ mà JavaScript đời cũ chấp nhận, dùng khi bạn còn phải hỗ trợ môi trường rất cũ.
quoteProps ba giá trị khác nhau thế nào?
as-needed chỉ giữ nháy ở những khóa bắt buộc phải có, chẳng hạn khóa chứa dấu gạch ngang. consistent đặt nháy cho toàn bộ khóa của một object nếu có ít nhất một khóa cần nháy. preserve giữ đúng như bạn viết. Đa số dự án để as-needed cho gọn.
endOfLine để lf hay crlf?
Để lf cho mọi hệ điều hành, kể cả khi đội có người dùng Windows, và đặt kèm quy tắc trong tệp .gitattributes. Nếu để auto hoặc để lệch nhau giữa các máy, sẽ có lúc toàn bộ tệp hiện là đã sửa chỉ vì ký tự xuống dòng thay đổi.
Prettier có thay được ESLint không?
Không, hai công cụ làm hai việc khác nhau. Prettier chỉ quyết định mã trông thế nào, nó hoàn toàn không biết mã đúng hay sai. ESLint mới là nơi bắt lỗi logic và quy ước, ví dụ gọi hook trong vòng lặp hay quên phụ thuộc trong useEffect. Dự án nghiêm túc cần cả hai.
Làm sao để Prettier và ESLint thôi sửa ngược nhau?
Cài eslint-config-prettier rồi đặt nó ở vị trí cuối cùng trong cấu hình ESLint. Gói này tắt hết quy tắc định dạng bên ESLint để nhường phần trình bày cho Prettier. Vị trí cuối là bắt buộc vì cấu hình đứng sau ghi đè cấu hình đứng trước.
Nên đặt cấu hình trong .prettierrc hay trong package.json?
Cả hai đều được. Đặt trong package.json ở trường prettier giúp giảm số tệp ở thư mục gốc, còn tệp .prettierrc riêng thì dễ tìm hơn với người mới vào dự án. Chỉ cần tránh khai ở cả hai nơi, vì khi đó rất khó đoán cấu hình nào đang có hiệu lực.
Chạy Prettier lần đầu tạo bản vá quá lớn, có cách nào giảm không?
Hãy gộp riêng một lần chỉ chứa việc định dạng lại, không kèm thay đổi logic. Sau đó ghi mã băm của lần gộp đó vào tệp .git-blame-ignore-revs và cấu hình cho công cụ quản lý mã dùng tệp này, nhờ vậy lệnh truy vết dòng vẫn chỉ đúng người đã viết dòng mã.
Vì sao tệp YAML bị hỏng sau khi định dạng?
Gần như chắc chắn vì useTabs đang bật. YAML không chấp nhận ký tự tab để thụt lề. Hãy thêm một khối overrides cho mẫu đuôi yml và yaml, ép useTabs về false và tabWidth về hai, hoặc đưa hẳn tệp YAML vào .prettierignore.
Vì sao ảnh chụp kết quả kiểm thử bị lỗi sau khi định dạng?
Vì tệp ảnh chụp lưu chính xác chuỗi kết quả để so sánh, định dạng lại là làm lệch chuỗi đó và mọi phép so sánh đều trượt. Đưa thư mục chứa ảnh chụp vào .prettierignore, mẫu tệp bỏ qua ở công cụ này đã có sẵn dòng đó.
Từ khóa liên quan
- tạo file prettierrc
- prettier config generator
- cấu hình prettier cho react
- printWidth prettier bao nhiêu
- prettier singleQuote
- trailingComma es5 hay all
- arrowParens always avoid
- bracketSameLine là gì
- singleAttributePerLine jsx
- quoteProps as-needed
- prettier overrides theo loại tệp
- mẫu prettierignore
- prettier và eslint xung đột
- eslint config prettier cách dùng
- prettier endOfLine lf crlf
- embeddedLanguageFormatting
- prettier format on save
- git blame ignore revs prettier
- prettier cho file yaml
- định dạng code tự động javascript
