Skip to content

Commit 9e91872

Browse files
authored
feat(esbuild): allow ts / tsx files in esbuilds srcs (#2594)
1 parent d36b77c commit 9e91872

File tree

14 files changed

+143
-15
lines changed

14 files changed

+143
-15
lines changed

packages/esbuild/esbuild.bzl

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ esbuild rule
44

55
load("@build_bazel_rules_nodejs//:providers.bzl", "JSEcmaScriptModuleInfo", "JSModuleInfo", "NpmPackageInfo", "node_modules_aspect")
66
load("@build_bazel_rules_nodejs//internal/linker:link_node_modules.bzl", "MODULE_MAPPINGS_ASPECT_RESULTS_NAME", "module_mappings_aspect")
7-
load(":helpers.bzl", "filter_files", "generate_path_mapping", "resolve_js_input", "write_jsconfig_file")
7+
load(":helpers.bzl", "filter_files", "generate_path_mapping", "resolve_entry_point", "write_jsconfig_file")
88

99
def _esbuild_impl(ctx):
1010
# For each dep, JSEcmaScriptModuleInfo is used if found, then JSModuleInfo and finally
@@ -47,12 +47,12 @@ def _esbuild_impl(ctx):
4747
path_alias_mappings.update({"*": node_modules_mappings})
4848

4949
deps_inputs = depset(transitive = deps_depsets).to_list()
50-
inputs = filter_files(ctx.files.entry_point, [".mjs", ".js"]) + ctx.files.srcs + deps_inputs
50+
inputs = filter_files(ctx.files.entry_point) + ctx.files.srcs + deps_inputs
5151

5252
metafile = ctx.actions.declare_file("%s_metadata.json" % ctx.attr.name)
5353
outputs = [metafile]
5454

55-
entry_point = resolve_js_input(ctx.file.entry_point, inputs)
55+
entry_point = resolve_entry_point(ctx.file.entry_point, inputs, ctx.files.srcs)
5656

5757
args = ctx.actions.args()
5858

@@ -126,7 +126,7 @@ def _esbuild_impl(ctx):
126126
execution_requirements = {"no-remote-exec": "1"}
127127

128128
ctx.actions.run(
129-
inputs = inputs,
129+
inputs = depset(inputs),
130130
outputs = outputs,
131131
executable = ctx.executable.tool,
132132
arguments = [args],
@@ -260,9 +260,7 @@ See https://esbuild.github.io/api/#sources-content for more details
260260
"srcs": attr.label_list(
261261
allow_files = True,
262262
default = [],
263-
doc = """Non-entry point JavaScript source files from the workspace.
264-
265-
You must not repeat file(s) passed to entry_point""",
263+
doc = """Source files to be made available to esbuild""",
266264
),
267265
"target": attr.string(
268266
default = "es2015",

packages/esbuild/helpers.bzl

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,43 @@ Utility helper functions for the esbuild rule
44

55
load("@build_bazel_rules_nodejs//third_party/github.com/bazelbuild/bazel-skylib:lib/paths.bzl", "paths")
66

7+
TS_EXTENSIONS = ["ts", "tsx"]
8+
JS_EXTENSIONS = ["js", "mjs"]
9+
ALLOWED_EXTENSIONS = JS_EXTENSIONS + TS_EXTENSIONS
10+
711
def strip_ext(f):
812
"Strips the extension of a file."
913
return f.short_path[:-len(f.extension) - 1]
1014

11-
def resolve_js_input(f, inputs):
15+
def resolve_entry_point(f, inputs, srcs):
1216
"""Find a corresponding javascript entrypoint for a provided file
1317
1418
Args:
1519
f: The file where its basename is used to match the entrypoint
16-
inputs: The list of files where it should take a look at
20+
inputs: The list of all inputs
21+
srcs: List of direct src files to check
1722
1823
Returns:
1924
Returns the file that is the corresponding entrypoint
2025
"""
21-
if f.extension == "js" or f.extension == "mjs":
22-
return f
2326

2427
no_ext = strip_ext(f)
28+
29+
# check for the ts file in srcs
30+
for i in srcs:
31+
if i.extension in TS_EXTENSIONS:
32+
if strip_ext(i) == no_ext:
33+
return i
34+
35+
# check for a js files everywhere else
2536
for i in inputs:
26-
if i.extension == "js" or i.extension == "mjs":
37+
if i.extension in JS_EXTENSIONS:
2738
if strip_ext(i) == no_ext:
2839
return i
29-
fail("Could not find corresponding javascript entry point for %s. Add the %s.js to your deps." % (f.path, no_ext))
3040

31-
def filter_files(input, endings = [".js"]):
41+
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))
42+
43+
def filter_files(input, endings = ALLOWED_EXTENSIONS):
3244
"""Filters a list of files for specific endings
3345
3446
Args:
@@ -45,7 +57,7 @@ def filter_files(input, endings = [".js"]):
4557

4658
for file in input_list:
4759
for ending in endings:
48-
if file.path.endswith(ending):
60+
if file.path.endswith("." + ending):
4961
filtered.append(file)
5062
continue
5163

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
load("//:index.bzl", "generated_file_test", "nodejs_binary", "npm_package_bin")
2+
load("//packages/esbuild/test:tests.bzl", "esbuild")
3+
4+
esbuild(
5+
name = "lib",
6+
srcs = [
7+
"main.ts",
8+
"service/index.ts",
9+
"service/service.ts",
10+
],
11+
entry_point = "main.ts",
12+
minify = True,
13+
platform = "node",
14+
deps = [
15+
"//packages/esbuild/test/typescript/ts_as_srcs/questions",
16+
],
17+
)
18+
19+
nodejs_binary(
20+
name = "bin",
21+
data = [":lib"],
22+
entry_point = ":lib.js",
23+
)
24+
25+
npm_package_bin(
26+
name = "runner",
27+
stdout = "output.txt",
28+
tool = ":bin",
29+
)
30+
31+
generated_file_test(
32+
name = "ts_srcs_test",
33+
src = "output.golden.txt",
34+
generated = ":output.txt",
35+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {QUESTION} from '@rnj/questions';
2+
3+
import {UnhelpfulService} from './service';
4+
5+
const service = new UnhelpfulService();
6+
const answer = service.question(QUESTION);
7+
8+
console.log(answer);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Don't know
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
load("//internal/js_library:js_library.bzl", "js_library")
2+
load("//packages/typescript:index.bzl", "ts_project")
3+
4+
ts_project(
5+
name = "lib",
6+
srcs = [
7+
"index.ts",
8+
"wood-chuck.ts",
9+
],
10+
tsconfig = {
11+
"compilerOptions": {
12+
"declaration": True,
13+
"types": [],
14+
},
15+
},
16+
)
17+
18+
js_library(
19+
name = "questions",
20+
package_name = "@rnj/questions",
21+
visibility = ["//packages/esbuild/test/typescript/ts_as_srcs:__pkg__"],
22+
deps = [":lib"],
23+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './wood-chuck';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const QUESTION = `How much wood could a woodchuck chuck, if a woodchuck could chuck wood?`;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './service';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
abstract class Service {
2+
abstract question(q: string): string;
3+
}
4+
5+
export class UnhelpfulService extends Service {
6+
public question(q: string): string {
7+
return `Don't know`;
8+
}
9+
}
10+
11+
export class HelpfulService extends Service {
12+
public question(q: string): string {
13+
return `42`;
14+
}
15+
}

0 commit comments

Comments
 (0)