From 9e9187248583e351743aaa0683b2c047317fcd0c Mon Sep 17 00:00:00 2001 From: Matt Mackay Date: Thu, 8 Apr 2021 17:27:11 -0400 Subject: [PATCH] feat(esbuild): allow ts / tsx files in esbuilds srcs (#2594) --- packages/esbuild/esbuild.bzl | 12 +++---- packages/esbuild/helpers.bzl | 28 ++++++++++----- .../test/typescript/ts_as_srcs/BUILD.bazel | 35 +++++++++++++++++++ .../test/typescript/ts_as_srcs/main.ts | 8 +++++ .../typescript/ts_as_srcs/output.golden.txt | 1 + .../ts_as_srcs/questions/BUILD.bazel | 23 ++++++++++++ .../typescript/ts_as_srcs/questions/index.ts | 1 + .../ts_as_srcs/questions/wood-chuck.ts | 1 + .../typescript/ts_as_srcs/service/index.ts | 1 + .../typescript/ts_as_srcs/service/service.ts | 15 ++++++++ packages/esbuild/test/vanilla_js/BUILD.bazel | 29 +++++++++++++++ packages/esbuild/test/vanilla_js/main.js | 2 ++ packages/esbuild/test/vanilla_js/name.js | 1 + .../esbuild/test/vanilla_js/output.golden.txt | 1 + 14 files changed, 143 insertions(+), 15 deletions(-) create mode 100644 packages/esbuild/test/typescript/ts_as_srcs/BUILD.bazel create mode 100644 packages/esbuild/test/typescript/ts_as_srcs/main.ts create mode 100644 packages/esbuild/test/typescript/ts_as_srcs/output.golden.txt create mode 100644 packages/esbuild/test/typescript/ts_as_srcs/questions/BUILD.bazel create mode 100644 packages/esbuild/test/typescript/ts_as_srcs/questions/index.ts create mode 100644 packages/esbuild/test/typescript/ts_as_srcs/questions/wood-chuck.ts create mode 100644 packages/esbuild/test/typescript/ts_as_srcs/service/index.ts create mode 100644 packages/esbuild/test/typescript/ts_as_srcs/service/service.ts create mode 100644 packages/esbuild/test/vanilla_js/BUILD.bazel create mode 100644 packages/esbuild/test/vanilla_js/main.js create mode 100644 packages/esbuild/test/vanilla_js/name.js create mode 100644 packages/esbuild/test/vanilla_js/output.golden.txt diff --git a/packages/esbuild/esbuild.bzl b/packages/esbuild/esbuild.bzl index a28fcb3cd3..071915a068 100644 --- a/packages/esbuild/esbuild.bzl +++ b/packages/esbuild/esbuild.bzl @@ -4,7 +4,7 @@ esbuild rule load("@build_bazel_rules_nodejs//:providers.bzl", "JSEcmaScriptModuleInfo", "JSModuleInfo", "NpmPackageInfo", "node_modules_aspect") load("@build_bazel_rules_nodejs//internal/linker:link_node_modules.bzl", "MODULE_MAPPINGS_ASPECT_RESULTS_NAME", "module_mappings_aspect") -load(":helpers.bzl", "filter_files", "generate_path_mapping", "resolve_js_input", "write_jsconfig_file") +load(":helpers.bzl", "filter_files", "generate_path_mapping", "resolve_entry_point", "write_jsconfig_file") def _esbuild_impl(ctx): # For each dep, JSEcmaScriptModuleInfo is used if found, then JSModuleInfo and finally @@ -47,12 +47,12 @@ def _esbuild_impl(ctx): path_alias_mappings.update({"*": node_modules_mappings}) deps_inputs = depset(transitive = deps_depsets).to_list() - inputs = filter_files(ctx.files.entry_point, [".mjs", ".js"]) + ctx.files.srcs + deps_inputs + inputs = filter_files(ctx.files.entry_point) + ctx.files.srcs + deps_inputs metafile = ctx.actions.declare_file("%s_metadata.json" % ctx.attr.name) outputs = [metafile] - entry_point = resolve_js_input(ctx.file.entry_point, inputs) + entry_point = resolve_entry_point(ctx.file.entry_point, inputs, ctx.files.srcs) args = ctx.actions.args() @@ -126,7 +126,7 @@ def _esbuild_impl(ctx): execution_requirements = {"no-remote-exec": "1"} ctx.actions.run( - inputs = inputs, + inputs = depset(inputs), outputs = outputs, executable = ctx.executable.tool, arguments = [args], @@ -260,9 +260,7 @@ See https://esbuild.github.io/api/#sources-content for more details "srcs": attr.label_list( allow_files = True, default = [], - doc = """Non-entry point JavaScript source files from the workspace. - -You must not repeat file(s) passed to entry_point""", + doc = """Source files to be made available to esbuild""", ), "target": attr.string( default = "es2015", diff --git a/packages/esbuild/helpers.bzl b/packages/esbuild/helpers.bzl index 6dada022e8..61cfc87894 100644 --- a/packages/esbuild/helpers.bzl +++ b/packages/esbuild/helpers.bzl @@ -4,31 +4,43 @@ Utility helper functions for the esbuild rule load("@build_bazel_rules_nodejs//third_party/github.com/bazelbuild/bazel-skylib:lib/paths.bzl", "paths") +TS_EXTENSIONS = ["ts", "tsx"] +JS_EXTENSIONS = ["js", "mjs"] +ALLOWED_EXTENSIONS = JS_EXTENSIONS + TS_EXTENSIONS + def strip_ext(f): "Strips the extension of a file." return f.short_path[:-len(f.extension) - 1] -def resolve_js_input(f, inputs): +def resolve_entry_point(f, inputs, srcs): """Find a corresponding javascript entrypoint for a provided file Args: f: The file where its basename is used to match the entrypoint - inputs: The list of files where it should take a look at + inputs: The list of all inputs + srcs: List of direct src files to check Returns: Returns the file that is the corresponding entrypoint """ - if f.extension == "js" or f.extension == "mjs": - return f no_ext = strip_ext(f) + + # check for the ts file in srcs + for i in srcs: + if i.extension in TS_EXTENSIONS: + if strip_ext(i) == no_ext: + return i + + # check for a js files everywhere else for i in inputs: - if i.extension == "js" or i.extension == "mjs": + if i.extension in JS_EXTENSIONS: if strip_ext(i) == no_ext: return i - fail("Could not find corresponding javascript entry point for %s. Add the %s.js to your deps." % (f.path, no_ext)) -def filter_files(input, endings = [".js"]): + fail("Could not find corresponding entry point for %s. Add the %s.js to your deps or %s.ts to your srcs" % (f.path, no_ext, no_ext)) + +def filter_files(input, endings = ALLOWED_EXTENSIONS): """Filters a list of files for specific endings Args: @@ -45,7 +57,7 @@ def filter_files(input, endings = [".js"]): for file in input_list: for ending in endings: - if file.path.endswith(ending): + if file.path.endswith("." + ending): filtered.append(file) continue diff --git a/packages/esbuild/test/typescript/ts_as_srcs/BUILD.bazel b/packages/esbuild/test/typescript/ts_as_srcs/BUILD.bazel new file mode 100644 index 0000000000..dd436a379b --- /dev/null +++ b/packages/esbuild/test/typescript/ts_as_srcs/BUILD.bazel @@ -0,0 +1,35 @@ +load("//:index.bzl", "generated_file_test", "nodejs_binary", "npm_package_bin") +load("//packages/esbuild/test:tests.bzl", "esbuild") + +esbuild( + name = "lib", + srcs = [ + "main.ts", + "service/index.ts", + "service/service.ts", + ], + entry_point = "main.ts", + minify = True, + platform = "node", + deps = [ + "//packages/esbuild/test/typescript/ts_as_srcs/questions", + ], +) + +nodejs_binary( + name = "bin", + data = [":lib"], + entry_point = ":lib.js", +) + +npm_package_bin( + name = "runner", + stdout = "output.txt", + tool = ":bin", +) + +generated_file_test( + name = "ts_srcs_test", + src = "output.golden.txt", + generated = ":output.txt", +) diff --git a/packages/esbuild/test/typescript/ts_as_srcs/main.ts b/packages/esbuild/test/typescript/ts_as_srcs/main.ts new file mode 100644 index 0000000000..199f8f99cb --- /dev/null +++ b/packages/esbuild/test/typescript/ts_as_srcs/main.ts @@ -0,0 +1,8 @@ +import {QUESTION} from '@rnj/questions'; + +import {UnhelpfulService} from './service'; + +const service = new UnhelpfulService(); +const answer = service.question(QUESTION); + +console.log(answer); diff --git a/packages/esbuild/test/typescript/ts_as_srcs/output.golden.txt b/packages/esbuild/test/typescript/ts_as_srcs/output.golden.txt new file mode 100644 index 0000000000..b7dd62c84c --- /dev/null +++ b/packages/esbuild/test/typescript/ts_as_srcs/output.golden.txt @@ -0,0 +1 @@ +Don't know diff --git a/packages/esbuild/test/typescript/ts_as_srcs/questions/BUILD.bazel b/packages/esbuild/test/typescript/ts_as_srcs/questions/BUILD.bazel new file mode 100644 index 0000000000..52be229bf0 --- /dev/null +++ b/packages/esbuild/test/typescript/ts_as_srcs/questions/BUILD.bazel @@ -0,0 +1,23 @@ +load("//internal/js_library:js_library.bzl", "js_library") +load("//packages/typescript:index.bzl", "ts_project") + +ts_project( + name = "lib", + srcs = [ + "index.ts", + "wood-chuck.ts", + ], + tsconfig = { + "compilerOptions": { + "declaration": True, + "types": [], + }, + }, +) + +js_library( + name = "questions", + package_name = "@rnj/questions", + visibility = ["//packages/esbuild/test/typescript/ts_as_srcs:__pkg__"], + deps = [":lib"], +) diff --git a/packages/esbuild/test/typescript/ts_as_srcs/questions/index.ts b/packages/esbuild/test/typescript/ts_as_srcs/questions/index.ts new file mode 100644 index 0000000000..65be995799 --- /dev/null +++ b/packages/esbuild/test/typescript/ts_as_srcs/questions/index.ts @@ -0,0 +1 @@ +export * from './wood-chuck'; diff --git a/packages/esbuild/test/typescript/ts_as_srcs/questions/wood-chuck.ts b/packages/esbuild/test/typescript/ts_as_srcs/questions/wood-chuck.ts new file mode 100644 index 0000000000..10ae7914db --- /dev/null +++ b/packages/esbuild/test/typescript/ts_as_srcs/questions/wood-chuck.ts @@ -0,0 +1 @@ +export const QUESTION = `How much wood could a woodchuck chuck, if a woodchuck could chuck wood?`; diff --git a/packages/esbuild/test/typescript/ts_as_srcs/service/index.ts b/packages/esbuild/test/typescript/ts_as_srcs/service/index.ts new file mode 100644 index 0000000000..f78beabc33 --- /dev/null +++ b/packages/esbuild/test/typescript/ts_as_srcs/service/index.ts @@ -0,0 +1 @@ +export * from './service'; diff --git a/packages/esbuild/test/typescript/ts_as_srcs/service/service.ts b/packages/esbuild/test/typescript/ts_as_srcs/service/service.ts new file mode 100644 index 0000000000..00e6572be3 --- /dev/null +++ b/packages/esbuild/test/typescript/ts_as_srcs/service/service.ts @@ -0,0 +1,15 @@ +abstract class Service { + abstract question(q: string): string; +} + +export class UnhelpfulService extends Service { + public question(q: string): string { + return `Don't know`; + } +} + +export class HelpfulService extends Service { + public question(q: string): string { + return `42`; + } +} \ No newline at end of file diff --git a/packages/esbuild/test/vanilla_js/BUILD.bazel b/packages/esbuild/test/vanilla_js/BUILD.bazel new file mode 100644 index 0000000000..06e059db6d --- /dev/null +++ b/packages/esbuild/test/vanilla_js/BUILD.bazel @@ -0,0 +1,29 @@ +load("//:index.bzl", "generated_file_test", "nodejs_binary", "npm_package_bin") +load("//packages/esbuild/test:tests.bzl", "esbuild") + +esbuild( + name = "lib", + srcs = [ + "main.js", + "name.js", + ], + entry_point = "main.js", +) + +nodejs_binary( + name = "bin", + data = [":lib"], + entry_point = ":lib.js", +) + +npm_package_bin( + name = "runner", + stdout = "output.txt", + tool = ":bin", +) + +generated_file_test( + name = "vanilla_js_test", + src = "output.golden.txt", + generated = ":output.txt", +) diff --git a/packages/esbuild/test/vanilla_js/main.js b/packages/esbuild/test/vanilla_js/main.js new file mode 100644 index 0000000000..f93024a5f4 --- /dev/null +++ b/packages/esbuild/test/vanilla_js/main.js @@ -0,0 +1,2 @@ +const NAME = require('./name').NAME; +console.log(NAME); diff --git a/packages/esbuild/test/vanilla_js/name.js b/packages/esbuild/test/vanilla_js/name.js new file mode 100644 index 0000000000..7558dcba2e --- /dev/null +++ b/packages/esbuild/test/vanilla_js/name.js @@ -0,0 +1 @@ +exports.NAME = 'rules_nodejs' diff --git a/packages/esbuild/test/vanilla_js/output.golden.txt b/packages/esbuild/test/vanilla_js/output.golden.txt new file mode 100644 index 0000000000..0c23e83a65 --- /dev/null +++ b/packages/esbuild/test/vanilla_js/output.golden.txt @@ -0,0 +1 @@ +rules_nodejs