Tôi đã phát triển trình định dạng C, C++, Java, JavaScript dùng Clang trong môi trường Node.js.
(github.com/lumirlumir)- Kho GitHub: https://github.com/lumirlumir/npm-clang-format-node
- Trang tài liệu chính thức: https://clang-format-node.lumir.page/
Xin chào!
Tôi đã phát triển một trình định dạng cho C, C++, Java và JavaScript sử dụng Clang trong môi trường Node.js. Dự án này là một khởi đầu mới dựa trên gói clang-format của Angular, hiện không còn được bảo trì nữa.
Tôi từng chia sẻ nội dung tương tự cách đây hai ba tháng, và lần này khi phát hành phiên bản v1.3.0, tôi đã bổ sung một trang tài liệu chi tiết để người dùng có thể sử dụng dễ dàng và thuận tiện hơn. Bạn có thể xem trang tài liệu tại đây; trong đó có nhiều nội dung từ cách cài đặt cơ bản cho tới lý do nên sử dụng gói này, nên nếu quan tâm thì rất đáng tham khảo.
Trong bản cập nhật lần này, tôi đã bổ sung nhiều bài kiểm thử để tăng thêm độ ổn định cho gói, đồng thời cũng thêm vào các tính năng mới.
Gói này được phát hành theo giấy phép MIT, nên bạn có thể tự do sử dụng.
clang-format-node là dự án gì?
Đây là một gói Node.js dựa trên clang-format của Clang, trình biên dịch C nổi tiếng của LLVM, hỗ trợ định dạng mã cho các ngôn ngữ C, C++ và Java. Nói ngắn gọn, nó đóng vai trò tương tự Prettier trong môi trường Node.js, nhưng khác biệt ở chỗ cung cấp khả năng định dạng cho C, C++ và Java — những ngôn ngữ mà Prettier không hỗ trợ.
Đặc biệt, trong các trường hợp cần viết cả mã JavaScript lẫn mã C/C++ như phát triển Node.js core hoặc Electron, clang-format-node sẽ rất hữu ích.
Gói clang-format trước đây khá bất tiện vì phải cài thêm các phụ thuộc phụ thuộc vào môi trường hệ điều hành như Ubuntu, nhưng với gói này bạn có thể dùng ngay mà không cần cài đặt bổ sung. Ngoài ra, trong khi gói cũ khá khó tích hợp vào các workflow CI dựa trên Node.js và npm, thì clang-format-node có thể được dùng rất đơn giản chỉ bằng cách cài từ npm và thiết lập script, nhờ đó mang lại nhiều lợi thế trong môi trường CI.
Vậy các đặc điểm của gói clang-format-node là gì?
1. Drop-in Replacement thay thế clang-format của Angular
clang-format-node là một Drop-in Replacement có thể thay thế dễ dàng cho gói Angular/clang-format.
Việc chuyển từ gói cũ sang clang-format-node rất đơn giản và có thể dùng ngay mà không cần quy trình phức tạp nào.
2. Chỉ cần Node.js, không cần thêm phụ thuộc để dùng Clang
Hoàn toàn không cần các phụ thuộc bổ sung như Python hay C++. Chỉ cần có Node.js là có thể chạy đơn giản.
3. Phạm vi hỗ trợ rộng
Hỗ trợ rộng rãi nhiều hệ điều hành và kiến trúc, nhiều phiên bản Node.js, các runner image của GitHub Actions, Docker build image, v.v.
4. Thiết lập CI đơn giản
Không cần cấu hình phức tạp; bạn có thể dùng clang-format-node giống như các gói Node.js khác.
5. Build và phát hành tự động
Mỗi khi clang-format được cập nhật, một phiên bản npm mới sẽ tự động được phát hành. GitHub Actions sẽ định kỳ phát hiện cập nhật, build gói và tạo Pull Request.
Định dạng mã với clang-format và git-clang-format
(Phần dưới đây là nội dung tôi đã viết bằng tiếng Anh trong mục https://clang-format-node.lumir.page/docs/get-started/introduction, sau đó dịch một phần sang tiếng Hàn.)
Tầm quan trọng của việc định dạng mã
Hãy luôn định dạng mã
Định dạng mã là một công việc rất quan trọng để nâng cao chất lượng code. Cốt lõi của việc định dạng là duy trì tính nhất quán trong cách trình bày mã để tăng khả năng đọc và dễ hiểu.
clang-format là gì?
clang-format là công cụ tự động định dạng các tệp mã nguồn của những ngôn ngữ như C và C++, được phát triển như một phần của dự án mã nguồn mở LLVM Clang.
Cách hoạt động
- Tạo tệp cấu hình
Tạo tệp cấu hình (.clang-format) định nghĩa style định dạng. - Chạy lệnh
Khi chạy lệnhclang-format, mã nguồn sẽ tự động được sắp xếp lại theo các quy tắc style tương ứng.
Đặc điểm chính
- Hỗ trợ nhiều ngôn ngữ
Hỗ trợ nhiều ngôn ngữ như C, C++, Java, JavaScript, Objective-C, Protobuf, C#, v.v. - Ví dụ lệnh định dạng
Khi chạy lệnh trên, tệpclang-format -i my_source.cppmy_source.cppsẽ được tự động định dạng theo style đã chỉ định.
Ví dụ định dạng mã
// Before formatting
void test(QString&data, bool extraString) {
int i=0;
for (i=0;i<3;i++) {
data+="reallylongstringtoproducealonglineasanexample" + QString::number(i * 1000) + "/filetoload.html";
if (extraString)
{
data += "some-extra";
}
}
}
// After formatting
void test(QString &data, bool extraString)
{
int i = 0;
for (i = 0; i < 3; i++) {
data += "reallylongstringtoproducealonglineasanexample" + QString::number(i * 1000)
+ "/filetoload.html";
if (extraString) {
data += "some-extra";
}
}
}
Ví dụ trên cho thấy clang-format định dạng mã như thế nào. Các quy tắc định dạng có thể được thiết lập linh hoạt theo style của từng đội ngũ.
Các vấn đề của clang-format
clang-format là một công cụ tuyệt vời, nhưng nó có thể gây ra vấn đề với mã hiện có và lịch sử commit.
Những vấn đề chính
- Xung đột với mã hiện có
Khi định dạng toàn bộ tệp, cả những phần không liên quan đến định dạng cũng có thể bị thay đổi, tạo ra các thay đổi không cần thiết. - Làm rối lịch sử commit
Các thay đổi định dạng quy mô lớn có thể khiến lịch sử commit trở nên phức tạp, gây khó khăn cho việc merge nhánh, review code và phân tích mã. - Không nhất quán giữa mã mới và mã cũ
Khi thêm mã mới vào phần mã đã được định dạng sẵn, việc duy trì định dạng có thể trở nên khó khăn.
Giải pháp: git-clang-format
git-clang-format là một công cụ mở rộng của Git giúp chỉ áp dụng định dạng cho phần mã đã thay đổi. Nhờ đó, nó mang lại các lợi ích sau.
- Giảm thiểu phạm vi định dạng: chỉ áp dụng định dạng cho phần mã đã thay đổi
- Đơn giản hóa review: có thể xem xét riêng thay đổi định dạng và thay đổi phát triển
Cách dùng git-clang-format
Cài đặt
git-clang-format được cung cấp cùng với gói clang-format-node. Bạn có thể cài và sử dụng gói npm clang-format-git.
Workflow cơ bản
- Viết mã.
- Thêm thay đổi vào staging (
git add). - Chạy
git-clang-format.
Ví dụ
# Thêm tệp mới và đưa thay đổi vào staging
$ git diff --staged
diff --git a/x.cpp b/x.cpp
new file mode 100644
index 0000000..af14ed5
--- /dev/null
+++ b/x.cpp
@@ -0,0 +1,3 @@
+int main() {
+
+}
# Chạy git-clang-format
$ git-clang-format
changed files:
x.cpp
# Kiểm tra trạng thái sau khi định dạng
$ git status
On branch master
Changes to be committed:
new file: x.cpp
Changes not staged for commit:
modified: x.cpp
Với workflow này, bạn có thể review độc lập giữa thay đổi định dạng và thay đổi phát triển. Nếu không thích thay đổi định dạng, bạn cũng có thể hoàn tác bằng git checkout.
Chỉ định style
Có thể thiết lập style định dạng bằng tùy chọn --style.
$ git-clang-format --style=WebKit
$ git-clang-format --style=file # sử dụng tệp `.clang-format`
Kết luận
clang-format là một công cụ mạnh mẽ, nhưng trong thực tế công việc, chỉ riêng lệnh clang-format -i thường không đủ. Nếu dùng git-clang-format để chỉ áp dụng định dạng cho phần đã thay đổi, bạn có thể quản lý mã hiệu quả hơn và đơn giản hóa quy trình review.
Vì git-clang-format chỉ định dạng các thay đổi, nó cho phép duy trì một codebase gọn gàng và chuyên nghiệp đồng thời vẫn mang lại môi trường phát triển linh hoạt. Khi cần định dạng commit làm việc hoặc toàn bộ nhánh, chỉ cần dùng thêm một vài lệnh Git là có thể dễ dàng giải quyết các vấn đề về định dạng.
Cảm ơn bạn đã đọc bài viết dài này! Chúc toàn thể độc giả GeekNews một năm mới an khang 🙇♂️
- Kho GitHub: https://github.com/lumirlumir/npm-clang-format-node
- Trang tài liệu chính thức: https://clang-format-node.lumir.page/
2 bình luận
Xin gửi lời khen ngợi.
Cảm ơn!!