Mục đích của video
Phần mở rộng là các nội dung khai báo cho wrap Compiler biết tên của các biểu tượng không nên đổi tên trong quá trình biên dịch nâng cao. Chúng được gọi là bên ngoài vì các ký hiệu này thường được xác định bằng mã bên ngoài quá trình biên dịch, chẳng hạn như mã gốc hoặc thư viện bên thứ ba. Vì lý do này, các trình ngoài
Nhìn chung, bạn nên coi bên ngoài là một hợp đồng API giữa người triển khai và người tiêu dùng của một số đoạn mã đã biên dịch. Phần bên ngoài xác định nội dung mà trình triển khai hứa hẹn sẽ cung cấp và những gì người tiêu dùng có thể phụ thuộc vào việc sử dụng. Cả hai bên cần bản sao hợp đồng.
Các tệp thông tin tương tự như tệp tiêu đề ở các ngôn ngữ khác.
Cú pháp Externs
Tệp này là những tệp trông rất giống với JavaScript bình thường, được chú thích cho Closure Compiler. Điểm khác biệt chính là nội dung bên trong không bao giờ được in trong kết quả đã biên dịch, vì vậy, không có giá trị nào có ý nghĩa, mà chỉ có tên và loại.
Dưới đây là ví dụ về tệp externs cho thư viện đơn giản.
// The `@externs` annotation is the best way to indicate a file contains externs. /** * @fileoverview Public API of my_math.js. * @externs */ // Externs often declare global namespaces. const myMath = {}; // Externs can declare functions, most importantly their names. /** * @param {number} x * @param {number} y * @return {!myMath.DivResult} */ myMath.div = function(x, y) {}; // Note the empty body. // Externs can contain type declarations, such as classes and interfaces. /** The result of an integer division. */ myMath.DivResult = class { // Constructors are special; member fields can be declared in their bodies. constructor() { /** @type {number} */ this.quotient; /** @type {number} */ this.remainder; } // Methods can be declared as usual; their bodies are meaningless though. /** @return {!Array<number>} */ toPair() {} }; // Fields and methods can also be declared using prototype notation. /** * @override * @param {number=} radix */ myMath.DivResult.prototype.toString = function(radix) {};
Cờ --externs
Nhìn chung, chú thích @externs
là cách tốt nhất để thông báo cho trình biên dịch rằng một tệp có chứa bên ngoài. Bạn có thể đưa các tệp như vậy vào
các tệp nguồn thông thường bằng cách sử dụng cờ dòng lệnh --js
,
Tuy nhiên, có một cách cũ để chỉ định tệp bên ngoài. Bạn có thể sử dụng cờ hiệu dòng lệnh --externs
để chuyển tệp extexer ra bên ngoài. Bạn không nên dùng phương pháp này.
Sử dụng Exter
Bạn có thể sử dụng các nội dung bên ngoài như sau.
/** * @fileoverview Do some math. */ /** * @param {number} x * @param {number} y * @return {number} */ export function greatestCommonDivisor(x, y) { while (y != 0) { const temp = y; // `myMath` is a global, it and `myMath.div` are never renamed. const result = myMath.div(x, y); // `remainder` is also never renamed on instances of `DivResult`. y = result.remainder; x = temp; } return x; }
Cách bao gồm mã ngoại lệ bằng Closure Compiler Service API
Cả ứng dụng Closure Compiler và API dịch vụ Closure Compiler đều cho phép khai báo bên ngoài. Tuy nhiên, giao diện người dùng của dịch vụ Closure Compiler không cung cấp thành phần giao diện để chỉ định các tệp bên ngoài.
Có ba cách để gửi nội dung khai báo bên ngoài đến dịch vụ Trình biên dịch khoá:
-
Truyền một tệp chứa chú thích
@externs
dưới dạng tệp nguồn. -
Chuyển JavaScript đến dịch vụ Closure Compiler (Trình biên dịch đóng) trong tham số
js_externs
. -
Truyền URL của một tệp JavaScript đến dịch vụ Trình biên dịch đóng trong tham số
externs_url
.
Sự khác biệt duy nhất giữa việc sử dụng js_externs
và sử dụng externs_url
là cách JavaScript được thông báo đến dịch vụ Trình biên dịch đóng.
Mục đích xuất khẩu
Xuất là một cơ chế khác để đặt tên nhất quán cho các ký hiệu sau khi biên dịch. Chúng ít hữu ích hơn so với extern và thường gây nhầm lẫn. Tốt nhất là bạn nên tránh sử dụng tất cả trừ những trường hợp đơn giản.
Tính năng xuất phụ thuộc vào thực tế là Closure Compiler không sửa đổi giá trị cố định kiểu chuỗi. Khi chỉ định một đối tượng cho một thuộc tính có tên bằng giá trị cố định, đối tượng đó sẽ có sẵn thông qua tên thuộc tính đó ngay cả sau khi biên dịch.
Dưới đây là một ví dụ đơn giản.
/** * @fileoverview Do some math. */ // Note that the concept of module exports is totally unrelated. /** @return {number} */ export function myFunction() { return 5; } // This assignment ensures `myFunctionAlias` will be a global alias exposing `myFunction`, // even after compilation. window['myFunctionAlias'] = myFunction;
Nếu đang sử dụng Thư viện đóng, bạn cũng có thể khai báo tệp xuất bằng các hàm
goog.exportSymbol
và goog.exportProperty
.
Bạn có thể xem thêm thông tin trong tài liệu về Thư viện đóng cửa của các hàm này. Tuy nhiên, hãy lưu ý rằng các trình biên dịch này có hỗ trợ đặc biệt và sẽ được chuyển đổi hoàn toàn trong đầu ra đã biên dịch.
Vấn đề khi xuất dữ liệu
Nội dung xuất khác với nội dung bên ngoài vì chúng chỉ tạo bí danh hiển thị để người tiêu dùng tham chiếu. Trong mã đã biên dịch, biểu tượng đã xuất sẽ vẫn được đổi tên. Vì lý do này, các biểu tượng được xuất phải là hằng số, vì việc gán lại các biểu tượng đó trong mã sẽ khiến bí danh bị lộ chỉ trỏ sai.
Sự tinh vi trong việc đổi tên này đặc biệt phức tạp đối với các thuộc tính của thực thể được xuất.
Về lý thuyết, các bản xuất có thể cho phép kích thước mã nhỏ hơn so với bên ngoài, vì tên dài vẫn có thể thay đổi thành tên ngắn hơn trong mã của bạn. Trên thực tế, những điểm cải tiến này thường rất nhỏ và không biện minh cho việc xuất dữ liệu nhầm lẫn.
Tính năng xuất cũng không cung cấp API để người tiêu dùng tuân theo cách thức hoạt động của bên ngoài. So với nội dung xuất, bên ngoài ghi lại các biểu tượng mà bạn dự định hiển thị, loại của chúng và cung cấp cho bạn một nơi để thêm thông tin sử dụng. Ngoài ra, nếu người tiêu dùng của bạn cũng sử dụng Closure Compiler, họ sẽ cần các công cụ bên ngoài để biên dịch.