Gỡ lỗi web hiện đại trong Công cụ của Chrome cho nhà phát triển

Giới thiệu

Ngày nay, tác giả có thể sử dụng nhiều tính năng trừu tượng để xây dựng ứng dụng Web. Thay vì trực tiếp giao tiếp với các API cấp thấp mà Nền tảng web cung cấp, nhiều tác giả tận dụng các khung, công cụ xây dựng và trình biên dịch để viết ứng dụng từ góc độ cấp cao hơn.

Ví dụ: các thành phần được tạo dựa trên khung Angular được tạo bằng TypeScript với các mẫu HTML. Bên trong, Angular CLI và webpack biên dịch mọi thứ thành JavaScript và vào một gói được gọi là gói, sau đó được gửi đến trình duyệt.

Khi gỡ lỗi hoặc phân tích tài nguyên ứng dụng Web trong DevTools, bạn hiện có thể xem và gỡ lỗi phiên bản mã đã biên dịch này thay vì mã bạn thực sự viết. Tuy nhiên, với tư cách là tác giả, bạn không muốn điều này xảy ra:

  • Bạn không muốn gỡ lỗi mã JavaScript đã rút gọn, mà muốn gỡ lỗi mã JavaScript ban đầu.
  • Khi sử dụng TypeScript, bạn không muốn gỡ lỗi JavaScript mà muốn gỡ lỗi mã TypeScript ban đầu.
  • Khi sử dụng mẫu như với Angular, Lit hoặc JSX, bạn không phải lúc nào cũng muốn gỡ lỗi DOM thu được. Bạn nên tự gỡ lỗi các thành phần.

Nhìn chung, bạn có thể muốn gỡ lỗi mã của riêng mình khi viết mã đó.

Mặc dù bản đồ nguồn đã thu hẹp khoảng cách này ở một mức độ nào đó, nhưng Chrome DevTools và hệ sinh thái có thể làm được nhiều việc hơn trong lĩnh vực này.

Hãy cùng xem nhé!

Mã đã tạo so với mã đã triển khai

Hiện tại, khi di chuyển trong cây tệp trong Bảng điều khiển nguồn, bạn sẽ thấy nội dung của gói đã biên dịch và thường được rút gọn. Đây là các tệp thực mà trình duyệt tải xuống và chạy. Công cụ cho nhà phát triển gọi mã này là Mã đã triển khai.

Ảnh chụp màn hình cây tệp trong Công cụ của Chrome cho nhà phát triển cho thấy Mã đã triển khai.

Cách này không quá tiện dụng và thường khó nắm bắt. Là một tác giả, bạn muốn xem và gỡ lỗi mã mình đã viết chứ không phải Mã đã triển khai.

Để bù đắp, giờ đây bạn có thể để cây hiển thị Mã tác giả. Điều này giúp cây giống với các tệp nguồn mà bạn thấy trong IDE hơn. Giờ đây, các tệp này được tách biệt với Mã đã triển khai.

Ảnh chụp màn hình cây tệp trong Công cụ của Chrome cho nhà phát triển cho thấy Mã do tác giả tạo.

Để bật tuỳ chọn này trong Công cụ cho nhà phát triển Chrome, hãy chuyển đến phần Settings (Cài đặt) > Experiments (Thử nghiệm) rồi đánh dấu vào Group sources into Authored and Deployed trees (Nhóm các nguồn thành cây Đã tạo và Đã triển khai).

Ảnh chụp màn hình phần Cài đặt của DevTools.

"Chỉ cần mã của tôi"

Khi sử dụng các phần phụ thuộc hoặc xây dựng dựa trên một khung, các tệp của bên thứ ba có thể gây trở ngại cho bạn. Trong hầu hết trường hợp, bạn chỉ muốn xem mã của mình chứ không muốn xem thư viện bên thứ ba nào đó nằm gọn trong thư mục node_modules.

Để khắc phục vấn đề này, DevTools có một chế độ cài đặt bổ sung được bật theo mặc định: Tự động thêm tập lệnh đã biết của bên thứ ba vào danh sách bỏ qua. Bạn có thể tìm thấy danh sách này trong DevTools > Settings (Công cụ phát triển > Cài đặt) > Ignore List (Danh sách bỏ qua).

Ảnh chụp màn hình phần Cài đặt của DevTools.

