Skip to content

Commit

Permalink
fix: handle opaque targets in swc srcs (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
gregmagolan authored Nov 18, 2022
1 parent daae45d commit edc6421
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 40 deletions.
10 changes: 6 additions & 4 deletions examples/custom_outs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ load("@aspect_rules_swc//swc:defs.bzl", "swc_transpiler")
[
swc_transpiler(
name = "transpile_" + format,
srcs = ["in.ts"],
srcs = ["a.ts"],
args = [
"--config",
"module.type=" + format,
],
js_outs = [format + "/out." + ("cjs" if format == "commonjs" else "js")],
# The extension of the outputs can be modified using js_outs
js_outs = [format + "/a." + ("cjs" if format == "commonjs" else "js")],
out_dir = format,
)
for format in [
"commonjs",
Expand All @@ -20,7 +22,7 @@ load("@aspect_rules_swc//swc:defs.bzl", "swc_transpiler")
write_source_files(
name = "tests",
files = {
"expected.cjs": ":commonjs/out.cjs",
"expected.js": ":es6/out.js",
"expected.cjs": ":commonjs/a.cjs",
"expected.js": ":es6/a.js",
},
)
File renamed without changes.
2 changes: 1 addition & 1 deletion examples/custom_outs/expected.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ var a = "a";
exports.a = a;


//# sourceMappingURL=out.cjs.map
//# sourceMappingURL=a.cjs.map
2 changes: 1 addition & 1 deletion examples/custom_outs/expected.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions examples/opaque_src/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Simple use case for swc: transpiling TypeScript using the `swc` rule
Note that this example also depends on the setup in /WORKSPACE at the root of this repository.
"""

load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_files")
load("@aspect_bazel_lib//lib:output_files.bzl", "output_files")
load("@aspect_rules_swc//swc:defs.bzl", "swc")

filegroup(
name = "opaque_src",
srcs = ["in.ts"],
)

# In this case we pass a target containing sources so the swc macro can't pre-declare the .js output targets
swc(
name = "transpile",
srcs = [":opaque_src"],
)

# But we can extract the opaque outputs using output_files to make a friendly label for the output .js file
output_files(
name = "in.js",
paths = ["%s/in.js" % package_name()],
target = ":transpile",
)

# Assert that the output of "transpile" rule matches the expected file.
write_source_files(
name = "test",
# This is a pre-declared output of the "transpile" rule, so we can refer to it directly using a Bazel label
# even though the file itself is generated by Bazel in ../../bazel-bin/examples/simple/in.js
files = {"expected.js": ":in.js"},
)
4 changes: 4 additions & 0 deletions examples/opaque_src/expected.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/opaque_src/in.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const a: string = "simple";
2 changes: 1 addition & 1 deletion swc/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def swc(name, srcs = None, args = [], data = [], output_dir = False, swcrc = Non

if not output_dir:
js_outs = _swc_lib.calculate_js_outs(srcs, out_dir)
map_outs = _swc_lib.calculate_map_outs(srcs, out_dir, source_maps)
map_outs = _swc_lib.calculate_map_outs(srcs, source_maps, out_dir)

swc_transpiler(
name = name,
Expand Down
75 changes: 42 additions & 33 deletions swc/private/swc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ _SUPPORTED_EXTENSIONS = [".ts", ".tsx", ".jsx", ".mjs", ".cjs", ".js"]
def _is_supported_src(src):
return paths.split_extension(src)[-1] in _SUPPORTED_EXTENSIONS

def _declare_outputs(ctx, paths):
return [ctx.actions.declare_file(p) for p in paths]

# TODO: aspect_bazel_lib should provide this?
def _relative_to_package(path, ctx):
for prefix in (ctx.bin_dir.path, ctx.label.package):
Expand All @@ -64,6 +61,21 @@ def _relative_to_package(path, ctx):
path = path[len(prefix):]
return path

def _calculate_js_out(src, out_dir = None, js_outs = []):
if not _is_supported_src(src):
return None
js_out = paths.replace_extension(src, ".js")
if out_dir:
js_out = paths.join(out_dir, js_out)

# Check if a custom out was requested with a potentially different extension
for maybe_out in js_outs:
no_ext = paths.replace_extension(js_out, "")
if no_ext == paths.replace_extension(maybe_out, ""):
js_out = maybe_out
break
return js_out

def _calculate_js_outs(srcs, out_dir = None):
if out_dir == None:
js_srcs = []
Expand All @@ -73,21 +85,20 @@ def _calculate_js_outs(srcs, out_dir = None):
if len(js_srcs) > 0:
fail("Detected swc rule with srcs=[{}, ...] and out_dir=None. Please set out_dir when compiling .js files.".format(", ".join(js_srcs[:3])))

js_outs = [paths.replace_extension(f, ".js") for f in srcs if _is_supported_src(f)]
if out_dir != None:
js_outs = [paths.join(out_dir, f) for f in js_outs]

return js_outs
return [f2 for f2 in [_calculate_js_out(f, out_dir) for f in srcs] if f2]

def _calculate_map_outs(srcs, out_dir, source_maps):
def _calculate_map_out(src, source_maps, out_dir = None):
if source_maps in ["false", "inline"]:
return []
return None
if not _is_supported_src(src):
return None
map_out = paths.replace_extension(src, ".js.map")
if out_dir:
map_out = paths.join(out_dir, map_out)
return map_out

map_outs = [paths.replace_extension(f, ".js.map") for f in srcs if _is_supported_src(f)]
if out_dir != None:
map_outs = [paths.join(out_dir, f) for f in map_outs]

return map_outs
def _calculate_map_outs(srcs, source_maps, out_dir = None):
return [f2 for f2 in [_calculate_map_out(f, source_maps, out_dir) for f in srcs] if f2]

def _impl(ctx):
swcinfo = ctx.toolchains["@aspect_rules_swc//swc:toolchain_type"].swcinfo
Expand Down Expand Up @@ -129,32 +140,27 @@ def _impl(ctx):
progress_message = "Transpiling with swc %{label}",
)
else:
srcs = [_relative_to_package(src.path, ctx) for src in ctx.files.srcs]
output_sources = []

if len(ctx.attr.js_outs):
js_outs = ctx.outputs.js_outs
else:
js_outs = _declare_outputs(ctx, _calculate_js_outs(srcs, ctx.attr.out_dir))
if len(ctx.attr.map_outs):
map_outs = ctx.outputs.map_outs
else:
map_outs = _declare_outputs(ctx, _calculate_map_outs(srcs, ctx.attr.out_dir, ctx.attr.source_maps))
for src in ctx.files.srcs:
inputs = [copy_file_to_bin_action(ctx, src)] + swcinfo.tool_files

output_sources = js_outs + map_outs
src_path = _relative_to_package(src.path, ctx)
js_out_path = _calculate_js_out(src_path, ctx.attr.out_dir, [_relative_to_package(f.path, ctx) for f in ctx.outputs.js_outs])
if not js_out_path:
# This source file is not a supported src
continue
js_out = ctx.actions.declare_file(js_out_path)
outputs = [js_out]
map_out_path = _calculate_map_out(src_path, ctx.attr.source_maps, ctx.attr.out_dir)
if map_out_path:
outputs.append(ctx.actions.declare_file(map_out_path))

for i, src in enumerate(ctx.files.srcs):
src_args = ctx.actions.args()

js_out = js_outs[i]
inputs = [copy_file_to_bin_action(ctx, src)] + swcinfo.tool_files
outputs = [js_out]
if map_outs:
outputs.append(map_outs[i])

# Pass in the swcrc config if it is set
if ctx.file.swcrc:
swcrc_path = ctx.file.swcrc.short_path
swcrc_directory = paths.dirname(swcrc_path)
src_args.add("--config-file", swcrc_path)
inputs.append(copy_file_to_bin_action(ctx, ctx.file.swcrc))
else:
Expand All @@ -167,6 +173,8 @@ def _impl(ctx):
"-q",
])

output_sources.extend(outputs)

ctx.actions.run(
inputs = inputs,
arguments = [args, src_args],
Expand Down Expand Up @@ -227,6 +235,7 @@ swc = struct(
attrs = dict(_attrs, **_outputs),
toolchains = ["@aspect_rules_swc//swc:toolchain_type"],
SUPPORTED_EXTENSIONS = _SUPPORTED_EXTENSIONS,
calculate_js_out = _calculate_js_out,
calculate_js_outs = _calculate_js_outs,
calculate_map_outs = _calculate_map_outs,
)

0 comments on commit edc6421

Please sign in to comment.