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 tính năng tạo 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 tế mà trình duyệt tải xuống và chạy. Công cụ cho nhà phát triển gọi đâ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 thuận tiện và thường khó nắm bắt. Là tác giả, bạn muốn xem và gỡ lỗi mã mà mình đã viết, chứ không phải Mã đã triển khai.

Để khắc phục vấn đề này, giờ đây, bạn có thể yêu cầu cây hiển thị Mã do tác giả tạo. Đ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ỉ 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 các trường hợp, bạn chỉ muốn xem mã của mình, chứ không phải mã của một số thư viện bên thứ ba nằm 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 thư mục node_moduleswebpack đã được đánh dấu 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 nữa là trong dấu vết ngăn xếp. Giờ đây, với tư cách là tác giả, bạn có thể xem thêm dấu vết ngăn xếp có liên quan.

Ả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ủa Công cụ cho nhà phát triển trong khi gỡ lỗi.

Mã có trong danh sách 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

Đã đề cập đến các dấu vết ngăn xếp liên quan, Công cụ cho nhà phát triển của Chrome còn cải thiện nhiều hơn nữa đối với các 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 DevTools hiện chỉ cho biết một phần thông tin.

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 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 một điểm ngắt bên trong phương thức someTask hoặc khi kiểm tra dấu vết được in trong bảng điều khiển, bạn sẽ không thấy bất kỳ nội dung nào đề cập đến lệnh gọi businessLogic() là "nguyên nhân gốc rễ" của thao tác này.

Thay vào đó, bạn chỉ thấy logic lên lịch khung dẫn đến việc thực thi tác vụ và không có dấu vết bánh mì trong dấu vết ngăn xếp để giúp bạn tìm ra mối liên hệ nhân quả giữa các sự kiện dẫn đến tác 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 của tác vụ f.

// 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 một bản đồ nguồn có mục nhập tên cho phần bắt đầu của phạm vi hàm, thì khung lệnh gọi sẽ hiển thị tên đó trong dấu vết ngăn xếp.

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.

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 phân tích tài nguyên trong Công cụ cho nhà phát triển.

Nhóm Công cụ cho nhà phát triển Chrome khuyến khích các tác giả khung sử dụng các tính năng mới này. Bài viết Nghiên cứu điển hình: Gỡ lỗi Angular hiệu quả hơn bằng Công cụ của Chrome cho nhà phát triển đưa ra hướng dẫn về cách triển khai việc này.