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 thành phần trừu tượng để xây dựng ứng dụng web. Thay vì giao tiếp trực tiếp với các API cấp thấp hơn 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 của họ từ góc nhìn cấp cao hơn.

Ví dụ: các thành phần được xây dựng dựa trên khung Angular được ghi nhận bằng TypeScript với các mẫu HTML. Về sau, Angular CLI và webpack sẽ biên dịch mọi thứ thành JavaScript và thành một gói, sau đó được chuyển đến trình duyệt.

Khi gỡ lỗi hoặc phân tích tài nguyên của ứng dụng web trong Công cụ cho nhà phát triển, bạn hiện sẽ được xem và gỡ lỗi phiên bản mã đã biên dịch này của bạn thay vì mã mà bạn thực sự đã viết. Là một tác giả, điều này không phải là bạn muốn, mặc dù:

  • Bạn không muốn gỡ lỗi mã JavaScript đã rút gọn mà bạn muốn gỡ lỗi mã JavaScript ban đầu của mình.
  • Khi sử dụng TypeScript, bạn không muốn gỡ lỗi JavaScript mà lại muốn gỡ lỗi mã TypeScript ban đầu.
  • Khi sử dụng việc tạo mẫu như Angular, Lit hoặc JSX, không phải lúc nào bạn 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, có thể bạn sẽ muốn gỡ lỗi mã của chính mình như chính bạn đã viết.

Mặc dù bản đồ nguồn đã thu hẹp khoảng cách này ở một mức độ nào đó, nhưng Công cụ của Chrome cho nhà phát triển 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 điều hướng cây tệp trong Bảng điều khiển nguồn, bạn sẽ xem được 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ả. Nhờ vậy, cây này sẽ gần giống với các tệp nguồn mà bạn thấy trong IDE và các tệp này hiện được tách khỏ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ã tác giả.

Để bật tuỳ chọn này trong Công cụ của Chrome cho nhà phát triển, hãy chuyển đến phần Cài đặt > Thử nghiệm và chọn Nhóm các nguồn thành Cây đã tạo tác giả và Cây đã triển khai.

Ảnh chụp màn hình phần Cài đặt của Công cụ cho nhà phát triển.

"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 trên một khung, các tệp của bên thứ ba có thể cản trở 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.

Để bù đắp cho điều này, Công cụ cho nhà phát triển có một chế độ cài đặt bổ sung được bật theo mặc định: Tự động thêm các 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 công cụ này trong DevTools > Cài đặt > Danh sách bỏ qua.

Ảnh chụp màn hình phần Cài đặt của Công cụ cho nhà phát triển.

Khi bật chế độ cài đặt này, Công cụ cho nhà phát triển sẽ ẩn mọi tệp hoặc thư mục mà khung hoặc công cụ bản dựng đã đánh dấu là cần 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, tệp trong đó và các cấu phần phần mềm bên thứ ba khác không xuất hiện ở nhiều vị trí trong Công cụ cho nhà phát triển.

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 tiêu chuẩn.

Mã bị liệt kê trong dấu vết ngăn xếp bị bỏ qua

Trong dấu vết ngăn xếp có một nơi mà các tệp thuộc danh sách bỏ qua này không còn xuất hiện nữa. 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 dấu vết ngăn xếp trong Công cụ cho nhà phát triển.

Nếu muốn xem tất cả khung 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ị thêm khung.

Điều này cũng áp dụng cho các ngăn xếp lệnh gọi mà bạn thấy trong khi gỡ lỗi và duyệt qua mã. Khi các khung hoặc bộ gói thông báo cho Công cụ cho nhà phát triển về các tập lệnh của bên thứ ba, Công cụ cho nhà phát triển sẽ tự động ẩn tất cả các khung lệnh gọi không liên quan và chuyển qua bất kỳ mã nào có trong danh sách bỏ qua trong quá trình gỡ lỗi theo 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 có trong danh sách bỏ qua khỏi cây tệp Authored Code (Mã đã tạo) trong bảng Sources (Nguồn), hãy đánh dấu chọn Ẩn mã có trong danh sách bỏ qua trong chế độ xem dạng cây nguồn trong phần Cài đặt > Thử nghiệm trong Công cụ cho nhà phát triển.

Ảnh chụp màn hình phần Cài đặt của Công cụ cho nhà phát triển.

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, trong đó cho thấy Mã tác giả (Authored Code) nhưng không cho thấynode_modules.

Mã bị bỏ qua trong trình đơn "Mở nhanh"

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

Ảnh chụp màn hình Công cụ cho nhà phát triển có trình đơn "Mở nhanh".

Thêm nhiều điểm cải tiến đối với dấu vết ngăn xếp

Sau khi đã đề cập đến 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ụ: dưới đâ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ộ không có thông tin về thời điểm lên lịch mã.

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ụ tạo thành 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.

Áp dụng cho hàm makeScheduler ở trên, mã sẽ có dạng 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ó thông tin về thời điểm lên lịch mã.

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òn có tên quen thuộc là someTask thay vì requestAnimationFrame chung chung như trước đây.

Khung cuộc gọi thân thiện

Các khung thường tạo mã từ tất cả các 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 nhằm biến mã giống HTML thành JavaScript thuần tuý để rồi cuối cùng sẽ chạy trong trình duyệt. Đôi khi, những loại hàm được tạo này được đặt tên không thân thiện cho lắm — có thể là tên một chữ cái sau khi rút gọn hoặc một số tên ít người biết đến hoặc lạ lẫm ngay cả khi chúng không được dùng nữa.

Trong dự án mẫu, một ví dụ 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 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, Công cụ của Chrome cho nhà phát triển 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 tiêu chuẩn.

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

Nhờ những nội dung 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 lại cho bạn trải nghiệm gỡ lỗi tốt hơn. Còn nhiều khía cạnh khác mà nhóm muốn khám phá. 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.