anki/ts/svelte/svelte.bzl
Damien Elmes 1f876cfe39 Svelte build improvements
1. All Svelte files in a package are compiled in one step now, which
ensures that properties that use types from a different Svelte file in the
same package are typed correctly. The single-file svelte() has been removed,
and compile_svelte() may be renamed to svelte() in the future.

2. The .ts files in the same package are included as part of the Svelte
compilation, so that types imported imported from .ts files in the
same package work.

3. Dependencies passed into the rule are now loaded into the TypeScript
compiler, so that properties referencing types from different packages
work. We'll need to update our compile_svelte() lines to list the
dependencies. For example, before this change:

% cat bazel-bin/ts/congrats/CongratsPage.svelte.d.ts
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
    props: {
        info: any;
    };
...

After adding //ts/lib to the deps of compile_svelte() in ts/congrats:

% cat bazel-bin/ts/congrats/CongratsPage.svelte.d.ts
import { SvelteComponentTyped } from "svelte";
import type { Scheduler } from "../lib/proto";
declare const __propDef: {
    props: {
        info: Scheduler.CongratsInfoResponse;
    };
...
2021-10-18 12:44:29 +10:00

113 lines
3.4 KiB
Python

load("@npm//svelte-check:index.bzl", _svelte_check = "svelte_check_test")
load("@build_bazel_rules_nodejs//:providers.bzl", "DeclarationInfo", "declaration_info")
load("@io_bazel_rules_sass//:defs.bzl", "SassInfo")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("@bazel_skylib//lib:paths.bzl", "paths")
def _get_declarations(dep):
if SassInfo in dep:
return dep[SassInfo].transitive_sources
elif DeclarationInfo in dep:
return dep[DeclarationInfo].transitive_declarations
else:
fail("unexpected dep", dep)
def _svelte(ctx):
args = ctx.actions.args()
args.use_param_file("@%s", use_always = True)
args.set_param_file_format("multiline")
# path to bin folder, for sass
args.add(ctx.var["BINDIR"])
args.add(ctx.var["GENDIR"])
# svelte and ts sources
outputs = []
dts_only = []
nondts_only = []
for src in ctx.files.srcs:
args.add(src.path)
if src.path.endswith(".svelte"):
# strip off external/ankidesktop if invoked from external workspace
path = src.path
if src.path.startswith("external/ankidesktop/"):
path = path[len("external/ankidesktop/"):]
# strip off package prefix, eg ts/editor/mathjax/Foo.svelte -> mathjax/Foo.svelte
base = path[len(ctx.label.package) + 1:]
for ext in ("d.ts", "css", "mjs"):
out = ctx.actions.declare_file(base.replace(".svelte", ".svelte." + ext))
args.add(out)
outputs.append(out)
if ext == "d.ts":
dts_only.append(out)
else:
nondts_only.append(out)
# dependencies
deps = depset([], transitive = [_get_declarations(dep) for dep in ctx.attr.deps])
args.add_all(deps)
ctx.actions.run(
execution_requirements = {"supports-workers": "1"},
executable = ctx.executable._svelte_bin,
outputs = outputs,
inputs = ctx.files.srcs + deps.to_list(),
mnemonic = "Svelte",
progress_message = "Compiling Svelte {}:{}".format(ctx.label.package, ctx.attr.name),
arguments = [args],
)
return [
declaration_info(depset(dts_only), deps = ctx.attr.deps),
DefaultInfo(
files = depset(nondts_only),
runfiles = ctx.runfiles(files = outputs, transitive_files = deps),
),
]
svelte = rule(
implementation = _svelte,
attrs = {
"srcs": attr.label_list(allow_files = True, doc = ".ts and .svelte files"),
"deps": attr.label_list(),
"_svelte_bin": attr.label(
default = Label("//ts/svelte:svelte_bin"),
executable = True,
cfg = "host",
),
},
)
def compile_svelte(name = "svelte", srcs = None, deps = [], visibility = ["//visibility:private"]):
if not srcs:
srcs = native.glob([
"**/*.svelte",
"**/*.ts",
])
svelte(
name = name,
srcs = srcs,
deps = deps + [
"@npm//svelte2tsx",
],
visibility = visibility,
)
def svelte_check(name = "svelte_check", srcs = []):
_svelte_check(
name = name,
args = [
"--workspace",
native.package_name(),
"--fail-on-warnings",
"--fail-on-hints",
],
data = [
"@npm//sass",
] + srcs,
env = {"SASS_PATH": "sass"},
)