Skip to content

Commit

Permalink
feat: support custom dts transpiler (#697)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbedard authored Sep 27, 2024
1 parent 4a4bf96 commit dd832db
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 32 deletions.
21 changes: 12 additions & 9 deletions docs/rules.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions docs/transpiler.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,17 @@ then `load()` from your own macro rather than from `@aspect_rules_ts`.
## Macro expansion
When `transpiler` is used, then the `ts_project` macro expands to these targets:
When `no_emit`, `transpiler` or `declaration_transpiler` is set, then the `ts_project` macro expands to these targets:
- `[name]` - the default target which can be included in the `deps` of downstream rules.
Note that it will successfully build *even if there are typecheck failures* because invoking `tsc` is not needed to produce the default outputs.
This is considered a feature, as it allows you to have a faster development mode where type-checking is not on the critical path.
- `[name]_typecheck` - provides typings (`.d.ts` files) as the default output.
- `[name]_types` - provides typings (`.d.ts` files) as the default outputs.
This target is not created if `no_emit` is set.
- `[name]_typecheck` - provides default outputs asserting type-checking has been run.
Building this target always causes the typechecker to run.
- `[name]_typecheck_test` - a [`build_test`] target which simply depends on the `[name]_typecheck` target.
This ensures that typechecking will be run under `bazel test` with [`--build_tests_only`].
- `[name]_typings` - internal target which runs the binary from the `tsc` attribute
- Any additional target(s) the custom transpiler rule/macro produces.
(For example, some rules produce one target per TypeScript input file.)
Expand Down
155 changes: 155 additions & 0 deletions examples/transpiler/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
load("@bazel_skylib//lib:partial.bzl", "partial")
load("@bazel_skylib//rules:build_test.bzl", "build_test")

# Note, Bazel 6 starlark has lambda so maybe we can stop using partial
load("@bazel_skylib//rules:write_file.bzl", "write_file")
load(":babel.bzl", "babel")
load(":tsc.bzl", "tsc_dts", "tsc_js")

###
# See a more full-featured example showing swc and babel at
Expand Down Expand Up @@ -90,3 +92,156 @@ build_test(
"a.js", # NOTE: does not implement out_dir in this test
],
)

# custom js & dts transpilers, tsc still run for typechecking
ts_project(
name = "custom_transpilers",
srcs = ["a.ts"],
declaration = True,
declaration_transpiler = partial.make(
tsc_dts,
out_dir = "build-custom_transpilers",
),
out_dir = "build-custom_transpilers",
source_map = True,
transpiler = partial.make(
tsc_js,
out_dir = "build-custom_transpilers",
),
)

build_test(
name = "custom_transpilers_test",
targets = [
":custom_transpilers",
":custom_transpilers_types",
":custom_transpilers_typecheck",
"build-custom_transpilers/a.js",
"build-custom_transpilers/a.d.ts",
],
)

# custom js & dts transpilers, noEmit prevents any outputs, typechecking still exists
ts_project(
name = "custom_transpilers-no_emit",
srcs = ["a.ts"],
declaration_transpiler = tsc_dts,
transpiler = tsc_js,
tsconfig = {
"compilerOptions": {
"noEmit": True,
"declaration": True,
"emitDeclarationOnly": True,
},
},
)

build_test(
name = "custom_transpilers-no_emit-test",
targets = [
":custom_transpilers-no_emit",
":custom_transpilers-no_emit_typecheck",
],
)

# custom dts transpiler, noEmit prevents any outputs, typechecking still exists
ts_project(
name = "custom_dts_transpiler-no_emit",
srcs = ["a.ts"],
declaration_transpiler = tsc_dts,
tsconfig = {
"compilerOptions": {
"noEmit": True,
"declaration": True,
"emitDeclarationOnly": True,
},
},
)

build_test(
name = "custom_dts_transpiler-no_emit-test",
targets = [
":custom_dts_transpiler-no_emit",
":custom_dts_transpiler-no_emit_typecheck",
],
)

# custom dts transpiler but still invokes tsc for type-checking
ts_project(
name = "custom_dts_transpiler",
srcs = ["a.ts"],
declaration = True,
declaration_transpiler = partial.make(
tsc_dts,
out_dir = "build-custom_dts_transpiler",
),
out_dir = "build-custom_dts_transpiler",
source_map = True,
transpiler = "tsc",
)

build_test(
name = "custom_dts_transpiler-test",
targets = [
":custom_dts_transpiler",
":custom_dts_transpiler_types",
":custom_dts_transpiler_typecheck",
"build-custom_dts_transpiler/a.js",
"build-custom_dts_transpiler/a.d.ts",
],
)

# a custom dts transpiler but not actually outputting types
# should stylle have a _typecheck target
ts_project(
name = "custom_dts_transpiler-no_declarations",
srcs = ["a.ts"],
declaration_transpiler = partial.make(
tsc_dts,
out_dir = "build-custom_dts_transpiler-no_declarations",
),
out_dir = "build-custom_dts_transpiler-no_declarations",
source_map = True,
transpiler = "tsc",
tsconfig = {
"compilerOptions": {
"declaration": False,
},
},
)

build_test(
name = "custom_dts_transpiler-no_declarations-test",
targets = [
":custom_dts_transpiler-no_declarations",
":custom_dts_transpiler-no_declarations_typecheck",
"build-custom_dts_transpiler-no_declarations/a.js",
],
)

# custom dts transpiler and only outputting declarations
ts_project(
name = "custom_dts_transpiler-declarations_only",
srcs = ["a.ts"],
declaration_transpiler = partial.make(
tsc_dts,
out_dir = "build-custom_dts_transpiler-no_declarations",
),
out_dir = "build-custom_dts_transpiler-no_declarations",
transpiler = "tsc",
tsconfig = {
"compilerOptions": {
"declaration": True,
"emitDeclarationOnly": True,
},
},
)

build_test(
name = "custom_dts_transpiler-declarations_only-test",
targets = [
":custom_dts_transpiler-declarations_only",
":custom_dts_transpiler-declarations_only_typecheck",
"build-custom_dts_transpiler-no_declarations/a.d.ts",
],
)
32 changes: 32 additions & 0 deletions examples/transpiler/tsc.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"Adapter from the TypeScript CLI to the ts_project#transpiler/declaration_transpiler interface"

load("@npm//examples:typescript/package_json.bzl", typescript_bin = "bin")

# tsc configured with --outDir and --emitDeclarationOnly
def tsc_dts(name, srcs, out_dir, **kwargs):
typescript_bin.tsc(
name = name,
srcs = srcs + ["tsconfig.json"],
outs = ["%s/%s" % (out_dir, src.replace(".ts", ".d.ts")) for src in srcs],
args = [
"-p %s/tsconfig.json" % native.package_name(),
"--emitDeclarationOnly",
"--outDir %s/%s" % (native.package_name(), out_dir),
],
**kwargs
)

# tsc configured with --outDir and --declaration false
def tsc_js(name, srcs, out_dir, **kwargs):
typescript_bin.tsc(
name = name,
srcs = srcs + ["tsconfig.json"],
outs = ["%s/%s" % (out_dir, src.replace(".ts", ".js")) for src in srcs],
args = [
"-p %s/tsconfig.json" % native.package_name(),
"--declaration",
"false",
"--outDir %s/%s" % (native.package_name(), out_dir),
],
**kwargs
)
Loading

0 comments on commit dd832db

Please sign in to comment.