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: document the escape hatch from ts_library #1247

Merged
merged 1 commit into from
Oct 8, 2019
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
33 changes: 21 additions & 12 deletions examples/app/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
load("@build_bazel_rules_nodejs//internal/web_package:web_package.bzl", "web_package")
load("@npm//http-server:index.bzl", "http_server")
load("@npm//typescript:index.bzl", "tsc")
load("@npm_bazel_protractor//:index.bzl", "protractor_web_test_suite")
load("@npm_bazel_rollup//:index.bzl", "rollup_bundle")
load("@npm_bazel_terser//:index.bzl", "terser_minified")
load("@npm_bazel_typescript//:index.bzl", "ts_config", "ts_devserver", "ts_library")
load("@npm_bazel_typescript//:index.bzl", "ts_devserver", "ts_library")

package(default_visibility = ["//visibility:public"])

Expand Down Expand Up @@ -46,20 +47,28 @@ http_server(
templated_args = ["package"],
)

ts_config(
name = "tsconfig-test",
src = "tsconfig-test.json",
deps = [":tsconfig.json"],
)

ts_library(
# we could use ts_library here, but we use plain typescript to demonstrate that it works
tsc(
name = "e2e",
testonly = 1,
srcs = ["app.e2e-spec.ts"],
tsconfig = ":tsconfig-test",
deps = [
# Remember that Bazel requires it know what outputs are created ahead of time
# so that it can construct a dependency graph.
outs = [
"app.e2e-spec.js",
],
args = [
"-p",
"$(location tsconfig-test.json)",
"--outDir",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment explaining what --outDir $@ expands to and why it is needed may be good for the purposes of this example

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, also added a sentence to the npm_package_bin docs

# $@ is a shorthand for the dist/bin directory where Bazel requires we write outputs
"$@",
],
data = [
"app.e2e-spec.ts",
"tsconfig.json",
"tsconfig-test.json",
"@npm//@types/jasmine",
"@npm//jasmine",
"@npm//@types/node",
"@npm//protractor",
],
)
Expand Down
2 changes: 1 addition & 1 deletion examples/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"rollup": "1.20.3",
"stylus": "^0.54.7",
"terser": "4.3.1",
"typescript": "2.7.x"
"typescript": "3.6.3"
},
"scripts": {
"test": "bazel test ..."
Expand Down
3 changes: 2 additions & 1 deletion examples/app/tsconfig-test.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@

"compilerOptions": {
"types": ["jasmine", "node"]
}
},
"include": ["*-spec.ts"]
}
8 changes: 4 additions & 4 deletions examples/app/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1339,10 +1339,10 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=

typescript@2.7.x:
version "2.7.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836"
integrity sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==
typescript@3.6.3:
version "3.6.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.3.tgz#fea942fabb20f7e1ca7164ff626f1a9f3f70b4da"
integrity sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==

union@~0.4.3:
version "0.4.6"
Expand Down
13 changes: 10 additions & 3 deletions internal/node/npm_package_bin.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ _ATTRS = {
# because the output_dir is a tree artifact
# so we weren't able to give it a label
def _expand_location(ctx, s):
s = s.replace("$@", "/".join([ctx.bin_dir.path, ctx.label.package, ctx.attr.name]))
outdir_segments = [ctx.bin_dir.path, ctx.label.package]
if ctx.attr.output_dir:
# We'll write into a newly created directory named after the rule
outdir_segments.append(ctx.attr.name)

# The list comprehension removes empty segments like if we are in the root package
s = s.replace("$@", "/".join([o for o in outdir_segments if o]))
return ctx.expand_location(s, targets = ctx.attr.data)

def _impl(ctx):
Expand Down Expand Up @@ -53,7 +59,7 @@ _npm_package_bin = rule(
)

def npm_package_bin(tool = None, package = None, package_bin = None, data = [], outs = [], args = [], output_dir = False, **kwargs):
"""Run an arbitrary npm package binary (anything under node_modules/.bin/*) under Bazel.
"""Run an arbitrary npm package binary (e.g. a program under node_modules/.bin/*) under Bazel.

It must produce outputs. If you just want to run a program with `bazel run`, use the nodejs_binary rule.

Expand All @@ -69,13 +75,14 @@ def npm_package_bin(tool = None, package = None, package_bin = None, data = [],
outs: similar to [genrule.outs](https://docs.bazel.build/versions/master/be/general.html#genrule.outs)
output_dir: set to True if you want the output to be a directory
Exactly one of `outs`, `output_dir` may be used.
If you output a directory, there can only be one output, which will be named the same as the target.
If you output a directory, there can only be one output, which will be a directory named the same as the target.

args: Command-line arguments to the tool.

Subject to 'Make variable' substitution.
Can use $(location) expansion. See https://docs.bazel.build/versions/master/be/make-variables.html
You may also refer to the location of the output_dir with the special `$@` replacement, like genrule.
If output_dir=False then $@ will refer to the output directory for this package.

package: an npm package whose binary to run, like "terser". Assumes your node_modules are installed in a workspace called "npm"
package_bin: the "bin" entry from `package` that should be run. By default package_bin is the same string as `package`
Expand Down
70 changes: 70 additions & 0 deletions packages/typescript/docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,45 @@ 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.

They are 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 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,

```python
load("@npm//typescript:index.bzl", "tsc")

srcs = glob(["*.ts"])
deps = ["@npm//@types/node"]

tsc(
name = "compile",
data = srcs + deps,
outs = [s.replace(".ts", ext) for ext in [".js", ".d.ts"] for s in srcs],
args = [
"--outDir",
"$@",
"--lib",
"es2017,dom",
"--downlevelIteration",
"--declaration",
] + [
"$(location %s)" % s
for s in srcs
],
)
```

## Installation

Add a devDependency on `@bazel/typescript`
Expand Down Expand Up @@ -208,6 +247,37 @@ directory. See the notes about the `tsconfig` attribute in the [ts_library API d

[ts_library API docs]: http://tsetse.info/api/build_defs.html#ts_library

## Accessing JavaScript outputs

The default output of the `ts_library` rule is the `.d.ts` files.
This is for a couple reasons:

- help ensure that downstream rules which access default outputs will not require
a cascading re-build when only the implementation changes but not the types
- make you think about whether you want the devmode (named UMD) or prodmode outputs

You can access the JS output by adding a `filegroup` rule after the `ts_library`,
for example

```python
ts_library(
name = "compile",
srcs = ["thing.ts"],
)

filegroup(
name = "thing.js",
srcs = ["compile"],
# Change to es6_sources to get the 'prodmode' JS
output_group = "es5_sources",
)

my_rule(
name = "uses_js",
deps = ["thing.js"],
)
```

## Serving TypeScript for development

There are two choices for development mode:
Expand Down