Kỹ thuật debug ứng dụng viết bằng Node.js

Kỹ thuật debug ứng dụng viết bằng Node.js

Tin ngắn hàng ngày dành cho bạn
  • Bắt đầu kỳ nghỉ tết rồi nên mình cũng không đăng bài nữa. Hẹn gặp lại các bạn qua tết nha 😁

    » Xem thêm
  • Tiếp tục về jj. Đang thắc mắc là nó mới thế liệu có ai làm mấy phần mềm dạng GUI cho dễ nhìn chưa. Kiểu giống như git thì có quá nhiều rồi không đếm xuể.

    May quá, tác giả tổng hợp lại luôn rồi Community-built tools around Jujutsu 🥳

    » Xem thêm
  • Turso thông báo rằng họ đang viết lại SQLite bằng Rust. Thế là lại có thêm một bằng chứng nữa cũng cố cho câu nói Rust đang "tái định nghĩa" lại nhiều thứ.

    Nhưng nguyên nhân sâu xa mới thú vị. Tại sao họ lại làm vậy? Ai cũng biết SQLite là nguồn mở, ai cũng có thể tạo bản sao (fork) để chỉnh sửa lại theo ý mình. Lẽ nào nhóm của Turso không thích hoặc không tin vào C - vốn là ngôn ngữ dùng để cấu thành SQLite.

    Mình xin kể chuyện một chút. Turso là một bên cung cấp dịch vụ máy chủ cơ sở dữ liệu dựa trên SQLite, họ đã thực hiện một vài tùy chỉnh trên bản sao của SQLite để phục vụ cho mục đích của mình, gọi nó là libSQL. Họ "hào phóng" cho cộng đồng đóng góp thoải mái.

    Quay trở lại SQLite là mã nguồn mở chứ không phải là đóng góp mở. Chỉ có một nhóm người đứng đằng sau duy trì mã nguồn này, và họ không tiếp nhận yêu cầu kéo (pull request) từ những người khác. Đồng nghĩa mọi thay đổi hoặc tính năng đều là của nhóm người này tạo ra. Có vẻ như SQLite rất phổ biến nhưng cộng đồng không thể làm điều mà họ muốn là đóng góp cho sự phát triển của nó.

    Chúng ta biết rằng hầu hết ứng dụng mã nguồn mở thường đi kèm với một thư mục "tests" với các bài kiểm tra rất nghiêm ngặt. Điều đó giúp cho sự cộng tác trong phát triển trở nên dễ dàng hơn. Nếu muốn chỉnh sửa hoặc thêm một tính năng mới, trước hết bạn cần phải đảm bảo sự thay đổi vượt qua được tất cả bài kiểm tra. Nhiều thông tin cho rằng SQLite không công khai bộ kiểm tra này. Điều này vô tình gây khó khăn cho những ai muốn chỉnh sửa mã nguồn. Vì họ không chắc chắn rằng liệu triển khai mới của mình có phù hợp với những tính năng cũ hay không.

    tursodatabase/limbo là dự án viết lại SQLite bằng Rust đã nhắc đến ở đầu bài. Họ nói rằng nó hoàn toàn tương thích với SQLite và nguồn mở hoàn toàn. limbo đang trong giai đoạn hoàn thiện. Chúng ta hãy chờ xem kết quả trong tương lai thế nào nhé. Bài viết chi tiết tại Introducing Limbo: A complete rewrite of SQLite in Rust.

    » Xem thêm

Vấn đề

Debug là một trong những kỹ năng không thể thiếu của một developer. Trong bất kỳ vị trí nào, ngôn ngữ gì... mà có liên quan đến viết mã thì không thể không biết debug. Bởi mỗi dòng code được thêm vào, nguy cơ tạo ra lỗi càng tăng. Debug giúp cho chúng ta tiến hành tìm ra nguyên nhân của lỗi, hay chí ít là kiểm tra xem liệu chương trình có đang hoạt động đúng như ta mong muốn.

Với mỗi nền tảng hay ngôn ngữ có các cách debug khác nhau, tùy thuộc vào khả năng chăm chút của nhà phát triển mà nó đi từ dễ dàng đến khó. Trong Node, có nhiều cách để developer tiến hành gỡ lỗi. Một trong những cách đó là "console.log every where". Vậy ngoài console.log ra thì còn cách nào debug ứng dụng viết bằng Javascript/Node.js nữa hay không?

Console.log tốt nhưng chưa đủ

Bạn được học cách in mọi thứ ra màn hình bằng console.log. Muốn xem nội dung của biến thì console.log, muốn xem chương trình có chạy vào hàm này không cũng console.log, thậm chí console.log ra nhiều dòng thông tin khác để nhìn cho dễ... Điều này vô hình gây ra những phiền hà, thậm chí là rắc rối như mã trở nên cồng kềnh, rối loạn thông tin trong console... khiến cho nhiều người có cái nhìn không thiện cảm với nó.

Lợi ích console.log mang lại chúng ta thấy rõ, vì tính chất hiển thị ra được thông tin nhanh gọn mà nó thường được sử dụng trong debug. Bằng cách đặt console.log ở những vị trí mà ta muốn theo dõi giúp người gỡ lỗi nhanh chóng nắm bắt được luồng cũng như vị trí gây ra lỗi. Tuy nhiên việc sử dụng console.log vô tội vạ hoặc lạm dụng gây ra một sự "nhiễu loạn" thông tin khủng khiếp trong console, thậm chí nó còn có khả năng gây ra vấn đề về hiệu năng.

Nếu bạn vẫn hay sử dụng console.log để debug mà cảm hài lòng thì tôi vẫn muốn giới thiệu cho bạn một phương pháp mới hơn. Bởi vì lợi ích nó mang lại hơn hẳn console.log về mọi mặt. Còn bạn đang cảm thấy không hài lòng thì quả là khởi đầu tuyệt vời.

