https://github.com/openlayers/babel-plugin-jsdoc-closure
Transpiles JSDoc types from namepaths to types for Closure Compiler
https://github.com/openlayers/babel-plugin-jsdoc-closure
Last synced: 8 months ago
JSON representation
Transpiles JSDoc types from namepaths to types for Closure Compiler
- Host: GitHub
- URL: https://github.com/openlayers/babel-plugin-jsdoc-closure
- Owner: openlayers
- License: mit
- Created: 2018-02-06T08:43:40.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2018-06-12T07:46:55.000Z (over 7 years ago)
- Last Synced: 2024-11-10T22:40:43.810Z (about 1 year ago)
- Language: JavaScript
- Size: 24.4 KB
- Stars: 5
- Watchers: 5
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# babel-plugin-jsdoc-closure
Transpiles JSDoc types from [namepaths](http://usejsdoc.org/about-namepaths.html) with [module identifiers](http://usejsdoc.org/howto-commonjs-modules.html#module-identifiers) to types for Closure Compiler.
This is useful for type checking and building an application or library from a set of ES modules with Closure Compiler, without the use of any additional bundler.
## Installation
npm install babel-cli babel-plugin-jsdoc-closure
### Configuration
Create a `.babelrc` file in the root of your project to enable the plugin:
```json
{
"plugins": ["jsdoc-closure"],
}
```
**Note**: When your code uses Closure type casts (i.e. something like `/** @type {Custom} */ (foo)`), you need to configure Babel to use recast as parser and generator by modifying your `.babelrc` file:
```json
{
"plugins": ["jsdoc-closure"],
"parserOpts": {
"parser": "recast"
},
"generatorOpts": {
"generator": "recast"
}
}
```
You will also need to install recast to make this work:
npm install recast
To run the transform on your sources (`src/`) and output them to `build/`, run
node_modules/.bin/babel --out-dir build src
To build your project, create a simple build script (e.g. `build.js`) like this:
```js
const Compiler = require('google-closure-compiler').compiler;
const compiler = new Compiler({
js: [
'build/**.js',
// add directories for your dependencies, if any, here
],
entry_point: 'build/index.js',
module_resolution: 'NODE',
dependency_mode: 'STRICT',
process_common_js_modules: true,
jscomp_error: ['newCheckTypes'],
// Uncomment and modify for dependencies without Closure annotations
//hide_warnings_for: ['node_modules']
js_output_file: 'bundle.js'
});
compiler.run((exit, out, err) => {
if (exit) {
process.stderr.write(err, () => process.exit(exit));
} else {
process.stderr.write(out);
process.stderr.write(err);
}
});
```
To run the Compiler, simply call
node build.js
## What the plugin does
### Convert module namepaths to imported types
Closure Compiler does not allow JSDoc's [namepaths](http://usejsdoc.org/about-namepaths.html) with [module identifiers](http://usejsdoc.org/howto-commonjs-modules.html#module-identifiers) as types. Instead, with `module_resolution: 'NODE'`, it recognizes types that are imported from other files. Let's say you have a file `foo/Bar.js` with the following:
```js
/** @module foo/Bar */
/**
* @constructor
* @param {string} name Name.
*/
const Bar = function(name) {
this.name = name;
};
export default Bar;
```
Then you can use the `Bar` type in another module with
```js
/**
* @param {module:foo/Bar} bar Bar.
*/
function foo(bar) {}
```
This is fine for JSDoc, and this plugin transforms it to something like
```js
/**
* @param {foo$Bar} bar Bar.
*/
function foo(bar) {}
const foo$Bar = require('./foo/Bar');
```
With this, the type definition is recognized by Closure Compiler.
### Convert JSDoc object typedefs to Closure structural interfaces
JSDoc uses a nice, documentable format for `{Object}` typedefs:
```js
/**
* @typedef {Object} Foo
* @property {string} bar Bar.
* @property {module:types.Baz} baz Baz.
*/
```
Such typedefs are not understood by Closure compiler, so they are transformed to something like
```js
/** @interface */
export function Foo() {};
/** @type {(string)} */
Foo.prototype.bar;
/** @type {(_types_Baz)} */
Foo.prototype.baz;
```
Properties marked as optional with JSDoc notation are also handled. The plugin will transforms `@property {number} [foo] Foo.` or `@property {number=} foo Foo.` to `foo: (undefined|number)`.