diff --git a/README.md b/README.md index 6f784f0cd..e822e7e9f 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,24 @@ Contents * [Examples](#examples)
A few examples to get you started. -* [Documentation](#documentation)
- A list of available documentation resources. + * [Using .proto files](#using-proto-files) + * [Using JSON descriptors](#using-json-descriptors) + * [Using reflection only](#using-reflection-only) + * [Using custom classes](#using-custom-classes) + * [Using services](#using-services) + * [Usage with TypeScript](#usage-with-typescript) * [Command line](#command-line)
How to use the command line utility. + * [pbjs for JavaScript](#pbjs-for-javascript) + * [pbts for TypeScript](#pbts-for-typescript) + * [Reflection vs. static code](#reflection-vs-static-code) + * [Command line API](#command-line-api) + +* [Additional documentation](#additional-documentation)
+ A list of available documentation resources. + * [Performance](#performance)
A few internals and a benchmark on performance. @@ -329,7 +341,7 @@ var root = new Root().define("awesomepackage").add(AwesomeMessage); ... ``` -Detailed information on the reflection structure is available within the [documentation](#documentation). +Detailed information on the reflection structure is available within the [API documentation](#additional-documentation). ### Using custom classes @@ -465,7 +477,7 @@ protobuf.load("awesome.proto", function(err, root) { }); ``` -**Note:** Dynamically generated runtime message classes cannot be typed, technically, so you must either access its fields using `message["awesomeField"]` notation or you can utilize [typings of its static counterpart](https://github.com/dcodeIO/protobuf.js/tree/master/cli#pbts) for full typings support. +**Note:** Dynamically generated runtime message classes cannot be typed, technically, so you must either access its fields using `message["awesomeField"]` notation or you can utilize [typings of its static counterpart](#pbts-for-typescript) for full typings support. If you generated static code to `bundle.js` using the CLI and its type definitions to `bundle.d.ts` instead, then you can just do: @@ -486,25 +498,177 @@ var buffer = AwesomeMessage.encode(message).finish(); /// ``` -Documentation -------------- +Command line +------------ + +**Note** that moving the CLI to [its own package](./cli) is a work in progress. At the moment, it's still part of the main package. + +The command line interface (CLI) can be used to translate between file formats and to generate static code as well as TypeScript definitions. + +### pbjs for JavaScript + +``` +Translates between file formats and generates static code. + + -t, --target Specifies the target format. Also accepts a path to require a custom target. + + json JSON representation + json-module JSON representation as a module + proto2 Protocol Buffers, Version 2 + proto3 Protocol Buffers, Version 3 + static Static code without reflection (non-functional on its own) + static-module Static code without reflection as a module + + -p, --path Adds a directory to the include path. + + -o, --out Saves to a file instead of writing to stdout. + + --sparse Exports only those types referenced from a main file (experimental). + + Module targets only: + + -w, --wrap Specifies the wrapper to use. Also accepts a path to require a custom wrapper. + + default Default wrapper supporting both CommonJS and AMD + commonjs CommonJS wrapper + amd AMD wrapper + es6 ES6 wrapper (implies --es6) + + -r, --root Specifies an alternative protobuf.roots name. + + -l, --lint Linter configuration. Defaults to protobuf.js-compatible rules: + + eslint-disable block-scoped-var, no-redeclare, no-control-regex, no-prototype-builtins + + --es6 Enables ES6 syntax (const/let instead of var) + + Proto sources only: + + --keep-case Keeps field casing instead of converting to camel case. + + Static targets only: + + --no-create Does not generate create functions used for reflection compatibility. + --no-encode Does not generate encode functions. + --no-decode Does not generate decode functions. + --no-verify Does not generate verify functions. + --no-convert Does not generate convert functions like from/toObject + --no-delimited Does not generate delimited encode/decode functions. + --no-beautify Does not beautify generated code. + --no-comments Does not output any JSDoc comments. + + --force-long Enfores the use of 'Long' for s-/u-/int64 and s-/fixed64 fields. + --force-message Enfores the use of runtime messages instead of plain objects. + +usage: pbjs [options] file1.proto file2.json ... (or) other | pbjs [options] - +``` + +For production environments it is recommended to bundle all your .proto files to a single .json file, which minimizes the number of network requests and avoids any parser overhead (hint: works with just the **light** library): + +``` +$> pbjs -t json file1.proto file2.proto > bundle.json +``` + +Now, either include this file in your final bundle: + +```js +var root = protobuf.Root.fromJSON(require("./bundle.json")); +``` + +or load it the usual way: + +```js +protobuf.load("bundle.json", function(err, root) { + ... +}); +``` + +Generated static code, on the other hand, works with just the **minimal** library. For example + +``` +$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto +``` + +will generate static code for definitions within `file1.proto` and `file2.proto` to a CommonJS module `compiled.js`. + +**ProTip!** Documenting your .proto files with `/** ... */`-blocks or (trailing) `/// ...` lines translates to generated static code. + + +### pbts for TypeScript + +``` +Generates TypeScript definitions from annotated JavaScript files. + + -o, --out Saves to a file instead of writing to stdout. + + -g, --global Name of the global object in browser environments, if any. + + --no-comments Does not output any JSDoc comments. + + Internal flags: + + -n, --name Wraps everything in a module of the specified name. + + -m, --main Whether building the main library without any imports. + +usage: pbts [options] file1.js file2.js ... (or) other | pbts [options] - +``` + +Picking up on the example above, the following not just generates static code to a CommonJS module `compiled.js` but also its respective TypeScript definitions to `compiled.d.ts`: + +``` +$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto +$> pbts -o compiled.d.ts compiled.js +``` + +Additionally, TypeScript definitions of static modules are compatible with their reflection-based counterparts (i.e. as exported by JSON modules), as long as the following conditions are met: + +1. Instead of using `new SomeMessage(...)`, always use `SomeMessage.create(...)` because reflection objects do not provide a constructor. +2. Types, services and enums must start with an uppercase letter to become available as properties of the reflected types as well (i.e. to be able to use `MyMessage.MyEnum` instead of `root.lookup("MyMessage.MyEnum")`). + +For example, the following generates a JSON module `bundle.js` and a `bundle.d.ts`, but no static code: + +``` +$> pbjs -t json-module -w commonjs -o bundle.js file1.proto file2.proto +$> pbjs -t static-module file1.proto file2.proto | pbts -o bundle.d.ts - +``` + +### Reflection vs. static code + +While using .proto files directly requires the full library respectively pure reflection/JSON the light library, pretty much all code but the relatively short descriptors is shared. + +Static code, on the other hand, requires just the minimal library, but generates additional, albeit editable, source code without any reflection features. + +There is no significant difference performance-wise as the code generated statically is pretty much the same as generated at runtime and both are largely interchangeable as seen in the previous section. + +### Command line API + +Both utilities can be used programmatically by providing command line arguments and a callback to their respective `main` functions: + +```js +var pbjs = require("protobufjs/cli/pbjs"); // or require("protobufjs/cli").pbjs / .pbts + +pbjs.main([ "--target", "json-module", "path/to/myproto.proto" ], function(err, output) { + if (err) + throw err; + // do something with output +}); +``` + +Additional documentation +------------------------ #### Protocol Buffers * [Google's Developer Guide](https://developers.google.com/protocol-buffers/docs/overview) #### protobuf.js * [API Documentation](http://dcode.io/protobuf.js) -* [CLI Documentation](./cli/README.md) * [CHANGELOG](https://github.com/dcodeIO/protobuf.js/blob/master/CHANGELOG.md) * [Frequently asked questions](https://github.com/dcodeIO/protobuf.js/wiki) on our wiki #### Community * [Questions and answers](http://stackoverflow.com/search?tab=newest&q=protobuf.js) on StackOverflow -Command line ------------- -Command line usage has moved to the (soon to be decoupled) [CLI package](./cli/README.md) - Performance ----------- The package includes a benchmark that tries to compare performance to native JSON as far as this is possible. On an i7-2600K running node 6.9.1 it yields: diff --git a/cli/README.md b/cli/README.md index e3b252232..1eb4c868a 100644 --- a/cli/README.md +++ b/cli/README.md @@ -4,189 +4,8 @@ protobufjs-cli Command line interface (CLI) for [protobuf.js](https://github.com/dcodeIO/protobuf.js). Translates between file formats and generates static code as well as TypeScript definitions. -**Note** that moving the CLI to its own package is a work in progress. At the moment, it's still part of the main package. - -Contents --------- - - - -* [Usage](#usage)
- An introduction to the toolset. - -* [API](#api)
- Details on using pbjs and pbts programmatically. - - - -Usage ------ - -### pbjs - -``` -Translates between file formats and generates static code. - - -t, --target Specifies the target format. Also accepts a path to require a custom target. - - json JSON representation - json-module JSON representation as a module - proto2 Protocol Buffers, Version 2 - proto3 Protocol Buffers, Version 3 - static Static code without reflection (non-functional on its own) - static-module Static code without reflection as a module - - -p, --path Adds a directory to the include path. - - -o, --out Saves to a file instead of writing to stdout. - - --sparse Exports only those types referenced from a main file (experimental). - - Module targets only: - - -w, --wrap Specifies the wrapper to use. Also accepts a path to require a custom wrapper. - - default Default wrapper supporting both CommonJS and AMD - commonjs CommonJS wrapper - amd AMD wrapper - es6 ES6 wrapper (implies --es6) - - -r, --root Specifies an alternative protobuf.roots name. - - -l, --lint Linter configuration. Defaults to protobuf.js-compatible rules: - - eslint-disable block-scoped-var, no-redeclare, no-control-regex, no-prototype-builtins - - --es6 Enables ES6 syntax (const/let instead of var) - - Proto sources only: - - --keep-case Keeps field casing instead of converting to camel case. - - Static targets only: - - --no-create Does not generate create functions used for reflection compatibility. - --no-encode Does not generate encode functions. - --no-decode Does not generate decode functions. - --no-verify Does not generate verify functions. - --no-convert Does not generate convert functions like from/toObject - --no-delimited Does not generate delimited encode/decode functions. - --no-beautify Does not beautify generated code. - --no-comments Does not output any JSDoc comments. - - --force-long Enfores the use of 'Long' for s-/u-/int64 and s-/fixed64 fields. - --force-message Enfores the use of runtime messages instead of plain objects. - -usage: pbjs [options] file1.proto file2.json ... (or) other | pbjs [options] - -``` - -For production environments it is recommended to bundle all your .proto files to a single .json file, which minimizes the number of network requests and avoids any parser overhead (hint: works with just the **light** library): +* [CLI Documentation](https://github.com/dcodeIO/protobuf.js#command-line) -``` -$> pbjs -t json file1.proto file2.proto > bundle.json -``` - -Now, either include this file in your final bundle: - -```js -var root = protobuf.Root.fromJSON(require("./bundle.json")); -``` - -or load it the usual way: - -```js -protobuf.load("bundle.json", function(err, root) { - ... -}); -``` - -Generated static code, on the other hand, works with just the **minimal** library. For example - -``` -$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto -``` - -will generate static code for definitions within `file1.proto` and `file2.proto` to a CommonJS module `compiled.js`. - -**ProTip!** Documenting your .proto files with `/** ... */`-blocks or (trailing) `/// ...` lines translates to generated static code. - - -### pbts - -``` -Generates TypeScript definitions from annotated JavaScript files. - - -o, --out Saves to a file instead of writing to stdout. - - -g, --global Name of the global object in browser environments, if any. - - --no-comments Does not output any JSDoc comments. - - Internal flags: - - -n, --name Wraps everything in a module of the specified name. - - -m, --main Whether building the main library without any imports. - -usage: pbts [options] file1.js file2.js ... (or) other | pbts [options] - -``` - -Picking up on the example above, the following not just generates static code to a CommonJS module `compiled.js` but also its respective TypeScript definitions to `compiled.d.ts`: - -``` -$> pbjs -t static-module -w commonjs -o compiled.js file1.proto file2.proto -$> pbts -o compiled.d.ts compiled.js -``` - -Additionally, TypeScript definitions of static modules are compatible with their reflection-based counterparts (i.e. as exported by JSON modules), as long as the following conditions are met: - -1. Instead of using `new SomeMessage(...)`, always use `SomeMessage.create(...)` because reflection objects do not provide a constructor. -2. Types, services and enums must start with an uppercase letter to become available as properties of the reflected types as well (i.e. to be able to use `MyMessage.MyEnum` instead of `root.lookup("MyMessage.MyEnum")`). - -For example, the following generates a JSON module `bundle.js` and a `bundle.d.ts`, but no static code: - -``` -$> pbjs -t json-module -w commonjs -o bundle.js file1.proto file2.proto -$> pbjs -t static-module file1.proto file2.proto | pbts -o bundle.d.ts - -``` - -### Reflection vs. static code - -While using .proto files directly requires the full library respectively pure reflection/JSON the light library, pretty much all code but the relatively short descriptors is shared. - -Static code, on the other hand, requires just the minimal library, but generates additional, albeit editable, source code without any reflection features. - -There is no significant difference performance-wise as the code generated statically is pretty much the same as generated at runtime and both are largely interchangeable as seen in the previous section. - -API ---- - -Both utilities can be used programmatically by providing command line arguments and a callback to their respective `main` functions: - -```js -var pbjs = require("protobufjs-cli/pbjs"); // or require("protobufjs-cli").pbjs / .pbts - -pbjs.main([ "--target", "json-module", "path/to/myproto.proto" ], function(err, output) { - if (err) - throw err; - // do something with output -}); -``` +**Note** that moving the CLI to its own package is a work in progress. At the moment, it's still part of the main package. **License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)