Tài liệu
/

Khắc phục sự cố

/

Tránh trùng tên định danh

Tránh trùng tên định danh

Khi nhiều tệp đã làm rối VM cùng nằm trong một bundle, chúng có thể khai báo cùng một định danh cấp cao nhất và làm trang bị lỗi ngay lúc phân tích cú pháp. Dưới đây là lý do và cách khắc phục.

Triệu chứng

Quá trình build chạy bình thường, nhưng trình duyệt ném lỗi lúc phân tích cú pháp, trước khi ứng dụng khởi động:

Text

Để xem có bao nhiêu chunk khai báo cái tên trong thông báo lỗi, hãy đếm số tệp chứa một khai báo của nó:

Text

-l liệt kê mỗi tệp khớp một lần và -w chỉ khớp nguyên từ, nên vmdX không bị tính. var được bỏ ra vì việc lặp lại một khai báo var tự nó không phải là lỗi. Kết quả lớn hơn 1 nghĩa là tên đó được khai báo trong nhiều hơn một chunk. Hãy thay vmd bằng tên trong thông báo lỗi của bạn.

Trùng tên định danh chỉ gây hậu quả khi các khai báo nằm chung một phạm vi. Cùng một tên lặp lại trong các module hoặc closure riêng biệt không chứng tỏ có xung đột; lỗi phân tích cú pháp ở trên mới là bằng chứng.

Vì sao điều này xảy ra

Các preset VM dùng mangled-shuffled làm Identifier Names Generator. Nó duyệt một bảng chữ cái nhỏ theo một thứ tự xáo trộn, và khi làm rối VM, mọi biến toàn cục được đổi tên đều nhận tiền tố vm (giá trị mặc định của identifiersPrefix). Thứ tự xáo trộn được lưu đệm theo từng tiến trình, nên các tệp được làm rối trong cùng một tiến trình, hoặc với cùng một seed cố định, sẽ lấy từ cùng một dãy: biến toàn cục đầu tiên trong mỗi tệp có chung một tên, biến thứ hai có chung một tên khác, và cứ thế tiếp tục.

Mỗi tệp được làm rối độc lập và bộ sinh bắt đầu lại từ đầu dãy của nó cho từng tệp. Khi hai tệp rơi vào cùng một phạm vi, các tên sẽ trùng nhau. Hai khai báo cấp cao nhất const vmd = … nằm trong cùng một phạm vi và trình phân tích cú pháp từ chối khai báo thứ hai.

Các tùy chọn tạo thêm định danh cấp cao nhất làm tăng khả năng hai tệp đi tới cùng một tên được sinh ra. vmWrapTopLevelInitializers là một trong số đó, và mọi preset VM đều đã bật nó; các tùy chọn như vmDynamicOpcodes hoặc vmBytecodeEncoding còn thêm nhiều hơn nữa.

Cách khắc phục

Nên đóng gói trước, rồi làm rối bundle một lần. Nếu bạn vẫn làm rối từng tệp riêng và các script dùng chung phạm vi toàn cục, hãy chọn một trong các cách sau:

  • Bật randomIdentifiersPrefix (khuyến nghị)

    Mỗi lần làm rối sẽ nhận một tiền tố ngẫu nhiên được thêm vào trước mọi định danh toàn cục (khi làm rối VM, nó thay cho tiền tố vm mặc định). Tên từ các tệp khác nhau không còn dùng chung một không gian tên, nên xung đột biến mất mà bạn không cần tự phối hợp tiền tố thủ công.

  • Đặt một identifiersPrefix riêng cho mỗi tệp

    Tự truyền một tiền tố khác nhau khi làm rối từng tệp (ví dụ identifiersPrefix: 'auth_' cho một tệp, checkout_ cho tệp khác). Cách này hiệu quả nhưng dễ sai sót nếu bạn có nhiều tệp; nên ưu tiên tùy chọn ngẫu nhiên ở trên.

    JavaScript

  • Chuyển identifierNamesGenerator sang hexadecimal

    Tên thập lục phân dùng một không gian khóa lớn hơn nhiều, nên khả năng hai tệp sinh ra cùng một định danh thấp hơn hẳn, nhưng tính duy nhất không được đảm bảo. Đánh đổi: định danh dài hơn so với đầu ra của mangled-shuffled, nên bundle lớn hơn một chút.

  • Dùng giao diện làm rối hàng loạt nhiều tệp, hoặc kiểm tra plugin bundler của bạn

    Bảng điều khiển thêm một tiền tố riêng cho mỗi tệp khi bạn dùng tính năng làm rối hàng loạt nhiều tệp, vốn có trong các gói trả phí. Nếu bạn dùng plugin bundler, hãy kiểm chứng hành vi của nó thay vì mặc định cho rằng nó cũng làm vậy. Nếu bạn tự tích hợp việc làm rối bằng API npm, bạn phải tự bật tiền tố.

Để kiểm chứng bản sửa, hãy build lại và tải lại ứng dụng đã gộp, rồi xác nhận rằng SyntaxError đã biến mất. Cái tên trong thông báo lỗi cũ không còn được khai báo trong nhiều hơn một chunk nữa; tiền tố làm thay đổi mọi tên được sinh ra, nên lệnh grep ở trên chỉ cho bạn biết về đúng cái tên đó, không phải về các tên mới.

Tùy chọn liên quan