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:
Để 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ó:
-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ố
vmmặ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
identifiersPrefixriêng cho mỗi tệpTự 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.Chuyển
identifierNamesGeneratorsanghexadecimalTê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
randomIdentifiersPrefix- tiền tố ngẫu nhiên cho mỗi bản dựng (khuyến nghị)identifiersPrefix- chuỗi tiền tố tường minhidentifierNamesGenerator- dạng tên (mangled,hexadecimal, …)
