diff --git a/.swcrc b/.swcrc new file mode 100644 index 00000000000..7f1317d0f30 --- /dev/null +++ b/.swcrc @@ -0,0 +1,10 @@ +{ + "$schema": "https://json.schemastore.org/swcrc", + "jsc": { + "transform": { + "react": { "runtime": "automatic" } + }, + "parser": { "syntax": "typescript" }, + "target": "es2022" + } +} diff --git a/BUILD.bazel b/BUILD.bazel index 8caaa6d84f3..9c22ead4c4e 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -337,4 +337,5 @@ exports_files([ # Used for when copy_to_directory might reference an empty filegroup # under certain conditions. See //ui/assets/... "CONTRIBUTING.md", + ".swcrc", ]) diff --git a/WORKSPACE b/WORKSPACE index ae70f527866..4f91499a1b2 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -49,6 +49,13 @@ http_archive( url = "https://github.com/aspect-build/rules_jest/archive/95d8f1961a9c6f3aee2929881b1b74461652e775.tar.gz", ) +http_archive( + name = "aspect_rules_swc", + sha256 = "8eb9e42ed166f20cacedfdb22d8d5b31156352eac190fc3347db55603745a2d8", + strip_prefix = "rules_swc-1.1.0", + url = "https://github.com/aspect-build/rules_swc/releases/download/v1.1.0/rules_swc-v1.1.0.tar.gz", +) + http_archive( name = "io_bazel_rules_go", sha256 = "51dc53293afe317d2696d4d6433a4c33feedb7748a9e352072e2ec3c0dafd2c6", @@ -206,12 +213,24 @@ load("@jest//:npm_repositories.bzl", jest_npm_repositories = "npm_repositories") jest_npm_repositories() +# rules_swc setup ============================== +load("@aspect_rules_swc//swc:dependencies.bzl", "rules_swc_dependencies") + +rules_swc_dependencies() + +load("@aspect_rules_swc//swc:repositories.bzl", "LATEST_SWC_VERSION", "swc_register_toolchains") + +swc_register_toolchains( + name = "swc", + swc_version = LATEST_SWC_VERSION, +) + # rules_esbuild setup =========================== http_archive( name = "aspect_rules_esbuild", - sha256 = "2ea31bd97181a315e048be693ddc2815fddda0f3a12ca7b7cc6e91e80f31bac7", - strip_prefix = "rules_esbuild-0.14.4", - url = "https://github.com/aspect-build/rules_esbuild/releases/download/v0.14.4/rules_esbuild-v0.14.4.tar.gz", + sha256 = "84419868e43c714c0d909dca73039e2f25427fc04f352d2f4f7343ca33f60deb", + strip_prefix = "rules_esbuild-0.15.3", + url = "https://github.com/aspect-build/rules_esbuild/releases/download/v0.15.3/rules_esbuild-v0.15.3.tar.gz", ) load("@aspect_rules_esbuild//esbuild:dependencies.bzl", "rules_esbuild_dependencies") @@ -219,11 +238,11 @@ load("@aspect_rules_esbuild//esbuild:dependencies.bzl", "rules_esbuild_dependenc rules_esbuild_dependencies() # Register a toolchain containing esbuild npm package and native bindings -load("@aspect_rules_esbuild//esbuild:repositories.bzl", "LATEST_VERSION", "esbuild_register_toolchains") +load("@aspect_rules_esbuild//esbuild:repositories.bzl", "LATEST_ESBUILD_VERSION", "esbuild_register_toolchains") esbuild_register_toolchains( name = "esbuild", - esbuild_version = LATEST_VERSION, + esbuild_version = LATEST_ESBUILD_VERSION, ) # Go toolchain setup diff --git a/client/browser/BUILD.bazel b/client/browser/BUILD.bazel index e85b75ac981..637b62ed490 100644 --- a/client/browser/BUILD.bazel +++ b/client/browser/BUILD.bazel @@ -381,7 +381,7 @@ esbuild( # STATIC ASSETS "//client/browser/assets", ], - config = "//client/browser/config:esbuild-config", + config = "//client/browser/config:esbuild-config_bundle", entry_points = [ "src/browser-extension/scripts/backgroundPage.main.js", "src/browser-extension/scripts/contentPage.main.js", diff --git a/client/browser/config/BUILD.bazel b/client/browser/config/BUILD.bazel index 3c170ae9cd2..51c2117ebec 100644 --- a/client/browser/config/BUILD.bazel +++ b/client/browser/config/BUILD.bazel @@ -1,4 +1,5 @@ load("//dev:defs.bzl", "ts_project") +load("@aspect_rules_esbuild//esbuild:defs.bzl", "esbuild") load("@aspect_rules_js//js:defs.bzl", "js_library") # config/ does not contain a src/ @@ -33,10 +34,41 @@ ts_project( js_library( name = "esbuild-config", srcs = ["esbuild.bazel.js"], - visibility = ["//client:__subpackages__"], deps = [ "//client/browser:node_modules/@sourcegraph/build-config", "//client/browser/config", "//client/build-config:build-config_lib", ], ) + +esbuild( + name = "esbuild-config_bundle", + srcs = [ + ":esbuild-config", + ], + entry_point = "esbuild.bazel.js", + external = [ + "fsevents", + "pnpapi", + "../../../../postcss.config", + + # suppress esbuild require-resolve-not-external warnings + "esbuild", + "path-browserify", + "monaco-yaml/lib/esm/monaco.contribution", + "monaco-yaml/lib/esm/yaml.worker", + "rxjs/_esm5/internal/OuterSubscriber", + "rxjs/_esm5/internal/util/subscribeToResult", + "rxjs/_esm5/internal/util/subscribeToArray", + "rxjs/_esm5/internal/Observable", + ], + format = "cjs", + platform = "node", + sourcemap = False, + splitting = False, + target = "es2022", + visibility = ["//client:__subpackages__"], + deps = [ + "//:postcss_config_js", + ], +) diff --git a/client/browser/src/types/webextension-polyfill/index.d.ts b/client/browser/src/types/webextension-polyfill/index.d.ts index 49377d42c00..7400dc5eed8 100644 --- a/client/browser/src/types/webextension-polyfill/index.d.ts +++ b/client/browser/src/types/webextension-polyfill/index.d.ts @@ -430,10 +430,6 @@ declare namespace browser.contentScripts { declare namespace browser.devtools.inspectedWindow { const tabId: number - function eval( - expression: string - ): Promise<[any, { isException: boolean; value: string } | { isError: boolean; code: string }]> - function reload(reloadOptions?: { ignoreCache?: boolean; userAgent?: string; injectedScript?: string }): void } diff --git a/client/build-config/BUILD.bazel b/client/build-config/BUILD.bazel index 16ae49847b4..19d2ea9b45d 100644 --- a/client/build-config/BUILD.bazel +++ b/client/build-config/BUILD.bazel @@ -35,7 +35,6 @@ ts_project( data = [ "//:postcss_config_js", #keep ], - module = "commonjs", tsconfig = ":tsconfig", deps = [ ":node_modules/@types/sass", diff --git a/client/shared/src/testing/BUILD.bazel b/client/shared/src/testing/BUILD.bazel index 34ab4456017..f1eca14ea99 100644 --- a/client/shared/src/testing/BUILD.bazel +++ b/client/shared/src/testing/BUILD.bazel @@ -57,7 +57,6 @@ ts_project( "utils.ts", ], tsconfig = "//client/shared:tsconfig", - use_preset_env = False, deps = [ "//:node_modules/@apollo/client", "//:node_modules/@axe-core/puppeteer", diff --git a/client/shared/src/testing/integration/polly/CdpAdapter.ts b/client/shared/src/testing/integration/polly/CdpAdapter.ts index 2e5658807aa..ea9568740fc 100644 --- a/client/shared/src/testing/integration/polly/CdpAdapter.ts +++ b/client/shared/src/testing/integration/polly/CdpAdapter.ts @@ -58,8 +58,11 @@ export class CdpAdapter extends PollyAdapter { /** * `adapterOptions` passed to Polly. + * + * Uses `declare` because otherwise esbuild overwrites the superclass PollyAdapter's `options` + * field. See https://github.com/evanw/esbuild/issues/885. */ - public options!: CdpAdapterOptions + public declare options: CdpAdapterOptions private readonly _errors = new Subject() diff --git a/client/web/BUILD.bazel b/client/web/BUILD.bazel index 104ced4304b..5a1547625a1 100644 --- a/client/web/BUILD.bazel +++ b/client/web/BUILD.bazel @@ -2120,7 +2120,7 @@ BUNDLE_DATA_DEPS = [ # TODO(bazel): this is already in the main ts_project(srcs). Why also here? "src/enterprise/codeintel/configuration/schema.json", ":enterprise-yaml", - "//client/web/dev:esbuild-config-production", + "//client/web/dev:esbuild-config-production_bundle", ] esbuild( @@ -2129,7 +2129,7 @@ esbuild( ":web_lib", "//:package_json", ], - config = "//client/web/dev:esbuild-config-production", + config = "//client/web/dev:esbuild-config-production_bundle", entry_points = [ "src/enterprise/main.js", "src/enterprise/embed/embedMain.js", @@ -2148,7 +2148,7 @@ esbuild_web_app( ":web_lib", "//:package_json", ], - config = "//client/web/dev:esbuild-config-production", + config = "//client/web/dev:esbuild-config-production_bundle", define = { "process.env.INTEGRATION_TESTS": "true", }, @@ -2156,6 +2156,7 @@ esbuild_web_app( "src/enterprise/main.js", "src/enterprise/embed/embedMain.js", ], + sourcemap = "linked", visibility = ["//visibility:public"], deps = ESBUILD_CONFIG_DEPS, ) diff --git a/client/web/dev/BUILD.bazel b/client/web/dev/BUILD.bazel index 331e8f6375a..04db2391132 100644 --- a/client/web/dev/BUILD.bazel +++ b/client/web/dev/BUILD.bazel @@ -1,3 +1,4 @@ +load("@aspect_rules_esbuild//esbuild:defs.bzl", "esbuild") load("@aspect_rules_js//js:defs.bzl", "js_library") load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("//dev:defs.bzl", "ts_project") @@ -36,7 +37,6 @@ ts_project( "utils/should-compress-response.ts", "utils/success-banner.ts", ], - module = "commonjs", tsconfig = ":tsconfig", visibility = ["//client/web:__subpackages__"], deps = [ @@ -66,10 +66,41 @@ ts_project( js_library( name = "esbuild-config-production", srcs = ["esbuild/bazel/esbuild.bazel.production.js"], - visibility = ["//client:__subpackages__"], deps = [ "//client/build-config:build-config_lib", "//client/web:node_modules/@sourcegraph/build-config", "//client/web/dev", ], ) + +esbuild( + name = "esbuild-config-production_bundle", + srcs = [ + ":esbuild-config-production", + ], + entry_point = "esbuild/bazel/esbuild.bazel.production.js", + external = [ + "fsevents", + "pnpapi", + "../../../../postcss.config", + + # suppress esbuild require-resolve-not-external warnings + "esbuild", + "path-browserify", + "monaco-yaml/lib/esm/monaco.contribution", + "monaco-yaml/lib/esm/yaml.worker", + "rxjs/_esm5/internal/OuterSubscriber", + "rxjs/_esm5/internal/util/subscribeToResult", + "rxjs/_esm5/internal/util/subscribeToArray", + "rxjs/_esm5/internal/Observable", + ], + format = "cjs", + platform = "node", + sourcemap = False, + splitting = False, + target = "es2022", + visibility = ["//client:__subpackages__"], + deps = [ + "//:postcss_config_js", + ], +) diff --git a/client/web/scripts/BUILD.bazel b/client/web/scripts/BUILD.bazel index c2fea2ccee0..7a29f664976 100644 --- a/client/web/scripts/BUILD.bazel +++ b/client/web/scripts/BUILD.bazel @@ -6,7 +6,6 @@ ts_project( srcs = [ "report-bundle-diff.ts", ], - module = "commonjs", tsconfig = "//client/web:tsconfig", deps = [ "//:node_modules/@types/shelljs", diff --git a/client/web/src/end-to-end/BUILD.bazel b/client/web/src/end-to-end/BUILD.bazel index 92cd1eed2b3..1c27b03869f 100644 --- a/client/web/src/end-to-end/BUILD.bazel +++ b/client/web/src/end-to-end/BUILD.bazel @@ -25,7 +25,6 @@ ts_project( "utils/initEndToEndTest.ts", ], tsconfig = ":tsconfig", - use_preset_env = False, deps = [ "//:node_modules/@types/mocha", "//:node_modules/@types/mockdate", @@ -44,7 +43,6 @@ ts_project( "frontend-platform/theme-switcher.test.ts", ], tsconfig = ":tsconfig", - use_preset_env = False, deps = [ ":end-to-end", "//:node_modules/@types/lodash", diff --git a/client/web/src/integration/BUILD.bazel b/client/web/src/integration/BUILD.bazel index 0a730c4b2ec..d99832d8e85 100644 --- a/client/web/src/integration/BUILD.bazel +++ b/client/web/src/integration/BUILD.bazel @@ -28,7 +28,6 @@ ts_project( "temporarySettingsContext.ts", "utils.ts", ], - module = "commonjs", tsconfig = ":tsconfig", deps = [ "//:node_modules/@codemirror/view", @@ -84,7 +83,6 @@ ts_project( "sign-in.test.ts", ], tsconfig = ":tsconfig", - use_preset_env = False, deps = [ ":integration", "//:node_modules/@types/lodash", diff --git a/dev/babel.bzl b/dev/babel.bzl deleted file mode 100644 index cc185d60d5d..00000000000 --- a/dev/babel.bzl +++ /dev/null @@ -1,95 +0,0 @@ -"Babel rule" - -load("@aspect_rules_js//js:defs.bzl", "js_library") -load("@npm//:@babel/cli/package_json.bzl", "bin") - -def babel(name, srcs, module = None, use_preset_env = True, **kwargs): - """A wrapper around Babel CLI - - Args: - name: A unique name for this target - - srcs: A list of sources - - module: If specified, sets BABEL_MODULE environment variable to this value - - use_preset_env: Controls if we transpile TS sources with babel-preset-env. - If set to False, sets the DISABLE_PRESET_ENV environment variable to "true". - - **kwargs: Additional arguments to pass to the rule - """ - - # rules_js runs in the execroot under the output tree in bazel-out/[arch]/bin - execroot = "../../.." - - visibility = kwargs.pop("visibility", ["//visibility:public"]) - source_map = kwargs.pop("source_map", True) - - ts_srcs = [] - outs = [] - data = kwargs.pop("data", []) - deps = kwargs.pop("deps", []) - - # Collect the srcs to compile and expected outputs - for src in srcs: - # JSON does not need to be compiled - if src.endswith(".json"): - data.append(src) - continue - - # dts are only for type-checking and not to be compiled - if src.endswith(".d.ts"): - continue - - if not (src.endswith(".ts") or src.endswith(".tsx")): - fail("babel example transpiler only supports source .ts[x] files, got: %s" % src) - - ts_srcs.append(src) - - # Predict the output paths where babel will write - js_out = src.replace(".tsx", ".js").replace(".ts", ".js") - - outs.append(js_out) - if source_map: - outs.append(js_out + ".map") - - # see https://babeljs.io/docs/en/babel-cli - args = [ - native.package_name(), - "--config-file", - "{}/$(location {})".format(execroot, "//:babel_config"), - "--source-maps", - "true" if source_map else "false", - "--extensions", - ".ts,.tsx", - "--out-dir", - "{}/{}".format(".", native.package_name()), - ] - - env = {} - if module != None: - env["BABEL_MODULE"] = module - - if use_preset_env == False: - env["DISABLE_PRESET_ENV"] = "true" - - bin.babel( - name = "{}_lib".format(name), - progress_message = "Compiling {}:{}".format(native.package_name(), name), - srcs = ts_srcs + [ - "//:babel_config", - "//:package_json", - ], - outs = outs, - args = args, - env = env, - **kwargs - ) - - js_library( - name = name, - srcs = outs, - deps = deps, - data = data, - visibility = visibility, - ) diff --git a/dev/defs.bzl b/dev/defs.bzl index 17ac8d8f93b..1cba01e286c 100644 --- a/dev/defs.bzl +++ b/dev/defs.bzl @@ -1,5 +1,6 @@ "Bazel rules" +load("@aspect_rules_swc//swc:defs.bzl", "swc") load("@bazel_skylib//lib:partial.bzl", "partial") load("@bazel_skylib//rules:expand_template.bzl", "expand_template") load("@aspect_rules_js//npm:defs.bzl", _npm_package = "npm_package") @@ -8,12 +9,11 @@ load("@aspect_rules_jest//jest:defs.bzl", _jest_test = "jest_test") load("@aspect_rules_js//js:defs.bzl", "js_binary") load("//dev:eslint.bzl", "eslint_test_with_types", "get_client_package_path") load(":sass.bzl", _sass = "sass") -load(":babel.bzl", _babel = "babel") sass = _sass # TODO move this to `ts_project.bzl` -def ts_project(name, srcs = [], deps = [], use_preset_env = True, **kwargs): +def ts_project(name, srcs = [], deps = [], module = "es6", **kwargs): """A wrapper around ts_project Args: @@ -23,7 +23,7 @@ def ts_project(name, srcs = [], deps = [], use_preset_env = True, **kwargs): deps: A list of dependencies - use_preset_env: Controls if we transpile TS sources with babel-preset-env + module: The module type to use for the project (es6 or commonjs) **kwargs: Additional arguments to pass to ts_project """ @@ -43,18 +43,27 @@ def ts_project(name, srcs = [], deps = [], use_preset_env = True, **kwargs): visibility = kwargs.pop("visibility", ["//visibility:public"]) # Add standard test libraries for the repo test frameworks - if kwargs.get("testonly", False): + testonly = kwargs.get("testonly", False) + if testonly: deps = deps + [d for d in [ "//:node_modules/@jest/globals", "//:node_modules/@types/mocha", "//:node_modules/@jest/expect", ] if not d in deps] + transpiler = partial.make( + swc, + swcrc = kwargs.pop("swcrc", "//:.swcrc"), + # Test code using jest.mock needs to be transpiled to CommonJS. + args = ["--config-json", '{"module": {"type": "commonjs"}}'] if module == "commonjs" else [], + ) + # Default arguments for ts_project. _ts_project( name = name, srcs = srcs, deps = deps, + transpiler = transpiler, # tsconfig options, default to the root tsconfig = kwargs.pop("tsconfig", "//:tsconfig"), @@ -65,16 +74,6 @@ def ts_project(name, srcs = [], deps = [], use_preset_env = True, **kwargs): source_map = kwargs.pop("source_map", True), preserve_jsx = kwargs.pop("preserve_jsx", None), visibility = visibility, - - # use babel as the transpiler - transpiler = partial.make( - _babel, - use_preset_env = use_preset_env, - module = kwargs.pop("module", None), - tags = kwargs.get("tags", []), - visibility = visibility, - testonly = kwargs.get("testonly", None), - ), supports_workers = 0, # Allow any other args diff --git a/dev/mocha.bzl b/dev/mocha.bzl index 8f508ae9f76..c493579f232 100644 --- a/dev/mocha.bzl +++ b/dev/mocha.bzl @@ -18,9 +18,6 @@ NON_BUNDLED = [ # UMD modules "jsonc-parser", - # Dependencies with bundling issues - "@sourcegraph/build-config", - # Used by require.resolve "axe-core", ] @@ -31,7 +28,6 @@ NON_BUNDLED_DEPS = [ "//:node_modules/puppeteer", "//:node_modules/@axe-core/puppeteer", "//:node_modules/axe-core", - "//client/web:node_modules/@sourcegraph/build-config", ] def mocha_test(name, tests, deps = [], args = [], data = [], env = {}, is_percy_enabled = False, **kwargs):