From d2f8ff1bb481e56cf6bcbbeed6f9b9118d91f30d Mon Sep 17 00:00:00 2001 From: twpayne Date: Tue, 30 Oct 2012 04:19:30 -0700 Subject: [PATCH] Updated Exports Files (markdown) --- Exports-Files.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Exports-Files.md b/Exports-Files.md index a0aae72..d3ac40f 100644 --- a/Exports-Files.md +++ b/Exports-Files.md @@ -14,4 +14,32 @@ Note: the `src/google.exports` file just makes the `goog.require` function be ex The `src/objectliterals.exports` file is specific. This file declares the config objects and properties for single-arg constructors. These declarations are done with the `@exportObjectLiteral` and `@exportObjectLiteralProperty` directives. This file is also processed with the `bin/generate-exports` script, but using the `--externs` and `--typedef` switches. The `generate-exports --externs` generates Closure externs from the `@exportObjectLiteral` and `@exportObjectLiteralProperty` directives. The Makefile places these externs in the `build/src/external/externs/types.js` file, which is used as a regular externs file by the Closure compiler (see `build/ol.json`). The `generate-exports --typedef` command generate typedef's for the object literals declared with `@exportObjectLiteral` and `@exportObjectLiteralProperty`. The `Makefile` places the typedef's in the `build/src/external/src/types.js`, which, like `exports.js`, is used as an input file for the ol.js build (see `build/ol.json`). Externs define types for config objects created by lib users, while typedef's define types created internally by the lib. -OL3 devs need to create new exports files when adding new API elements to the lib. They also need to declare single-arg constructors' config objects and properties in `src/objectliterals.exports`. \ No newline at end of file +OL3 devs need to create new exports files when adding new API elements to the lib. They also need to declare single-arg constructors' config objects and properties in `src/objectliterals.exports`. + +## Under the hood + +`build/src/internal/src/requireall.js` is used in the `make build` target to ensure that all source files are passed to the compiler. + +Before reading on, you should have a thorough understand of how the Closure Compiler handles exports and externs. + +The exports/externs/typedefs system is required so that the same source files can be used in several modes: + +1. Uncompiled (i.e. `mode=RAW`) +2. Application and ol3 library compiled together +3. ol3 library compiled, application uncompiled + +Cases 1 are 2 similar: no exports are needed (except for `ol.Object` property `get` and `set` methods whose names must be preserved), and object literals passed to single argument constructors are defined as `@typedef`s so that they can be type checked and the compiler can rename their properties. Everything is "internal". + +Case 3 is more complicated: we need to ensure that the appropriate library functions are exported so they can be used by application code. However, anything that is exported will be included in the built library and so increase the library size, hence the need for custom builds. Coarse-grained control over the custom build contents is achieved by deciding which `.exports` files to pass to the compiler. Object literals to single argument constructors are more complicated: these are supplied by the application, so the compiled library must not rename their properties. So, in "external" mode, in addition to the `@typedef`s, each object literals must be shadowed by an `@extern` declaration that declares an `@interface` in the `olx` namespace. A separate namespace is needed to avoid conflicts with the `ol` namespace used internally. Furthermore, a shadow derived class (e.g. `ol.MapExport`) is defined for each exported class that transparently translates the un-renamed external object literal into a possibly renamed internal object literal. This derived class is exported as its parent class by a cunning rename when it's exported. Easy, huh? + +Luckily, all this complexity is handled by the `generate-exports` script. The ol3 developer need only add his declarations to the `.exports` files and everything is auto-generated from this single source. + +### Approches that don't work + +#### Using the `@export` annotation + +Using `@export` in the source code means that all exported symbols would always be exported, this prevents custom builds. + +#### Using the `@expose` annotation + +This also prevents custom builds, as well as increasing the generated code size. \ No newline at end of file