|
| 1 | +# TypeScript rules for Bazel |
| 2 | + |
| 3 | +The TypeScript rules integrate the TypeScript compiler with Bazel. |
| 4 | + |
| 5 | +## Alternatives |
| 6 | + |
| 7 | +This package provides Bazel wrappers around the TypeScript compiler. |
| 8 | + |
| 9 | +At a high level, there are two alternatives provided: `ts_project` and `ts_library`. |
| 10 | +This section describes the trade-offs between these rules. |
| 11 | + |
| 12 | +`ts_project` is recommended for all new uses, and we hope to migrate all users to it in the future. |
| 13 | +It simply runs `tsc --project`. |
| 14 | + |
| 15 | +The rule ensures that Bazel knows which outputs to expect based on the TypeScript compiler options, and provides interoperability with other TypeScript rules via a Bazel Provider ([DeclarationInfo](Built-ins#declarationinfo)) that transmits the type information. |
| 16 | + |
| 17 | +Advantages of `ts_project` include: |
| 18 | +- it's an easy on-boarding for existing TypeScript code and for developers already familiar with using the TypeScript compiler. |
| 19 | +- any behavior of `ts_project` should be reproducible outside of Bazel, with a couple of caveats noted in the rule documentation below. |
| 20 | +- It's a compact implementation that we can afford to maintain. |
| 21 | + |
| 22 | +> We used to recommend using the `tsc` rule directly from the `typescript` project, like |
| 23 | +> `load("@npm//typescript:index.bzl", "tsc")` |
| 24 | +> However `ts_project` is strictly better and should be used instead. |
| 25 | +
|
| 26 | +**`ts_library` will be deprecated as soon as `ts_project` has performance parity. Thus we do not recommend any new usages** |
| 27 | + |
| 28 | +`ts_library` is an open-sourced version of the rule we use to compile TS code at Google, however it is very complex, involving code generation of the `tsconfig.json` file, a custom compiler binary, and a lot of extra features. |
| 29 | + |
| 30 | +It is also opinionated, and may not work with existing TypeScript code. For example: |
| 31 | + |
| 32 | +- Your TS code must compile under the `--declaration` flag so that downstream libraries depend only on types, not implementation. This makes Bazel faster by avoiding cascading rebuilds in cases where the types aren't changed. |
| 33 | +- You cannot use `--noEmit` compiler option to use TypeScript as a linter. We always expect to produce .js outputs. |
| 34 | +- We control the output format and module syntax so that downstream rules can rely on them. |
| 35 | + |
| 36 | +On the other hand, `ts_library` is also fast and optimized. |
| 37 | +We keep a running TypeScript compile running as a daemon, using Bazel workers. |
| 38 | +This process avoids re-parse and re-JIT of the >1MB `typescript.js` and keeps cached bound ASTs for input files which saves time. |
| 39 | +We also produce JS code which can be loaded faster (using named AMD module format) and which can be consumed by the Closure Compiler (via integration with [tsickle](https://github.com/angular/tsickle)). |
| 40 | + |
| 41 | +## Installation |
| 42 | + |
| 43 | +Add a `devDependency` on `@bazel/typescript` |
| 44 | + |
| 45 | +```sh |
| 46 | +$ yarn add -D @bazel/typescript |
| 47 | +# or |
| 48 | +$ npm install --save-dev @bazel/typescript |
| 49 | +``` |
| 50 | + |
| 51 | +Watch for any `peerDependency` warnings - we assume you have already installed the `typescript` package from npm. |
| 52 | + |
| 53 | +### Notes |
| 54 | + |
| 55 | +If you'd like a "watch mode", try [ibazel]. |
| 56 | + |
| 57 | +At some point, we plan to release a tool similar to [gazelle] to generate the |
| 58 | +BUILD files from your source code. |
| 59 | + |
| 60 | +[gazelle]: https://github.com/bazelbuild/bazel-gazelle |
| 61 | +[ibazel]: https://github.com/bazelbuild/bazel-watcher |
0 commit comments