Bản đồ nguồn là gì?

Bản đồ nguồn là một công cụ quan trọng trong quá trình phát triển web hiện đại giúp việc gỡ lỗi trở nên dễ dàng hơn. Trang này khám phá các thông tin cơ bản về bản đồ nguồn, cách tạo bản đồ nguồn và cách chúng cải thiện trải nghiệm gỡ lỗi.

Nhu cầu của bản đồ nguồn

Các ứng dụng web ban đầu được xây dựng với độ phức tạp thấp. Các nhà phát triển đã triển khai trực tiếp các tệp HTML, CSS và JavaScript trên web.

Các ứng dụng web hiện đại và phức tạp hơn có thể cần nhiều công cụ trong quy trình phát triển. Ví dụ:

Tổng quan ngắn gọn về nhiều công cụ.
Một số công cụ phát triển ứng dụng web phổ biến.

Các công cụ này đòi hỏi một quy trình xây dựng để chuyển mã mã của bạn thành HTML, JavaScript và CSS chuẩn mà các trình duyệt có thể hiểu được. Bạn cũng nên tối ưu hoá hiệu suất bằng cách rút gọn và kết hợp các tệp này, sử dụng một công cụ như Terser.

Ví dụ: bằng các công cụ bản dựng, chúng tôi có thể chuyển đổi và nén tệp TypeScript sau đây thành một dòng JavaScript. Bạn có thể tự mình thử nghiệm trong bản minh hoạ này trên GitHub.

/* A TypeScript demo: example.ts */

document.querySelector('button')?.addEventListener('click', () => {
  const num: number = Math.floor(Math.random() * 101);
  const greet: string = 'Hello';
  (document.querySelector('p') as HTMLParagraphElement).innerText = `${greet}, you are no. ${num}!`;
  console.log(num);
});

Phiên bản nén sẽ là:

/* A compressed JavaScript version of the TypeScript demo: example.min.js  */

document.querySelector("button")?.addEventListener("click",(()=>{const e=Math.floor(101*Math.random());document.querySelector("p").innerText=`Hello, you are no. ${e}!`,console.log(e)}));

Tuy nhiên, việc nén mã có thể khiến việc gỡ lỗi trở nên khó khăn hơn. Bản đồ nguồn có thể loại bỏ vấn đề này: bằng cách ánh xạ mã đã biên dịch trở lại mã gốc, chúng có thể giúp bạn nhanh chóng tìm ra nguồn gốc gây ra lỗi.

Tạo bản đồ nguồn

Bản đồ nguồn là các tệp có tên kết thúc bằng .map (ví dụ: example.min.js.mapstyles.css.map). Hầu hết các công cụ tạo bản dựng đều có thể tạo bản đồ như Vite, webpack, Rollup, Parcelesbuild.

Một số công cụ có bản đồ nguồn theo mặc định. Những người khác có thể cần cấu hình bổ sung để tạo ra:

/* Example configuration: vite.config.js */
/* https://vitejs.dev/config/ */

export default defineConfig({
  build: {
    sourcemap: true, // enable production source maps
  },
  css: {
    devSourcemap: true // enable CSS source maps during development
  }
})

Tìm hiểu bản đồ nguồn

Để giúp gỡ lỗi, các tệp bản đồ nguồn này chứa thông tin thiết yếu về cách mã đã biên dịch ánh xạ với mã gốc. Dưới đây là ví dụ về bản đồ nguồn:

{
  "mappings": "AAAAA,SAASC,cAAc,WAAWC, ...",
  "sources": ["src/script.ts"],
  "sourcesContent": ["document.querySelector('button')..."],
  "names": ["document","querySelector", ...],
  "version": 3,
  "file": "example.min.js.map"
}

Để hiểu rõ từng trường này, bạn có thể đọc thông số kỹ thuật của bản đồ nguồn hoặc Cấu trúc của bản đồ nguồn.

