From 09ec2335fdd0181c93d2decee710c090dd8c1abb Mon Sep 17 00:00:00 2001 From: Alex Eagle Date: Fri, 28 Aug 2020 14:13:01 -0700 Subject: [PATCH] feat(typescript): generate tsconfig.json for ts_project (#2130) This is an experimental, opt-in feature where ts_project will generate a tsconfig.json file in place of the user specifying one in the source directory. I expect a long tail of compatibility bugs since any path appearing in this generated file needs to point from bazel-out back to the source directory. Fixes #2058 --- packages/typescript/checked_in_ts_project.bzl | 37 ++--- packages/typescript/internal/ts_config.bzl | 76 +++++++++ packages/typescript/internal/ts_project.bzl | 152 ++++++++++++++---- .../generated_tsconfig/config/BUILD.bazel | 43 +++++ .../config/expected.d.ts.map_ | 1 + .../generated_tsconfig/config/expected.d.ts_ | 2 + .../config/expected.js.map_ | 1 + .../generated_tsconfig/config/expected.js_ | 2 + .../generated_tsconfig/config/src/a.ts | 1 + .../config_attrs/BUILD.bazel | 43 +++++ .../config_attrs/expected.d.ts.map_ | 1 + .../config_attrs/expected.d.ts_ | 2 + .../config_attrs/expected.js.map_ | 1 + .../config_attrs/expected.js_ | 2 + .../generated_tsconfig/config_attrs/src/a.ts | 1 + .../generated_tsconfig/decl_only/BUILD.bazel | 20 +++ .../generated_tsconfig/decl_only/a.ts | 1 + .../decl_only/expected.d.ts_ | 1 + .../generated_tsconfig/default/BUILD.bazel | 16 ++ .../generated_tsconfig/default/a.ts | 1 + .../generated_tsconfig/default/expected.js_ | 3 + .../generated_tsconfig/extends/BUILD.bazel | 50 ++++++ .../generated_tsconfig/extends/a.ts | 1 + .../generated_tsconfig/extends/expected.js_ | 3 + .../extends/tsconfig-extended.json | 6 + .../generated_tsconfig/gen_src/BUILD.bazel | 25 +++ .../generated_tsconfig/gen_src/expected.js_ | 3 + 27 files changed, 441 insertions(+), 54 deletions(-) create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config/BUILD.bazel create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config/expected.d.ts.map_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config/expected.d.ts_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config/expected.js.map_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config/expected.js_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config/src/a.ts create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config_attrs/BUILD.bazel create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.d.ts.map_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.d.ts_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.js.map_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.js_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/config_attrs/src/a.ts create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/decl_only/BUILD.bazel create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/decl_only/a.ts create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/decl_only/expected.d.ts_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/default/BUILD.bazel create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/default/a.ts create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/default/expected.js_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/extends/BUILD.bazel create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/extends/a.ts create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/extends/expected.js_ create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/extends/tsconfig-extended.json create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/gen_src/BUILD.bazel create mode 100644 packages/typescript/test/ts_project/generated_tsconfig/gen_src/expected.js_ diff --git a/packages/typescript/checked_in_ts_project.bzl b/packages/typescript/checked_in_ts_project.bzl index b904ce3319..b8d2a6ac44 100644 --- a/packages/typescript/checked_in_ts_project.bzl +++ b/packages/typescript/checked_in_ts_project.bzl @@ -1,7 +1,6 @@ "checked_in_ts_project rule" load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test") -load("@build_bazel_rules_nodejs//third_party/github.com/bazelbuild/bazel-skylib:rules/write_file.bzl", "write_file") load("//packages/typescript:index.bzl", "ts_project") def checked_in_ts_project(name, src, checked_in_js = None, **kwargs): @@ -15,34 +14,20 @@ def checked_in_ts_project(name, src, checked_in_js = None, **kwargs): if not checked_in_js: checked_in_js = src[:-3] + ".js" - tsconfig = "tsconfig_%s.json" % name - - # workspace is up three dirs (bazel-out/arch/bin) plus number of segments in the package - workspace_root = "/".join([".."] * (3 + len(native.package_name().split("/")))) - - # Generate a tsconfig, this is partly an example of how it can be done, per jbedard and toxicable request - write_file( - name = "_gen_tsconfig_%s" % name, - content = [struct( - compilerOptions = struct( - lib = ["es2017", "dom"], - strict = True, - target = "es2015", - module = "commonjs", - removeComments = True, - declaration = True, - skipLibCheck = True, - ), - files = ["/".join([workspace_root, native.package_name(), src])], - ).to_json()], - out = tsconfig, - ) - ts_project( name = name, srcs = [src], - declaration = True, - tsconfig = tsconfig, + tsconfig = { + "compilerOptions": { + "declaration": True, + "lib": ["es2017", "dom"], + "module": "commonjs", + "removeComments": True, + "skipLibCheck": True, + "strict": True, + "target": "es2015", + }, + }, **kwargs ) diff --git a/packages/typescript/internal/ts_config.bzl b/packages/typescript/internal/ts_config.bzl index a54d5c9d99..8c20ccdaed 100644 --- a/packages/typescript/internal/ts_config.bzl +++ b/packages/typescript/internal/ts_config.bzl @@ -55,3 +55,79 @@ 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. """, ) + +def _join(*elements): + return "/".join([f for f in elements if f]) + +def _relative_path(tsconfig, dest): + relative_to = tsconfig.dirname + if dest.is_source: + # Calculate a relative path from the directory where we're writing the tsconfig + # back to the sources root + workspace_root = "/".join([".."] * len(relative_to.split("/"))) + return _join(workspace_root, dest.path) + + # Bazel guarantees that srcs are beneath the package directory, and we disallow + # tsconfig.json being generated with a "/" in the name. + # So we can calculate a relative path from e.g. + # bazel-out/darwin-fastbuild/bin/packages/typescript/test/ts_project/generated_tsconfig/gen_src + # to + return dest.path[len(relative_to) + 1:] + +def _write_tsconfig_rule(ctx): + # TODO: is it useful to expand Make variables in the content? + content = "\n".join(ctx.attr.content) + if ctx.attr.extends: + content = content.replace( + "__extends__", + _relative_path(ctx.outputs.out, ctx.file.extends), + ) + if ctx.attr.files: + content = content.replace( + "\"__files__\"", + str([_relative_path(ctx.outputs.out, f) for f in ctx.files.files]), + ) + ctx.actions.write( + output = ctx.outputs.out, + content = content, + ) + return [DefaultInfo(files = depset([ctx.outputs.out]))] + +write_tsconfig_rule = rule( + implementation = _write_tsconfig_rule, + attrs = { + "content": attr.string_list(), + "extends": attr.label(allow_single_file = True), + "files": attr.label_list(allow_files = True), + "out": attr.output(), + }, +) + +# Syntax sugar around skylib's write_file +def write_tsconfig(name, config, files, out, extends = None): + """Wrapper around bazel_skylib's write_file which understands tsconfig paths + + Args: + name: name of the resulting write_file rule + config: tsconfig dictionary + files: list of input .ts files to put in the files[] array + out: the file to write + extends: a label for a tsconfig.json file to extend from, if any + """ + if out.find("/") >= 0: + fail("tsconfig should be generated in the package directory, to make relative pathing simple") + + if extends: + config["extends"] = "__extends__" + + amended_config = struct( + files = "__files__", + **config + ) + write_tsconfig_rule( + name = name, + files = files, + extends = extends, + content = [amended_config.to_json()], + out = out, + ) diff --git a/packages/typescript/internal/ts_project.bzl b/packages/typescript/internal/ts_project.bzl index 7530f7bff5..7768d13417 100644 --- a/packages/typescript/internal/ts_project.bzl +++ b/packages/typescript/internal/ts_project.bzl @@ -2,7 +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") +load(":ts_config.bzl", "TsConfigInfo", "write_tsconfig") _DEFAULT_TSC = ( # BEGIN-INTERNAL @@ -39,11 +39,22 @@ _OUTPUTS = { } def _join(*elements): - return "/".join([f for f in elements if f]) + segments = [f for f in elements if f] + if len(segments): + return "/".join(segments) + return "." def _ts_project_impl(ctx): arguments = ctx.actions.args() + generated_srcs = False + for src in ctx.files.srcs: + if src.is_source: + if generated_srcs: + fail("srcs cannot be a mix of generated files and source files") + else: + generated_srcs = True + # Add user specified arguments *before* rule supplied arguments arguments.add_all(ctx.attr.args) @@ -53,7 +64,11 @@ def _ts_project_impl(ctx): "--outDir", _join(ctx.bin_dir.path, ctx.label.package, ctx.attr.out_dir), "--rootDir", - _join(ctx.label.package, ctx.attr.root_dir) if ctx.label.package else ".", + _join( + ctx.bin_dir.path if generated_srcs else None, + ctx.label.package, + ctx.attr.root_dir, + ), ]) if len(ctx.outputs.typings_outs) > 0: declaration_dir = ctx.attr.declaration_dir if ctx.attr.declaration_dir else ctx.attr.out_dir @@ -90,12 +105,17 @@ def _ts_project_impl(ctx): deps_depsets.append(dep[DeclarationInfo].transitive_declarations) inputs = ctx.files.srcs + depset(transitive = deps_depsets).to_list() + + # Gather TsConfig info from both the direct (tsconfig) and indirect (extends) attribute 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) + for extend in ctx.attr.extends: + if TsConfigInfo in extend: + inputs.extend(extend[TsConfigInfo].deps) + else: + inputs.extend(extend.files.to_list()) # We do not try to predeclare json_outs, because their output locations generally conflict with their path in the source tree. # (The exception is when out_dir is used, then the .json output is a different path than the input.) @@ -359,14 +379,51 @@ 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, or a target that provides TsConfigInfo. + tsconfig: Label of the tsconfig.json file to use for the compilation - By default, we assume the tsconfig file is named by adding `.json` to the `name` attribute. + To support "chaining" of more than one extended config, this label could be a target that + provdes `TsConfigInfo` such as `ts_config`. - extends: List of labels of tsconfig file(s) referenced in `extends` section of tsconfig. + By default, we assume the tsconfig file is named by adding `.json` to the `name` attribute. - 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. + EXPERIMENTAL: generated tsconfig + + Instead of a label, you can pass a dictionary of tsconfig keys. + + In this case, a tsconfig.json file will be generated for this compilation, in the following way: + - all top-level keys will be copied by converting the dict to json. + So `tsconfig = {"compilerOptions": {"declaration": True}}` + will result in a generated `tsconfig.json` with `{"compilerOptions": {"declaration": true}}` + - each file in srcs will be converted to a relative path in the `files` section. + - the `extends` attribute will be converted to a relative path + + Note that you can mix and match attributes and compilerOptions properties, so these are equivalent: + + ``` + ts_project( + tsconfig = { + "compilerOptions": { + "declaration": True, + }, + }, + ) + ``` + and + ``` + ts_project( + declaration = True, + ) + ``` + + extends: Label of the tsconfig file referenced in the `extends` section of tsconfig + + To support "chaining" of more than one extended config, this label could be a target that + provdes `TsConfigInfo` such as `ts_config`. + + _DEPRECATED, to be removed in 3.0_: + For backwards compatibility, this accepts a list of Labels of the "chained" + tsconfig files. You should instead use a single Label of a `ts_config` target. + Follow this deprecation: https://github.com/bazelbuild/rules_nodejs/issues/2140 args: List of strings of additional command-line arguments to pass to tsc. @@ -413,31 +470,70 @@ def ts_project_macro( if srcs == None: srcs = native.glob(["**/*.ts", "**/*.tsx"]) - - if tsconfig == None: - tsconfig = name + ".json" - extra_deps = [] - if validate: - validate_options( - name = "_validate_%s_options" % name, - target = "//%s:%s" % (native.package_name(), name), - declaration = declaration, - source_map = source_map, - declaration_map = declaration_map, - composite = composite, - incremental = incremental, - emit_declaration_only = emit_declaration_only, - ts_build_info_file = ts_build_info_file, - tsconfig = tsconfig, - extends = extends, + if type(tsconfig) == type(dict()): + # Opt-in to #2140 breaking change at the same time you opt-in to experimental tsconfig dict + if type(extends) == type([]): + fail("when tsconfig is a dict, extends should have a single value") + + # Copy attributes <-> tsconfig properties + # TODO: fail if compilerOptions includes a conflict with an attribute? + compiler_options = tsconfig.setdefault("compilerOptions", {}) + source_map = compiler_options.setdefault("sourceMap", source_map) + declaration = compiler_options.setdefault("declaration", declaration) + declaration_map = compiler_options.setdefault("declarationMap", declaration_map) + emit_declaration_only = compiler_options.setdefault("emitDeclarationOnly", emit_declaration_only) + + # These options are always passed on the tsc command line so don't include them + # in the tsconfig. At best they're redundant, but at worst we'll have a conflict + if "outDir" in compiler_options.keys(): + out_dir = compiler_options.pop("outDir") + if "declarationDir" in compiler_options.keys(): + declaration_dir = compiler_options.pop("declarationDir") + if "rootDir" in compiler_options.keys(): + root_dir = compiler_options.pop("rootDir") + + # FIXME: need to remove keys that have a None value? + write_tsconfig( + name = "_gen_tsconfig_%s" % name, + config = tsconfig, + files = srcs, + extends = Label("//%s:%s" % (native.package_name(), name)).relative(extends) if extends else None, + out = "tsconfig_%s.json" % name, ) - extra_deps.append("_validate_%s_options" % name) + + # From here, tsconfig becomes a file, the same as if the + # user supplied a tsconfig.json InputArtifact + tsconfig = "tsconfig_%s.json" % name + + else: + if tsconfig == None: + tsconfig = name + ".json" + + if validate: + validate_options( + name = "_validate_%s_options" % name, + target = "//%s:%s" % (native.package_name(), name), + declaration = declaration, + source_map = source_map, + declaration_map = declaration_map, + composite = composite, + incremental = incremental, + ts_build_info_file = ts_build_info_file, + emit_declaration_only = emit_declaration_only, + tsconfig = tsconfig, + extends = extends, + ) + 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 name + ".tsbuildinfo" + # Backcompat for extends as a list, to cleanup in #2140 + if (type(extends) == type("")): + extends = [extends] + ts_project( name = name, srcs = srcs, diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config/BUILD.bazel b/packages/typescript/test/ts_project/generated_tsconfig/config/BUILD.bazel new file mode 100644 index 0000000000..204dcbf3a9 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config/BUILD.bazel @@ -0,0 +1,43 @@ +"Test that properties in the tsconfig dict are honored" + +load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test") +load("//packages/typescript:index.bzl", "ts_project") + +ts_project( + tsconfig = { + "compilerOptions": { + "declaration": True, + "declarationDir": "types", + "declarationMap": True, + "module": "esnext", + "outDir": "out", + "rootDir": "src", + "sourceMap": True, + "types": [], + }, + }, +) + +generated_file_test( + name = "test", + src = "expected.js_", + generated = ":out/a.js", +) + +generated_file_test( + name = "test_map", + src = "expected.js.map_", + generated = ":out/a.js.map", +) + +generated_file_test( + name = "test_dts", + src = "expected.d.ts_", + generated = ":types/a.d.ts", +) + +generated_file_test( + name = "test_dtsmap", + src = "expected.d.ts.map_", + generated = ":types/a.d.ts.map", +) diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config/expected.d.ts.map_ b/packages/typescript/test/ts_project/generated_tsconfig/config/expected.d.ts.map_ new file mode 100644 index 0000000000..5303600092 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config/expected.d.ts.map_ @@ -0,0 +1 @@ +{"version":3,"file":"a.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/typescript/test/ts_project/generated_tsconfig/config/src/a.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,CAAC,EAAE,MAAsB,CAAC"} \ No newline at end of file diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config/expected.d.ts_ b/packages/typescript/test/ts_project/generated_tsconfig/config/expected.d.ts_ new file mode 100644 index 0000000000..c3679a9567 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config/expected.d.ts_ @@ -0,0 +1,2 @@ +export declare const a: string; +//# sourceMappingURL=a.d.ts.map \ No newline at end of file diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config/expected.js.map_ b/packages/typescript/test/ts_project/generated_tsconfig/config/expected.js.map_ new file mode 100644 index 0000000000..c137136194 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config/expected.js.map_ @@ -0,0 +1 @@ +{"version":3,"file":"a.js","sourceRoot":"","sources":["../../../../../../../../../../packages/typescript/test/ts_project/generated_tsconfig/config/src/a.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,CAAC,GAAW,aAAa,CAAC"} \ No newline at end of file diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config/expected.js_ b/packages/typescript/test/ts_project/generated_tsconfig/config/expected.js_ new file mode 100644 index 0000000000..467ac85431 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config/expected.js_ @@ -0,0 +1,2 @@ +export var a = 'hello world'; +//# sourceMappingURL=a.js.map \ No newline at end of file diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config/src/a.ts b/packages/typescript/test/ts_project/generated_tsconfig/config/src/a.ts new file mode 100644 index 0000000000..f32045c3a2 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config/src/a.ts @@ -0,0 +1 @@ +export const a: string = 'hello world'; diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/BUILD.bazel b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/BUILD.bazel new file mode 100644 index 0000000000..67bbf37020 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/BUILD.bazel @@ -0,0 +1,43 @@ +"Test that attributes set on ts_project are honored" + +load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test") +load("//packages/typescript:index.bzl", "ts_project") + +ts_project( + declaration = True, + declaration_dir = "types", + declaration_map = True, + out_dir = "out", + root_dir = "src", + source_map = True, + tsconfig = { + "compilerOptions": { + "module": "esnext", + "types": [], + }, + }, +) + +generated_file_test( + name = "test", + src = "expected.js_", + generated = ":out/a.js", +) + +generated_file_test( + name = "test_map", + src = "expected.js.map_", + generated = ":out/a.js.map", +) + +generated_file_test( + name = "test_dts", + src = "expected.d.ts_", + generated = ":types/a.d.ts", +) + +generated_file_test( + name = "test_dtsmap", + src = "expected.d.ts.map_", + generated = ":types/a.d.ts.map", +) diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.d.ts.map_ b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.d.ts.map_ new file mode 100644 index 0000000000..fdb472f977 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.d.ts.map_ @@ -0,0 +1 @@ +{"version":3,"file":"a.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/typescript/test/ts_project/generated_tsconfig/config_attrs/src/a.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,CAAC,EAAE,MAAsB,CAAC"} \ No newline at end of file diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.d.ts_ b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.d.ts_ new file mode 100644 index 0000000000..c3679a9567 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.d.ts_ @@ -0,0 +1,2 @@ +export declare const a: string; +//# sourceMappingURL=a.d.ts.map \ No newline at end of file diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.js.map_ b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.js.map_ new file mode 100644 index 0000000000..66c75d8511 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.js.map_ @@ -0,0 +1 @@ +{"version":3,"file":"a.js","sourceRoot":"","sources":["../../../../../../../../../../packages/typescript/test/ts_project/generated_tsconfig/config_attrs/src/a.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAM,CAAC,GAAW,aAAa,CAAC"} \ No newline at end of file diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.js_ b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.js_ new file mode 100644 index 0000000000..467ac85431 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/expected.js_ @@ -0,0 +1,2 @@ +export var a = 'hello world'; +//# sourceMappingURL=a.js.map \ No newline at end of file diff --git a/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/src/a.ts b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/src/a.ts new file mode 100644 index 0000000000..f32045c3a2 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/config_attrs/src/a.ts @@ -0,0 +1 @@ +export const a: string = 'hello world'; diff --git a/packages/typescript/test/ts_project/generated_tsconfig/decl_only/BUILD.bazel b/packages/typescript/test/ts_project/generated_tsconfig/decl_only/BUILD.bazel new file mode 100644 index 0000000000..9462681e90 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/decl_only/BUILD.bazel @@ -0,0 +1,20 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test") +load("//packages/typescript:index.bzl", "ts_project") + +ts_project( + name = "compile", + tsconfig = { + "compilerOptions": { + "declaration": True, + "emitDeclarationOnly": True, + "types": [], + }, + }, +) + +generated_file_test( + name = "test", + src = "a.d.ts", + # test the default output of the ts_project + generated = "compile", +) diff --git a/packages/typescript/test/ts_project/generated_tsconfig/decl_only/a.ts b/packages/typescript/test/ts_project/generated_tsconfig/decl_only/a.ts new file mode 100644 index 0000000000..f32045c3a2 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/decl_only/a.ts @@ -0,0 +1 @@ +export const a: string = 'hello world'; diff --git a/packages/typescript/test/ts_project/generated_tsconfig/decl_only/expected.d.ts_ b/packages/typescript/test/ts_project/generated_tsconfig/decl_only/expected.d.ts_ new file mode 100644 index 0000000000..106d610ab9 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/decl_only/expected.d.ts_ @@ -0,0 +1 @@ +export declare const a: string; diff --git a/packages/typescript/test/ts_project/generated_tsconfig/default/BUILD.bazel b/packages/typescript/test/ts_project/generated_tsconfig/default/BUILD.bazel new file mode 100644 index 0000000000..fc4a6ed0ba --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/default/BUILD.bazel @@ -0,0 +1,16 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test") +load("//packages/typescript:index.bzl", "ts_project") + +ts_project( + tsconfig = { + "compilerOptions": { + "types": [], + }, + }, +) + +generated_file_test( + name = "test", + src = "expected.js_", + generated = ":a.js", +) diff --git a/packages/typescript/test/ts_project/generated_tsconfig/default/a.ts b/packages/typescript/test/ts_project/generated_tsconfig/default/a.ts new file mode 100644 index 0000000000..f32045c3a2 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/default/a.ts @@ -0,0 +1 @@ +export const a: string = 'hello world'; diff --git a/packages/typescript/test/ts_project/generated_tsconfig/default/expected.js_ b/packages/typescript/test/ts_project/generated_tsconfig/default/expected.js_ new file mode 100644 index 0000000000..3b0b11cce7 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/default/expected.js_ @@ -0,0 +1,3 @@ +"use strict"; +exports.__esModule = true; +exports.a = 'hello world'; diff --git a/packages/typescript/test/ts_project/generated_tsconfig/extends/BUILD.bazel b/packages/typescript/test/ts_project/generated_tsconfig/extends/BUILD.bazel new file mode 100644 index 0000000000..dd553d98d7 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/extends/BUILD.bazel @@ -0,0 +1,50 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test") +load("//packages/typescript:index.bzl", "ts_config", "ts_project") + +# Case one: extend from a single tsconfig +ts_project( + name = "case_one", + extends = "//packages/typescript/test/ts_project:tsconfig-base.json", + tsconfig = { + "compilerOptions": { + "declaration": True, + "outDir": "case_one", + "types": [], + }, + }, +) + +ts_config( + name = "tsconfig_chain", + src = "tsconfig-extended.json", + deps = [ + "//packages/typescript/test/ts_project:tsconfig", + ], +) + +# Case two: extend from a chain of tsconfig +ts_project( + name = "case_two", + extends = ":tsconfig_chain", + tsconfig = { + "compilerOptions": { + "declaration": True, + "outDir": "case_two", + "types": [], + }, + }, +) + +generated_file_test( + name = "test_one", + # test the default output of the ts_project + src = "expected.js_", + generated = "case_one/a.js", +) + +generated_file_test( + name = "test_two", + # test the default output of the ts_project + src = "expected.js_", + generated = "case_two/a.js", +) diff --git a/packages/typescript/test/ts_project/generated_tsconfig/extends/a.ts b/packages/typescript/test/ts_project/generated_tsconfig/extends/a.ts new file mode 100644 index 0000000000..f32045c3a2 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/extends/a.ts @@ -0,0 +1 @@ +export const a: string = 'hello world'; diff --git a/packages/typescript/test/ts_project/generated_tsconfig/extends/expected.js_ b/packages/typescript/test/ts_project/generated_tsconfig/extends/expected.js_ new file mode 100644 index 0000000000..a5f2dff8eb --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/extends/expected.js_ @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.a = 'hello world'; diff --git a/packages/typescript/test/ts_project/generated_tsconfig/extends/tsconfig-extended.json b/packages/typescript/test/ts_project/generated_tsconfig/extends/tsconfig-extended.json new file mode 100644 index 0000000000..ae65966f72 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/extends/tsconfig-extended.json @@ -0,0 +1,6 @@ +{ + "extends": "../../tsconfig-base", + "compilerOptions": { + "declaration": true + }, +} diff --git a/packages/typescript/test/ts_project/generated_tsconfig/gen_src/BUILD.bazel b/packages/typescript/test/ts_project/generated_tsconfig/gen_src/BUILD.bazel new file mode 100644 index 0000000000..be87f274ca --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/gen_src/BUILD.bazel @@ -0,0 +1,25 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test") +load("@build_bazel_rules_nodejs//third_party/github.com/bazelbuild/bazel-skylib:rules/write_file.bzl", "write_file") +load("//packages/typescript:index.bzl", "ts_project") + +write_file( + name = "gen_src", + out = "subdir/a.ts", + content = ["export const a: string = 'hello world';"], +) + +ts_project( + srcs = ["subdir/a.ts"], + tsconfig = { + "compilerOptions": { + "rootDir": "subdir", + "types": [], + }, + }, +) + +generated_file_test( + name = "test", + src = "expected.js_", + generated = ":a.js", +) diff --git a/packages/typescript/test/ts_project/generated_tsconfig/gen_src/expected.js_ b/packages/typescript/test/ts_project/generated_tsconfig/gen_src/expected.js_ new file mode 100644 index 0000000000..3b0b11cce7 --- /dev/null +++ b/packages/typescript/test/ts_project/generated_tsconfig/gen_src/expected.js_ @@ -0,0 +1,3 @@ +"use strict"; +exports.__esModule = true; +exports.a = 'hello world';