Khi bạn bật chế độ cài đặt này, DevTools sẽ ẩn mọi tệp hoặc thư mục mà khung hoặc công cụ xây dựng đã đánh dấu là bỏ qua.

Kể từ Angular v14.1.0, nội dung của các thư mục node_moduleswebpack đã được đánh dấu là như vậy. Do đó, các thư mục này, các tệp trong đó và các cấu phần phần mềm khác của bên thứ ba như vậy sẽ không xuất hiện ở nhiều nơi trong DevTools.

Là tác giả, bạn không cần làm gì để bật hành vi mới này. Việc triển khai thay đổi này tuỳ thuộc vào khung.

Mã có trong danh sách bỏ qua trong dấu vết ngăn xếp

Một nơi mà các tệp có trong danh sách bỏ qua này không còn xuất hiện là trong dấu vết ngăn xếp. Với tư cách là tác giả, giờ đây bạn có thể xem nhiều dấu vết ngăn xếp liên quan hơn.

Ảnh chụp màn hình của dấu vết ngăn xếp trong DevTools.

Nếu muốn xem tất cả khung lệnh gọi của dấu vết ngăn xếp, bạn luôn có thể nhấp vào đường liên kết Hiện thêm khung.

Điều này cũng áp dụng cho ngăn xếp lệnh gọi mà bạn thấy trong khi gỡ lỗi và từng bước thực hiện mã. Khi các khung hoặc trình đóng gói thông báo cho DevTools về tập lệnh của bên thứ ba, DevTools sẽ tự động ẩn tất cả các khung lệnh gọi không liên quan và bỏ qua mọi mã trong danh sách bỏ qua trong khi gỡ lỗi từng bước.

Ảnh chụp màn hình Trình gỡ lỗi nguồn Công cụ cho nhà phát triển trong khi gỡ lỗi.

Mã thuộc danh sách bị bỏ qua trong cây tệp

Để ẩn các tệp và thư mục trong danh sách bỏ qua khỏi cây tệp Mã do tác giả tạo trong bảng điều khiển Nguồn, hãy đánh dấu vào Ẩn mã trong danh sách bỏ qua trong chế độ xem cây nguồn trong phần Cài đặt > Thử nghiệm trong DevTools.

Ảnh chụp màn hình phần Cài đặt của DevTools.

Trong dự án Angular mẫu, thư mục node_moduleswebpack hiện đã bị ẩn.

Ảnh chụp màn hình cây tệp trong Công cụ của Chrome cho nhà phát triển hiển thị Mã đã tạo nhưng không hiển thị node_modules.

Mã trong danh sách bỏ qua trong trình đơn "Mở nhanh"

Mã trong danh sách Bỏ qua không chỉ bị ẩn khỏi cây tệp mà còn bị ẩn khỏi trình đơn "Mở nhanh" (Control+P (Linux/Windows) hoặc Command+P (Mac)).

Ảnh chụp màn hình DevTools với trình đơn "Mở nhanh".

Cải tiến thêm cho dấu vết ngăn xếp

Sau khi đã đề cập đến các dấu vết ngăn xếp có liên quan, Công cụ của Chrome cho nhà phát triển thậm chí còn giới thiệu nhiều điểm cải tiến hơn nữa về dấu vết ngăn xếp.

Dấu vết ngăn xếp được liên kết

Khi một số thao tác được lên lịch diễn ra không đồng bộ, dấu vết ngăn xếp trong Công cụ cho nhà phát triển hiện chỉ cho biết một phần của câu chuyện.

Ví dụ: sau đây là một trình lập lịch biểu rất đơn giản trong tệp framework.js giả định:

function makeScheduler() {
  const tasks = [];

  return {
    schedule(f) {
      tasks.push({ f });
    },

    work() {
      while (tasks.length) {
        const { f } = tasks.shift();
        f();
      }
    },
  };
}

const scheduler = makeScheduler();

function loop() {
  scheduler.work();
  requestAnimationFrame(loop);
};

loop();

... và cách nhà phát triển có thể sử dụng giá trị này trong mã của riêng họ trong tệp example.js:

function someTask() {
  console.trace("done!");
}

function businessLogic() {
  scheduler.schedule(someTask);
}

businessLogic();

Khi thêm điểm ngắt bên trong phương thức someTask hoặc khi kiểm tra dấu vết in trong bảng điều khiển, bạn không thấy lệnh gọi businessLogic() nào là "nguyên nhân gốc" của thao tác này.

