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

Ts config ts project #2139

Merged
merged 1 commit into from
Aug 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
17 changes: 13 additions & 4 deletions packages/typescript/internal/ts_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,32 @@

"tsconfig.json files using extends"

TsConfigInfo = provider()
TsConfigInfo = provider(
doc = """Provides TypeScript configuration, in the form of a tsconfig.json file
along with any transitively referenced tsconfig.json files chained by the
"extends" feature""",
fields = {
"deps": "all tsconfig.json files needed to configure TypeScript",
},
)

def _ts_config_impl(ctx):
files = depset([ctx.file.src])
transitive_deps = []
for dep in ctx.attr.deps:
if TsConfigInfo in dep:
transitive_deps.extend(dep[TsConfigInfo].deps)
return [DefaultInfo(files = files), TsConfigInfo(deps = ctx.files.deps + transitive_deps)]
return [
DefaultInfo(files = files),
TsConfigInfo(deps = [ctx.file.src] + ctx.files.deps + transitive_deps),
]

ts_config = rule(
implementation = _ts_config_impl,
attrs = {
"deps": attr.label_list(
doc = """Additional tsconfig.json files referenced via extends""",
allow_files = True,
mandatory = True,
),
"src": attr.label(
doc = """The tsconfig.json file passed to the TypeScript compiler""",
Expand All @@ -41,7 +50,7 @@ ts_config = rule(
doc = """Allows a tsconfig.json file to extend another file.

Normally, you just give a single `tsconfig.json` file as the tsconfig attribute
of a `ts_library` rule. However, if your `tsconfig.json` uses the `extends`
of a `ts_library` or `ts_project` rule. However, if your `tsconfig.json` uses the `extends`
feature from TypeScript, then the Bazel implementation needs to know about that
extended configuration file as well, to pass them both to the TypeScript compiler.
""",
Expand Down
42 changes: 23 additions & 19 deletions packages/typescript/internal/ts_project.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

load("@build_bazel_rules_nodejs//:providers.bzl", "DeclarationInfo", "NpmPackageInfo", "declaration_info", "js_module_info", "run_node")
load("@build_bazel_rules_nodejs//internal/linker:link_node_modules.bzl", "module_mappings_aspect")
load(":ts_config.bzl", "TsConfigInfo")

_DEFAULT_TSC = (
# BEGIN-INTERNAL
Expand Down Expand Up @@ -37,14 +38,6 @@ _OUTPUTS = {
"typings_outs": attr.output_list(),
}

_TsConfigInfo = provider(
doc = """Passes tsconfig.json files to downstream compilations so that TypeScript can read them.
This is needed to support Project References""",
fields = {
"tsconfigs": "depset of tsconfig.json files",
},
)

def _join(*elements):
return "/".join([f for f in elements if f])

Expand Down Expand Up @@ -87,16 +80,20 @@ def _ts_project_impl(ctx):

deps_depsets = []
for dep in ctx.attr.deps:
if _TsConfigInfo in dep:
deps_depsets.append(dep[_TsConfigInfo].tsconfigs)
if TsConfigInfo in dep:
deps_depsets.append(dep[TsConfigInfo].deps)
if NpmPackageInfo in dep:
# TODO: we could maybe filter these to be tsconfig.json or *.d.ts only
# we don't expect tsc wants to read any other files from npm packages.
deps_depsets.append(dep[NpmPackageInfo].sources)
if DeclarationInfo in dep:
deps_depsets.append(dep[DeclarationInfo].transitive_declarations)

inputs = ctx.files.srcs + depset(transitive = deps_depsets).to_list() + [ctx.file.tsconfig]
inputs = ctx.files.srcs + depset(transitive = deps_depsets).to_list()
if TsConfigInfo in ctx.attr.tsconfig:
inputs.extend(ctx.attr.tsconfig[TsConfigInfo].deps)
else:
inputs.append(ctx.file.tsconfig)
if ctx.attr.extends:
inputs.extend(ctx.files.extends)

Expand Down Expand Up @@ -155,10 +152,10 @@ def _ts_project_impl(ctx):
sources = depset(runtime_outputs),
deps = ctx.attr.deps,
),
_TsConfigInfo(tsconfigs = depset([ctx.file.tsconfig] + ctx.files.extends, transitive = [
dep[_TsConfigInfo].tsconfigs
TsConfigInfo(deps = depset([ctx.file.tsconfig] + ctx.files.extends, transitive = [
dep[TsConfigInfo].deps
for dep in ctx.attr.deps
if _TsConfigInfo in dep
if TsConfigInfo in dep
])),
]

Expand Down Expand Up @@ -191,9 +188,15 @@ def _validate_options_impl(ctx):
ts_build_info_file = ctx.attr.ts_build_info_file,
).to_json()])

inputs = ctx.files.extends[:]
if TsConfigInfo in ctx.attr.tsconfig:
inputs.extend(ctx.attr.tsconfig[TsConfigInfo].deps)
else:
inputs.append(ctx.file.tsconfig)

run_node(
ctx,
inputs = [ctx.file.tsconfig] + ctx.files.extends,
inputs = inputs,
outputs = [marker],
arguments = [arguments],
executable = "validator",
Expand Down Expand Up @@ -356,13 +359,14 @@ def ts_project_macro(

deps: List of labels of other rules that produce TypeScript typings (.d.ts files)

tsconfig: Label of the tsconfig.json file to use for the compilation.
tsconfig: Label of the tsconfig.json file to use for the compilation, or a target that provides TsConfigInfo.

By default, we add `.json` to the `name` attribute.
By default, we assume the tsconfig file is named by adding `.json` to the `name` attribute.

extends: List of labels of tsconfig file(s) referenced in `extends` section of tsconfig.

Must include any tsconfig files "chained" by extends clauses.
Any tsconfig files "chained" by extends clauses must either be transitive deps of the TsConfigInfo
provided to the `tsconfig` attribute, or must be explicitly listed here.

args: List of strings of additional command-line arguments to pass to tsc.

Expand Down Expand Up @@ -432,7 +436,7 @@ def ts_project_macro(
extra_deps.append("_validate_%s_options" % name)

typings_out_dir = declaration_dir if declaration_dir else out_dir
tsbuildinfo_path = ts_build_info_file if ts_build_info_file else tsconfig[:-5] + ".tsbuildinfo"
tsbuildinfo_path = ts_build_info_file if ts_build_info_file else name + ".tsbuildinfo"
gregmagolan marked this conversation as resolved.
Show resolved Hide resolved

ts_project(
name = name,
Expand Down
8 changes: 8 additions & 0 deletions packages/typescript/test/ts_project/BUILD
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
load("//packages/typescript:index.bzl", "ts_config")

exports_files(["tsconfig-base.json"])

ts_config(
name = "tsconfig",
src = "tsconfig-base.json",
visibility = ["//packages/typescript/test/ts_project:__subpackages__"],
)
21 changes: 21 additions & 0 deletions packages/typescript/test/ts_project/ts_config/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Test a tree of tsconfig.json files
"""

load("//packages/typescript:index.bzl", "ts_config", "ts_project")

ts_config(
name = "tsconfig",
src = "tsconfig.json",
deps = [
"tsconfig-extended.json",
"//packages/typescript/test/ts_project:tsconfig",
],
)

ts_project(
name = "compile_ts",
composite = True,
declaration = True,
tsconfig = "tsconfig",
)
1 change: 1 addition & 0 deletions packages/typescript/test/ts_project/ts_config/a.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const a: string = 'hello world';
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../tsconfig-base",
"compilerOptions": {
"declaration": true
},
}
6 changes: 6 additions & 0 deletions packages/typescript/test/ts_project/ts_config/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "./tsconfig-extended.json",
"compilerOptions": {
"types": []
}
}