Thứ Tư, 27 tháng 11, 2013

Debug javascript với Chrome Dev Tools


Bạn đã bao giờ phải đau đầu khi đoạn JavaScript của mình không chạy không? Và sau đó lại phải sử dụng hàm alert() để xem code đó có chạy không. Rất mất công và khó thành công! Đặc biệt là khi ứng dụng web ngày càng yêu cầu xử lí phức tạp hơn nên JavaScript được viết rất nhiều vì thế việc debug rất cần thiết. Đừng lo lắng! Chrome Dev Tools đã giúp chúng ta rất nhiều :D Chúng ta cùng bắt đầu tìm hiểu về debug JavaScript nhé.


Bắt đầu debug

Như ta đã biết, lỗi trong code bao gồm:
  • Lỗi cú pháp: Code không thể chạy được và thông báo ra lỗi.
  • Lỗi ngữ nghĩa: Code chạy được nhưng không ra kết quả mong muốn.

Lỗi cú pháp

Lỗi của pháp sẽ được hiển thị trên Console của Chrome Dev Tools.
Loi cu phap

Như trên hình ta có thể thấy lỗi và vị trí lỗi (file bị lỗi với dòng code bị lỗi). Khi bạn bấm vào vị trí lỗi Chrome Dev Tools sẽ hiển thị đoạn JavaScript bị lỗi trên tab Source.

Lỗi ngữ nghĩa

Lỗi ngữ nghĩa thì khó debug hơn. Đầu tiên chúng ta phải phát hiện ra đoạn mã nào thực thi kết quả sai. Trên Chrome Dev Tools có rất nhiều cách để ta có thể thực hiện điều này:
1. View source của file
Đầu tiên, chúng ta mở Chrome Dev Tools. Sau đó chuyển qua tab Source.
Source Files

Như trên hình ta có thể thấy vùng khoanh đỏ hiển thị source files của web. Khi click vào tên file thì nó sẽ hiển thị source ở bên phải.
Lưu ý: Khi bạn mở tab Source của Chrome Dev Tools, khung hiển thị source files có thể sẽ không xuất hiện. Bạn cần bấm vào nút mở để hiển thị.
Button Open Source File

Mẹo nhỏ: Để có thể chuyển file trong tab Source nhanh chóng, chúng ta có thể thử dụng phím tắt Ctrl + P, sau đó gõ tên file cần xem source.
2. Kiểm tra đoạn mã sửa DOM
Tính năng này đặc biệt hữu ích khi ta muốn kiểm tra xem đoạn js nào sửa DOM. Mình đã giói thiệu ở bài: Mẹo nhỏ sử dụng Chrome Dev Tools.
Chrome Dev Tools - Breakpoint element
3. Kiểm tra đoạn mã thực thi AJAX
Ví dụ khi chúng ta đang làm một ứng dụng Web ecommerce chẳng hạn. Ta có nút button Add To Cart bên cạnh tên sản phẩm, khi bấm vào nút này thì nó sẽ thực thi AJAX gửi yêu cầu tới server. Nhưng vấn đề là ta muốn kiểm tra xem đoạn mã nào thực thi AJAX. Chrome Dev Tools đã cung cấp chức năng khi AJAX được chạy thì sẽ dừng tại dòng code đó.
Debug AJAX
4. Dừng chạy js khi xảy ra exception
Khi exception xảy ra JavaScript sẽ ngừng hoạt động và hiện thị lỗi trên Console của của Chrome Dev Tools. Như thế chúng ta sẽ rất khó để kiểm tra tại sao lại xảy ra exception, có thể biến này được gán sai, hàm kia có được chạy không. Ví thế Chrome Dev Tools đã cung cấp chức năng khi gặp exception thì dừng lại ở dòng ném exception để debug.
Để bật chức năng này, bạn chuyển sang tab Source của Chrome Dev Tools sau đó nhấn nút bấm như hình dưới đây.
Pause on exception

Công cụ debug

Dưới đây là ảnh mình đang debug JavaScript để minh họa rõ hơn :)
Debug js
1. File đang được debug
Khung bên trái sẽ hiển thị source files của web. File được đánh dấu là file đang được view source.
2. Đặt breakpoint
Breakpoint rất quan trọng khi ta debug. Khi JavaScript chạy đến dòng code ta đặt breakpoint thì nó sẽ dừng tại đó. Tại thời điểm đó, ta có thể:
  • Kiểm tra giá trị của biến
  • Chạy code JavaScript khác
  • Theo dõi Call Stack
