22
33load ("@build_bazel_rules_nodejs//:providers.bzl" , "DeclarationInfo" , "NpmPackageInfo" , "declaration_info" , "js_module_info" , "run_node" )
44load ("@build_bazel_rules_nodejs//internal/linker:link_node_modules.bzl" , "module_mappings_aspect" )
5+ load ("@build_bazel_rules_nodejs//internal/node:node.bzl" , "nodejs_binary" )
56load (":ts_config.bzl" , "TsConfigInfo" , "write_tsconfig" )
67
78_ValidOptionsInfo = provider ()
@@ -13,6 +14,20 @@ _DEFAULT_TSC = (
1314 "//typescript/bin:tsc"
1415)
1516
17+ _DEFAULT_TSC_BIN = (
18+ # BEGIN-INTERNAL
19+ "@npm" +
20+ # END-INTERNAL
21+ "//:node_modules/typescript/bin/tsc"
22+ )
23+
24+ _DEFAULT_TYPESCRIPT_MODULE = (
25+ # BEGIN-INTERNAL
26+ "@npm" +
27+ # END-INTERNAL
28+ "//typescript"
29+ )
30+
1631_ATTRS = {
1732 "args" : attr .string_list (),
1833 "declaration_dir" : attr .string (),
@@ -33,7 +48,14 @@ _ATTRS = {
3348 # if you swap out the `compiler` attribute (like with ngtsc)
3449 # that compiler might allow more sources than tsc does.
3550 "srcs" : attr .label_list (allow_files = True , mandatory = True ),
36- "tsc" : attr .label (default = Label (_DEFAULT_TSC ), executable = True , cfg = "host" ),
51+ "supports_workers" : attr .bool (
52+ doc = """Experimental! Use only with caution.
53+
54+ Allows you to enable the Bazel Worker strategy for this project.
55+ This requires that the tsc binary support it.""" ,
56+ default = False ,
57+ ),
58+ "tsc" : attr .label (default = Label (_DEFAULT_TSC ), executable = True , cfg = "target" ),
3759 "tsconfig" : attr .label (mandatory = True , allow_single_file = [".json" ]),
3860}
3961
@@ -56,6 +78,16 @@ def _join(*elements):
5678
5779def _ts_project_impl (ctx ):
5880 arguments = ctx .actions .args ()
81+ execution_requirements = {}
82+ progress_prefix = "Compiling TypeScript project"
83+
84+ if ctx .attr .supports_workers :
85+ # Set to use a multiline param-file for worker mode
86+ arguments .use_param_file ("@%s" , use_always = True )
87+ arguments .set_param_file_format ("multiline" )
88+ execution_requirements ["supports-workers" ] = "1"
89+ execution_requirements ["worker-key-mnemonic" ] = "TsProject"
90+ progress_prefix = "Compiling TypeScript project (worker mode)"
5991
6092 generated_srcs = False
6193 for src in ctx .files .srcs :
@@ -164,7 +196,9 @@ def _ts_project_impl(ctx):
164196 arguments = [arguments ],
165197 outputs = outputs ,
166198 executable = "tsc" ,
167- progress_message = "Compiling TypeScript project %s [tsc -p %s]" % (
199+ execution_requirements = execution_requirements ,
200+ progress_message = "%s %s [tsc -p %s]" % (
201+ progress_prefix ,
168202 ctx .label ,
169203 ctx .file .tsconfig .short_path ,
170204 ),
@@ -289,7 +323,10 @@ def ts_project_macro(
289323 emit_declaration_only = False ,
290324 ts_build_info_file = None ,
291325 tsc = None ,
326+ worker_tsc_bin = _DEFAULT_TSC_BIN ,
327+ worker_typescript_module = _DEFAULT_TYPESCRIPT_MODULE ,
292328 validate = True ,
329+ supports_workers = False ,
293330 declaration_dir = None ,
294331 out_dir = None ,
295332 root_dir = None ,
@@ -450,8 +487,28 @@ def ts_project_macro(
450487 For example, `tsc = "@my_deps//typescript/bin:tsc"`
451488 Or you can pass a custom compiler binary instead.
452489
490+ worker_tsc_bin: Label of the TypeScript compiler binary to run when running in worker mode.
491+
492+ For example, `tsc = "@my_deps//node_modules/typescript/bin/tsc"`
493+ Or you can pass a custom compiler binary instead.
494+
495+ worker_typescript_module: Label of the package containing all data deps of worker_tsc_bin.
496+
497+ For example, `tsc = "@my_deps//typescript"`
498+
453499 validate: boolean; whether to check that the tsconfig settings match the attributes.
454500
501+ supports_workers: Experimental! Use only with caution.
502+
503+ Allows you to enable the Bazel Persistent Workers strategy for this project.
504+ See https://docs.bazel.build/versions/master/persistent-workers.html
505+
506+ This requires that the tsc binary support a `--watch` option.
507+
508+ NOTE: this does not work on Windows yet.
509+ We will silently fallback to non-worker mode on Windows regardless of the value of this attribute.
510+ Follow https://github.com/bazelbuild/rules_nodejs/issues/2277 for progress on this feature.
511+
455512 root_dir: a string specifying a subdirectory under the input package which should be consider the
456513 root directory of all the input files.
457514 Equivalent to the TypeScript --rootDir option.
@@ -556,6 +613,38 @@ def ts_project_macro(
556613 )
557614 extra_deps .append ("_validate_%s_options" % name )
558615
616+ if supports_workers :
617+ tsc_worker = "%s_worker" % name
618+ protobufjs = (
619+ # BEGIN-INTERNAL
620+ "@npm" +
621+ # END-INTERNAL
622+ "//protobufjs"
623+ )
624+ nodejs_binary (
625+ name = tsc_worker ,
626+ data = [
627+ Label ("//packages/typescript/internal/worker:worker" ),
628+ Label (worker_tsc_bin ),
629+ Label (worker_typescript_module ),
630+ Label (protobufjs ),
631+ tsconfig ,
632+ ],
633+ entry_point = Label ("//packages/typescript/internal/worker:worker_adapter" ),
634+ templated_args = [
635+ "--nobazel_patch_module_resolver" ,
636+ "$(execpath {})" .format (Label (worker_tsc_bin )),
637+ "--project" ,
638+ "$(execpath {})" .format (tsconfig ),
639+ # FIXME: should take out_dir into account
640+ "--outDir" ,
641+ "$(RULEDIR)" ,
642+ # FIXME: what about other settings like declaration_dir, root_dir, etc
643+ ],
644+ )
645+
646+ tsc = ":" + tsc_worker
647+
559648 typings_out_dir = declaration_dir if declaration_dir else out_dir
560649 tsbuildinfo_path = ts_build_info_file if ts_build_info_file else name + ".tsbuildinfo"
561650
@@ -576,5 +665,9 @@ def ts_project_macro(
576665 buildinfo_out = tsbuildinfo_path if composite or incremental else None ,
577666 tsc = tsc ,
578667 link_workspace_root = link_workspace_root ,
668+ supports_workers = select ({
669+ "@bazel_tools//src/conditions:host_windows" : False ,
670+ "//conditions:default" : supports_workers ,
671+ }),
579672 ** kwargs
580673 )
0 commit comments