Phần quan trọng nhất của bản đồ nguồn là trường mappings. Tệp này sử dụng chuỗi mã hoá VLQ cơ sở 64 để ánh xạ các đường và vị trí trong tệp đã biên dịch với tệp gốc tương ứng. Bạn có thể xem mối liên kết này bằng một trình trực quan hoá bản đồ nguồn như source-map-enhancedization hoặc Hình ảnh hoá bản đồ nguồn.

Một hình ảnh bản đồ nguồn.
Hình ảnh minh hoạ ví dụ về mã trước đó do một trình tạo trực quan tạo.

Cột đã tạo ở bên trái hiển thị nội dung nén, còn cột gốc hiển thị nguồn ban đầu.

Trình hiển thị sẽ mã hoá màu từng dòng trong cột gốc với mã tương ứng trong cột đã tạo.

Phần ánh xạ cho thấy các ánh xạ đã giải mã của mã. Ví dụ: mục nhập 65 -> 2:2 có nghĩa là:

  • đã tạo: Từ const bắt đầu ở vị trí 65 trong nội dung nén.
  • gốc: Từ const bắt đầu từ dòng 2 và cột 2 trong nội dung gốc.
Mục ánh xạ.
Hình ảnh trực quan về hoạt động liên kết, tập trung vào mục 65 -> 2:2.

Điều này cho phép các nhà phát triển nhanh chóng xác định mối quan hệ giữa mã đã rút gọn và mã gốc, giúp quá trình gỡ lỗi diễn ra suôn sẻ hơn.

Công cụ cho nhà phát triển trình duyệt áp dụng các bản đồ nguồn này để giúp bạn nhanh chóng xác định các vấn đề gỡ lỗi trong trình duyệt.

Công cụ cho nhà phát triển áp dụng bản đồ nguồn.
Ví dụ về cách các công cụ cho nhà phát triển trình duyệt áp dụng bản đồ nguồn và hiển thị mối liên kết giữa các tệp.

Tiện ích bản đồ nguồn

Bản đồ nguồn hỗ trợ các trường tiện ích tuỳ chỉnh bắt đầu bằng tiền tố x_. Một ví dụ là trường tiện ích x_google_ignoreList do Chrome DevTools. Hãy xem x_google_ignoreList để tìm hiểu thêm về cách các tiện ích này giúp bạn tập trung vào mã.

Hạn chế của bản đồ nguồn

Không may là quá trình liên kết nguồn không phải lúc nào cũng hoàn chỉnh như bạn cần. Trong ví dụ đầu tiên của chúng tôi, biến greet được tối ưu hoá trong quá trình xây dựng, mặc dù giá trị của biến đó được nhúng trực tiếp vào dữ liệu đầu ra của chuỗi cuối cùng.

Lời chào của biến thể chưa được liên kết.
Biến greet trong mã gốc bị thiếu trong liên kết.

Trong trường hợp này, khi bạn gỡ lỗi mã, các công cụ cho nhà phát triển có thể không dự đoán và hiển thị được giá trị thực tế. Loại lỗi này có thể khiến việc giám sát và phân tích mã trở nên khó khăn hơn.

Lời chào của biến đổi có giá trị không xác định.
Công cụ dành cho nhà phát triển không tìm thấy giá trị cho greet.

Đây là vấn đề cần được giải quyết trong thiết kế của bản đồ nguồn. Một giải pháp tiềm năng là đưa thông tin phạm vi vào bản đồ nguồn theo cách tương tự như cách các ngôn ngữ lập trình khác thực hiện với thông tin gỡ lỗi.

Tuy nhiên, điều này đòi hỏi toàn bộ hệ sinh thái phải làm việc cùng nhau để cải thiện thông số kỹ thuật và cách triển khai bản đồ nguồn. Để tuân theo tiến trình cải thiện khả năng gỡ lỗi bằng bản đồ nguồn, hãy tham khảo đề xuất cho Source Maps v4 trên GitHub.