Để đặt breakpoint trên Chrome Dev Tools, chúng ta có thể click vào cột hiển thị số dòng như trên hình, ví dụ:
Put Breakpoint
3. Dòng code đang debug
Khi JavaScript dừng chương trình tại breakpoint thì nó sẽ bôi đậm dòng đó như trên hình.
4. Watch Expression
Tại đây ta có thể chạy các đoạn mã khác kiểm tra giá trị của biến chẳng hạn: ví dụ như trên hình mình hiển thị biến json là kết quả trả về của AJAX, hoặc cũng có thể chạy các mã tính toán như 1 + 2.
5. Call Stack
Call Stack thể hiện thị luồng chương trình của JavaScript qua các  hàm. Như trên hình,  ta có thể thấy, hàm thực hiện đầu tiên là Send AJAX request lên server bởi jQuery và sau đó trải qua các hàm khác của jQuery, cuối cùng là hàm thực hiện khi nhận được kết quả trả về từ server.
6. Scope Variables
Vùng này sẽ hiển thị các biến trong scope hiện tại. Scope ở đây được hiểu là vùng không gian mà hàm đó sử dụng.
7. Breakpoints
Ô này hiển thị các breakpoint chúng ta đặt. Các breakpoint không nhất thiết chỉ đặt trong cùng một file mà có thể được đặt ở rất nhiều file khác nhau. Chúng ta có thể quản lý các breakpoint tại đây: Có thể hủy tác dụng của breakpoint (khi JavaScript chạy đến breakpoint thì nó sẽ không dừng lại và chạy tiếp).
9. Run
Khi JavaScript đang dừng lại tại breakpoint thì khi bấm vào Run thì nó sẽ tiếp đến breakpoint kế tiếp, nếu không có breakpoint kế tiếp nào thì nó sẽ chạy đến khi hết chương trình.
Như trên ví dụ, khi ta bấm vào Run thì JavaScript sẽ chạy tiếp các dòng code tiếp theo và dừng chương trình ở dòng 30 và ta tiếp tục debug tại đó.
10. Step Over
Step Over cũng chạy như Run nhưng thay vì chạy đến breakpoint kế tiếp, nó sẽ chạy xuống dòng tiếp theo và dừng chương trình ở đó để chúng ta có thể debug. Khi chúng ta bấm Step Over tiếp thì nó sẽ chạy tiếp xuống dòng dưới và dừng ở đó, cứ như thế JavaScript sẽ được chạy từng dòng từng dòng một để ta có thể dễ dàng debug.
Ví dụ như trên hình, khi ta bấm Step Over JavaScript sẽ chạy đến dòng 21 và dừng ở đó. Ta có thể tiếp tục debug tại dòng đó.
11. Step Into
Step Into sẽ chạy vào từng hàm trong dòng code được debug. Ví dụ khi chúng ta đang debug tại dòng 5 của đoạn code dưới đây:
thì khi ta bấm vào Step Into thì JavaScript sẽ chạy vào trong hàm hello và bắt đầu debug tại dòng 2.
12. Step Out
Step Out thì có tác dụng ngược lại với Step Into. Chúng ta sẽ lấy ví dụ ở trên làm ví dụ nhé: Khi JavaScript dừng lại ở dòng 2 thì bấm vào Step Out nó sẽ nhảy ra ngoài và dừng lại ở dòng 7.
13. Deactivate Breakpoints
Khi chúng ta đã phát hiện ra lỗi, công việc debug đã xong hoặc không muốn debug nữa thì chúng ta có thể hủy tác dụng của tất cả các breakpoints bởi nút Deactivate Breakpoints.
Ví dụ như trên hình, khi ta bấm vào Detactivate Breakpoints rồi bấm Run thì JavaScript sẽ chạy hết chương trình và không dừng lại ở breakpoint dòng 30.

Kết luận

Ở phần trên, mình vừa giới thiệu căn bản về Debug JavaScript với Chrome Dev Tools. Khi chúng ta biết các tính năng được cung cấp thì sẽ chỉ còn vấn đề làm quen với việc debug. Bạn debug càng nhiều thì sẽ càng có nhiều kinh nghiệm. Trong các bài tiếp theo, mình sẽ cố gắng giới thiệu nhiều hơn về debug JavaScript để chúng ta cùng nhau học hỏi nhé.