Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(typescript): add ts_project rule #1710

Merged
merged 6 commits into from
Mar 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ example_integration_test(
name = "examples_react_webpack",
# TODO: add some tests in the example
bazel_commands = ["build ..."],
npm_packages = {
"//packages/typescript:npm_package": "@bazel/typescript",
},
# TODO(alexeagle): somehow this is broken by the new node-patches based node_patches script
# ERROR: D:/temp/tmp-6900sejcsrcttpdb/BUILD.bazel:37:1: output 'app.bundle.js' was not created
tags = ["no-bazelci-windows"],
Expand Down
20 changes: 3 additions & 17 deletions examples/react_webpack/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
load("@npm//http-server:index.bzl", "http_server")
load("@npm//sass:index.bzl", "sass")
load("@npm//typescript:index.bzl", "tsc")
load("@npm//webpack-cli:index.bzl", webpack = "webpack_cli")
load("@npm_bazel_typescript//:index.bzl", "ts_project")

sass(
name = "styles",
Expand All @@ -13,22 +13,8 @@ sass(
data = ["styles.scss"],
)

tsc(
name = "compile",
outs = ["index.js"],
args = [
"$(execpath index.tsx)",
"$(execpath types.d.ts)",
"--outDir",
"$(RULEDIR)",
"--lib",
"es2015,dom",
"--jsx",
"react",
],
data = [
"index.tsx",
"types.d.ts",
ts_project(
deps = [
"@npm//@types",
"@npm//csstype",
],
Expand Down
4 changes: 4 additions & 0 deletions examples/react_webpack/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ yarn_install(
package_json = "//:package.json",
yarn_lock = "//:yarn.lock",
)

load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")

install_bazel_dependencies()
1 change: 1 addition & 0 deletions examples/react_webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"@bazel/bazelisk": "^1.3.0",
"@bazel/buildifier": "^0.29.0",
"@bazel/ibazel": "^0.12.2",
"@bazel/typescript": "^1.4.1",
"@types/react": "^16.9.5",
"@types/react-dom": "^16.9.1",
"css-loader": "^3.2.0",
Expand Down
6 changes: 6 additions & 0 deletions examples/react_webpack/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"jsx": "react",
"lib": ["ES2015", "DOM"]
}
}
52 changes: 19 additions & 33 deletions packages/typescript/docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,33 @@

The TypeScript rules integrate the TypeScript compiler with Bazel.

Looking for Karma rules `ts_web_test` and `karma_web_test`?
These are now documented in the README at http://npmjs.com/package/@bazel/karma

## Alternatives

This package provides Bazel wrappers around the TypeScript compiler, and are how we compile TS code at Google.

These rules are opinionated, for example:

- 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.
- We control the output format and module syntax so that downstream rules can rely on them.
This package provides Bazel wrappers around the TypeScript compiler.

They are also fast and optimized:
At a high level, there are two alternatives provided: `ts_project` and `ts_library`.
This section describes the trade-offs between these rules.

- We keep a running TypeScript compile running as a daemon, using Bazel workers. This process avoids re-parse and re-JIT of the >1MB `typescript.js` and keeps cached bound ASTs for input files which saves time.
`ts_project` simply runs `tsc --project`, with Bazel knowing which outputs to expect based on the TypeScript compiler options, and with interoperability with other TypeScript rules via a Bazel Provider (DeclarationInfo) that transmits the type information.
It is intended as an easy on-boarding for existing TypeScript code and should be familiar if your background is in frontend ecosystem idioms.
Any behavior of `ts_project` should be reproducible outside of Bazel, with a couple of caveats noted in the rule documentation below.

We understand this is a tradeoff. If you want to use the plain TypeScript compiler provided by the TS team at Microsoft, you can do this by calling its CLI directly. For example,
> We used to recommend using the `tsc` rule directly from the `typescript` project, like
> `load("@npm//typescript:index.bzl", "tsc")`
> However `ts_project` is strictly better and should be used instead.

```python
load("@npm//typescript:index.bzl", "tsc")
`ts_library` is an open-sourced version of the rule we use to compile TS code at Google.
It should be familiar if your background is in Bazel idioms.
It is very complex, involving code generation of the `tsconfig.json` file, a custom compiler binary, and a lot of extra features.
It is also opinionated, and may not work with existing TypeScript code. For example:

srcs = glob(["*.ts"])
deps = ["@npm//@types/node"]
- 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.
- We control the output format and module syntax so that downstream rules can rely on them.

tsc(
name = "compile",
data = srcs + deps,
outs = [s.replace(".ts", ext) for ext in [".js", ".d.ts"] for s in srcs],
args = [
"--outDir",
"$(RULEDIR)",
"--lib",
"es2017,dom",
"--downlevelIteration",
"--declaration",
] + [
"$(location %s)" % s
for s in srcs
],
)
```
On the other hand, `ts_library` is also fast and optimized.
We keep a running TypeScript compile running as a daemon, using Bazel workers.
This process avoids re-parse and re-JIT of the >1MB `typescript.js` and keeps cached bound ASTs for input files which saves time.
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)).

## Installation

Expand Down
2 changes: 2 additions & 0 deletions packages/typescript/src/index.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ Users should not load files under "/internal"

load("//internal:build_defs.bzl", _ts_library = "ts_library_macro")
load("//internal:ts_config.bzl", _ts_config = "ts_config")
load("//internal:ts_project.bzl", _ts_project = "ts_project_macro")
load("//internal:ts_repositories.bzl", _ts_setup_workspace = "ts_setup_workspace")
load("//internal/devserver:ts_devserver.bzl", _ts_devserver = "ts_devserver_macro")

ts_setup_workspace = _ts_setup_workspace
ts_library = _ts_library
ts_config = _ts_config
ts_devserver = _ts_devserver
ts_project = _ts_project
# If adding rules here also add to index.docs.bzl
2 changes: 2 additions & 0 deletions packages/typescript/src/index.docs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ So this is a copy of index.bzl with macro indirection removed.

load("//internal:build_defs.bzl", _ts_library = "ts_library")
load("//internal:ts_config.bzl", _ts_config = "ts_config")
load("//internal:ts_project.bzl", _ts_project = "ts_project_macro")
load("//internal:ts_repositories.bzl", _ts_setup_workspace = "ts_setup_workspace")
load("//internal/devserver:ts_devserver.bzl", _ts_devserver = "ts_devserver")

ts_setup_workspace = _ts_setup_workspace
ts_library = _ts_library
ts_config = _ts_config
ts_project = _ts_project
ts_devserver = _ts_devserver
# DO NOT ADD MORE rules here unless they appear in the generated docsite.
# Run yarn stardoc to re-generate the docsite.
1 change: 1 addition & 0 deletions packages/typescript/src/internal/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ filegroup(
srcs = [
"build_defs.bzl",
"ts_config.bzl",
"ts_project.bzl",
"ts_repositories.bzl",
"//internal/devserver:package_contents",
],
Expand Down
Loading