diff --git a/packages/esbuild/esbuild.bzl b/packages/esbuild/esbuild.bzl index 41218731ec..7ce1905778 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 @@ -44,12 +44,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() @@ -120,7 +120,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], @@ -246,9 +246,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 avialble to esbuild""", ), "target": attr.string( default = "es2015", diff --git a/packages/esbuild/helpers.bzl b/packages/esbuild/helpers.bzl index 6dada022e8..eb20101af4 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, deps, 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 + deps: The list of dependency files to check + srcs: List of 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) - for i in inputs: - if i.extension == "js" or i.extension == "mjs": + + # 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 file in the deps + for i in deps: + 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