Inspector và cách hoạt động

Inspector là một trình gỡ lỗi được tích hợp trong Node.js, khi khởi chạy ứng dụng với cờ inspect hoặc --inspect, Node.js sẽ khởi chạy và lắng nghe trình gỡ lỗi. Theo mặc định nó lắng nghe ở địa chỉ và cổng 127.0.0.1:9229. Để kết nối đến, hoặc sử dụng các trình debug chuyên nghiệp bạn sẽ phải kết nối đến một địa chỉ trông giống như là ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e với 0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e là UUID của ứng dụng.

Ví dụ bạn có một file index.js:

const a = 1;
const b = 2;
const sum = a + b;

Khi debug bằng console.log, muốn biết giá trị của sum thì đặt console.log(sum) ngay bên dưới. Còn khi debug với cờ inspect như sau:

$ node inspect index.js
< Debugger listening on ws://127.0.0.1:9229/2855e131-b944-4ae4-bb4d-a6d374b83088
< For help, see: https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in index.js:1
> 1 const a = 1;
  2 const b = 2;
  3 const sum = a + b;

Bạn sẽ thấy kết quả trông giống như trên, với dòng Break on start in index.js:1 đang bắt đầu từ dòng thứ nhất. Bây giờ nhập n rồi enter bạn sẽ thấy chuyển sang dòng 2:

debug> n
break in index.js:2
  1 const a = 1;
> 2 const b = 2;
  3 const sum = a + b;
  4 

Muốn xem giá trị của a, chúng ta dùng lệnh watch.

debug> watch('a')

Lúc này giá trị của a chưa hiển thị ra, thao tác trên chỉ mới khởi tạo nhiệm vụ theo dõi giá trị của a thôi, hãy nhập n để đến dòng tiếp theo bạn sẽ thấy giá trị của a xuất hiện.

debug> n
break in index.js:3
Watchers:
  0: a = 1
 
  1 const a = 1;
  2 const b = 2;
> 3 const sum = a + b;
  4

Ngoài các chỉ thị n và các hàm watch ra còn nhiều chỉ thị và lệnh khác, bạn đọc xem thêm tại Debuger Command reference.

Chà, đến đây nhiều bạn sẽ thấy debug sao mà khó khăn đến thế, cứ gõ gõ như thế thì đến bao giờ. Đúng thật gõ như thế thì biết đến bao giờ mới xong, đã thế lại còn khó thao tác, khó theo dõi nữa.

Nhưng điều tôi trình bày trên chỉ là cách debug bằng công cụ dòng lệnh (CLI), đó cũng là nền móng của những công cụ debug hiện đại. Tôi chỉ muốn trình bày ra cho mọi người hiểu cách hoạt động của Inspector, còn trong thực tế chúng ta sẽ debug thông qua công cụ trợ giúp của Text editor hoặc IDE.

Debug bằng Break point Tích hợp Text editor / IDE

Break point là vị trí bạn muốn trình debug nhảy đến ngay lập tức mà không phải next qua từng dòng. Break point hiệu quả trong trường hợp bạn xác định được ngay vị trí nghi ngờ hoặc muốn kiểm tra trạng thái của tất cả các biến từ đầu đến khi chạy đến vị trí đó.

Hầu hết các trình viết code Node.js đều có công cụ debug, và nó dựa trên Inspector. Ví dụ nếu bạn đang dùng VSCode, hãy bấm vào Run and Debug.

Debugging Node.js - Step 1

Bấm vào Show all automatic debug configurations > Node.js > Run Current file để chạy debug trên tệp hiện tại.

Debugging Node.js - Step 2

Để đặt Break point rất đơn giản, chỉ cầm bấm vào bên trái số dòng một chấm đỏ sẽ hiện ra tức là bạn đã đặt thành công tại vị trí đó.

Debugging Node.js - Step 3

Bây giờ hãy chạy debug, bạn sẽ thấy trình gỡ lỗi dừng lại ở dòng số 3.

Debugging Node.js - Step 4

Thử di chuột vào các biến a, b, sum bạn sẽ thấy giá trị hiện tại của chúng khi chương trình chạy đến dòng thứ 3.

Hoặc là nhìn vào ô phía bên tay trái, đó là nơi chứa tất cả dữ liệu của trình gỡ lỗi thu thập được khi chạy chương trình.

Debugging Node.js - Step 5

Để next hoặc thực hiện các thao tác khác trong quá trình gỡ lỗi, hãy để ý vào trình điều khiển giống như thế này tại cửa sổ VSCode.

Debugging Node.js - Step 6

Có thể bạn cần phải học các sử dụng từng nút tại bài viết này. Bật mí nút đầu tiên giúp bạn nhanh chóng nhảy đến điểm Break point tiếp theo hoặc kết thúc lượt debug nếu không còn Break point nào sau đó.

Cuối cùng, bạn đọc có thể tìm hiểu chi tiết hơn về cách debug ứng dụng viết bằng Javascript/Node.js tại Node.js debugging in VS Code.

Tổng kết

Debug là một trong những kỹ năng không thể thiếu của một developer. Còn code là còn bug mà muốn fix bug thì phải trang bị cho mình kỹ năng gỡ lỗi chuyên nghiệp. Inspector là một trình gỡ lỗi được tích hợp trong Node.js, các Text editor hoặc IDE dựa vào Inspector để tạo cho chúng ta một trình gỡ lỗi chuyên nghiệp mà tiện ích hơn rất nhiều so với console.log.

Tham khảo:

Cao cấp
Hello

Bí mật ngăn xếp của Blog

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (0)

Nội dung bình luận...
Bấm hoặc cuộn mạnh để sang bài mới