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

feat(esbuild): allow ts / tsx files in esbuilds srcs #2594

Merged
merged 1 commit into from
Apr 8, 2021
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
12 changes: 5 additions & 7 deletions packages/esbuild/esbuild.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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",
Expand Down
28 changes: 20 additions & 8 deletions packages/esbuild/helpers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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

Expand Down
35 changes: 35 additions & 0 deletions packages/esbuild/test/typescript/ts_as_srcs/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -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",
)
8 changes: 8 additions & 0 deletions packages/esbuild/test/typescript/ts_as_srcs/main.ts
Original file line number Diff line number Diff line change
@@ -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);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Don't know
Original file line number Diff line number Diff line change
@@ -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"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './wood-chuck';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const QUESTION = `How much wood could a woodchuck chuck, if a woodchuck could chuck wood?`;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './service';
15 changes: 15 additions & 0 deletions packages/esbuild/test/typescript/ts_as_srcs/service/service.ts
Original file line number Diff line number Diff line change
@@ -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`;
}
}
29 changes: 29 additions & 0 deletions packages/esbuild/test/vanilla_js/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -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",
)
2 changes: 2 additions & 0 deletions packages/esbuild/test/vanilla_js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const NAME = require('./name').NAME;
console.log(NAME);
1 change: 1 addition & 0 deletions packages/esbuild/test/vanilla_js/name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports.NAME = 'rules_nodejs'
1 change: 1 addition & 0 deletions packages/esbuild/test/vanilla_js/output.golden.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules_nodejs