From 5daf9a0ef409d39ab0acee4b316c2973f7bb5226 Mon Sep 17 00:00:00 2001 From: Alex Eagle Date: Mon, 7 Aug 2023 17:13:19 -0700 Subject: [PATCH] feat: on upgrade to 2.0, ask user to select transpiler This avoids everyone getting the slow 'tsc' option just because they didn't consider their options. --- .bazelrc.common | 1 + WORKSPACE | 7 ++++++ e2e/test/common.bats | 1 + internal_deps.bzl | 7 ++++++ ts/BUILD.bazel | 17 +++++++++++++ ts/private/options.bzl | 53 ++++++++++++++++++++++++++++++++++++++- ts/private/ts_project.bzl | 5 +++- 7 files changed, 89 insertions(+), 2 deletions(-) diff --git a/.bazelrc.common b/.bazelrc.common index 26bd26fa..0c98e18f 100644 --- a/.bazelrc.common +++ b/.bazelrc.common @@ -71,6 +71,7 @@ build:freebsd --nolegacy_external_runfiles build:openbsd --nolegacy_external_runfiles build --@aspect_rules_ts//ts:skipLibCheck=honor_tsconfig +build --@aspect_rules_ts//ts:default_to_tsc_transpiler # Turn on --incompatible_strict_action_env which was on by default # in Bazel 0.21.0 but turned off again in 0.22.0. Follow diff --git a/WORKSPACE b/WORKSPACE index f1e8918b..68bb37d1 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -30,6 +30,13 @@ nodejs_register_toolchains( node_version = "18.12.0", ) +load("@aspect_rules_swc//swc:repositories.bzl", "LATEST_SWC_VERSION", "swc_register_toolchains") + +swc_register_toolchains( + name = "swc", + swc_version = LATEST_SWC_VERSION, +) + # For running our own unit tests load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") diff --git a/e2e/test/common.bats b/e2e/test/common.bats index b6f0e297..c4fefa5c 100644 --- a/e2e/test/common.bats +++ b/e2e/test/common.bats @@ -45,6 +45,7 @@ try-import $BATS_TEST_DIRNAME/.bazelrc startup --max_idle_secs=10 build --worker_verbose build --@aspect_rules_ts//ts:skipLibCheck=honor_tsconfig +build --@aspect_rules_ts//ts:default_to_tsc_transpiler EOF diff --git a/internal_deps.bzl b/internal_deps.bzl index 384eff56..10b9202b 100644 --- a/internal_deps.bzl +++ b/internal_deps.bzl @@ -48,3 +48,10 @@ def rules_ts_internal_deps(): "https://github.com/keith/buildifier-prebuilt/archive/6.1.0.tar.gz", ], ) + + http_archive( + name = "aspect_rules_swc", + sha256 = "b647c7c31feeb7f9330fff08b45f8afe7de674d3a9c89c712b8f9d1723d0c8f9", + strip_prefix = "rules_swc-1.0.1", + url = "https://github.com/aspect-build/rules_swc/releases/download/v1.0.1/rules_swc-v1.0.1.tar.gz", + ) diff --git a/ts/BUILD.bazel b/ts/BUILD.bazel index ef714a85..dee35628 100644 --- a/ts/BUILD.bazel +++ b/ts/BUILD.bazel @@ -51,6 +51,12 @@ string_flag( ], ) +bool_flag( + name = "default_to_tsc_transpiler", + build_setting_default = False, + visibility = ["//visibility:public"], +) + bool_flag( name = "verbose", build_setting_default = False, @@ -94,8 +100,19 @@ config_setting( }, ) +config_setting( + name = "default_to_tsc_transpiler_flag", + flag_values = { + ":default_to_tsc_transpiler": "true", + }, +) + options( name = "options", + default_to_tsc_transpiler = select({ + ":default_to_tsc_transpiler_flag": True, + "//conditions:default": False, + }), skip_lib_check = select( { "@aspect_rules_ts//ts:skip_lib_check.always": True, diff --git a/ts/private/options.bzl b/ts/private/options.bzl index 841b0f12..6a3df309 100644 --- a/ts/private/options.bzl +++ b/ts/private/options.bzl @@ -1,8 +1,57 @@ """A terminal rule collecting verbosity and worker support information""" +transpiler_selection_required = """\ + +######## Required Transpiler Selection ######## + +You must select a transpiler for ts_project rules, which produces the .js outputs. +For more information, see https://docs.aspect.build/rules/aspect_rules_ts/docs/transpiler + +1. Use [SWC](https://swc.rs/) for transpiles (recommended) + + This option results in the fastest development round-trip time, however it may have subtle + compatibility issues: https://github.com/aspect-build/rules_ts/discussions/398 + + Add rules_swc to your Bazel project, following instructions on a recent release: + https://github.com/aspect-build/rules_swc/releases + + If you don't need any .swcrc, you can run these commands to fixup your `ts_project` calls: + + npx @bazel/buildozer 'fix movePackageToTop' //...:__pkg__ + npx @bazel/buildozer 'new_load @aspect_rules_swc//swc:defs.bzl swc' //...:__pkg__ + npx @bazel/buildozer 'set transpiler swc' //...:%ts_project + npx @bazel/buildozer 'fix unusedLoads' //...:__pkg__ + + To use an .swcrc file, see option 3 below. + +2. Use [tsc](https://www.typescriptlang.org/docs/handbook/compiler-options.html): + + In rules_ts 1.x, the default value is to have TypeScript do both type-checking and transpilation. + However, this is the slowest choice, and we no longer recommend this. + + Note that rules_ts used to recommend a "Persistent Worker" mode to keep the `tsc` process running + as a background daemon, however this introduces correctness issues in the build and is no longer + recommended. + + Add this to /.bazelrc: + + # Use "tsc" as the transpiler when ts_project has no `transpiler` set. + build --@aspect_rules_ts//ts:default_to_tsc_transpiler + +3. Use a custom transpiler + + You can set the `transpiler` attribute of each `ts_project` to any rule or macro. + This could be swc with some custom arguments, babel, esbuild, or any other tool. + + You may want to create a `ts_project` macro within your repository where your choice is setup, + then load() from your own macro rather than from @aspect_rules_ts. + +########################################################## +""" + OptionsInfo = provider( doc = "Internal: Provider that carries verbosity and global worker support information.", - fields = ["args", "verbose", "supports_workers"], + fields = ["args", "default_to_tsc_transpiler", "verbose", "supports_workers"], ) def _options_impl(ctx): @@ -40,11 +89,13 @@ def _options_impl(ctx): verbose = verbose, args = args, supports_workers = ctx.attr.supports_workers, + default_to_tsc_transpiler = ctx.attr.default_to_tsc_transpiler, ) options = rule( implementation = _options_impl, attrs = { + "default_to_tsc_transpiler": attr.bool(), "verbose": attr.bool(), "supports_workers": attr.bool(), "skip_lib_check": attr.bool(), diff --git a/ts/private/ts_project.bzl b/ts/private/ts_project.bzl index 0dcec5a0..67cc5e1b 100644 --- a/ts/private/ts_project.bzl +++ b/ts/private/ts_project.bzl @@ -10,7 +10,7 @@ load("@aspect_rules_js//npm:providers.bzl", "NpmPackageStoreInfo") load(":ts_lib.bzl", "COMPILER_OPTION_ATTRS", "OUTPUT_ATTRS", "STD_ATTRS", _lib = "lib") load(":ts_config.bzl", "TsConfigInfo") load(":ts_validate_options.bzl", _validate_lib = "lib") -load(":options.bzl", "OptionsInfo") +load(":options.bzl", "OptionsInfo", "transpiler_selection_required") # Forked from js_lib_helpers.js_lib_helpers.gather_files_from_js_providers to not # include any sources; only transitive declarations & npm linked packages @@ -207,6 +207,9 @@ This is an error because Bazel does not run actions unless their outputs are nee # library, and determines what files are used by a simple non-provider-aware downstream # library. Only the JavaScript outputs are intended for use in non-TS-aware dependents. if ctx.attr.transpile: + if not options.default_to_tsc_transpiler: + fail(transpiler_selection_required) + # Special case case where there are no source outputs and we don't have a custom # transpiler so we add output_declarations to the default outputs default_outputs = output_sources[:] if len(output_sources) else output_declarations[:]