Thay vào đó, bạn sẽ chỉ thấy logic lập lịch khung đã dẫn đến việc thực thi nhiệm vụ và không có breadcrumb (tập hợp liên kết phân cấp) nào trong dấu vết ngăn xếp để giúp bạn tìm ra mối liên kết nhân quả giữa các sự kiện dẫn đến nhiệm vụ này.

Dấu vết ngăn xếp của một số mã được thực thi không đồng bộ mà không có thông tin về thời điểm lên lịch.

Nhờ tính năng mới có tên là "Gắn thẻ ngăn xếp không đồng bộ", bạn có thể kể toàn bộ câu chuyện bằng cách liên kết cả hai phần của mã không đồng bộ với nhau.

API gắn thẻ ngăn xếp không đồng bộ giới thiệu một phương thức console mới có tên là console.createTask(). Chữ ký API như sau:

interface Console {
  createTask(name: string): Task;
}

interface Task {
  run<T>(f: () => T): T;
}

Lệnh gọi console.createTask() trả về một thực thể Task mà sau này bạn có thể dùng để chạy nội dung f của tác vụ.

// Task Creation
const task = console.createTask(name);

// Task Execution
task.run(f);

Tác vụ này tạo ra mối liên kết giữa ngữ cảnh nơi tác vụ được tạo và ngữ cảnh của hàm không đồng bộ đang được thực thi.

Khi áp dụng cho hàm makeScheduler ở trên, mã sẽ trở thành như sau:

function makeScheduler() {
  const tasks = [];

  return {
    schedule(f) {
      const task = console.createTask(f.name);
      tasks.push({ task, f });
    },

    work() {
      while (tasks.length) {
        const { task, f } = tasks.shift();
        task.run(f); // instead of f();
      }
    },
  };
}

Nhờ đó, Công cụ của Chrome cho nhà phát triển hiện có thể hiển thị dấu vết ngăn xếp tốt hơn.

Dấu vết ngăn xếp của một số mã được thực thi không đồng bộ cùng với thông tin về thời điểm lên lịch.

Hãy lưu ý cách businessLogic() hiện được đưa vào dấu vết ngăn xếp! Không chỉ vậy, tác vụ này có tên quen thuộc là someTask thay vì requestAnimationFrame chung chung như trước.

Khung lệnh gọi thân thiện

Khung thường tạo mã từ mọi loại ngôn ngữ tạo mẫu khi xây dựng dự án, chẳng hạn như mẫu Angular hoặc JSX chuyển mã có giao diện HTML thành JavaScript thuần tuý và cuối cùng chạy trong trình duyệt. Đôi khi, các loại hàm được tạo này được đặt tên không thân thiện — tên chữ cái đơn sau khi được rút gọn hoặc một số tên khó hiểu hoặc không quen thuộc ngay cả khi không phải vậy.

Trong dự án mẫu, ví dụ về điều này là AppComponent_Template_app_button_handleClick_1_listener mà bạn thấy trong dấu vết ngăn xếp.

Ảnh chụp màn hình của dấu vết ngăn xếp có tên hàm được tạo tự động.

Để giải quyết vấn đề này, Chrome DevTools hiện hỗ trợ việc đổi tên các hàm này thông qua bản đồ nguồn. Nếu bản đồ nguồn có một mục tên để bắt đầu phạm vi hàm, thì khung lệnh gọi phải hiển thị tên đó trong dấu vết ngăn xếp.

Với tư cách là tác giả, bạn không cần phải làm gì để cho phép hành vi mới này. Việc triển khai thay đổi này tuỳ thuộc vào khung.

Hướng đến tương lai

Nhờ những tính năng bổ sung được nêu trong bài đăng này, Công cụ của Chrome cho nhà phát triển có thể mang đến cho bạn trải nghiệm gỡ lỗi tốt hơn. Nhóm chúng tôi muốn khám phá thêm nhiều lĩnh vực khác. Cụ thể là cách cải thiện trải nghiệm lập hồ sơ trong Công cụ cho nhà phát triển.

Nhóm Công cụ của Chrome cho nhà phát triển khuyến khích các tác giả khung áp dụng các tính năng mới này. Nghiên cứu điển hình: Gỡ lỗi góc tốt hơn bằng Công cụ cho nhà phát triển cung cấp hướng dẫn về cách triển khai phương thức này.