From 18a881186e64b0fdbf357fce2e178ae8427d6e93 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Sun, 23 Jul 2023 18:09:09 -0700 Subject: [PATCH] Performs a no-op bundle if no client-side JavaScript is provided. Previously the build would fail if `includeScript` was never called and `bundle_js = True`. This is because Rollup _requires_ at least one input to bundle or it will fail. In this case, we don't actually care and doing nothing is the correct solution which will inject no scripts into the page. There's a bit of wasted build-time effort, but it's not that big a deal. Unfortunately there's no way to check if any files are in a `TreeArtifact` at analysis-time and no way to configure Rollup to allow the "no inputs" case. Instead we wrap the Rollup binary with another tool, called `js_bundle`. This is simply a pass through to Rollup, however it adds one `if` statement to check for the "no inputs" case. If so, then it exits successfully as a no-op. Bazel creates the output directory automatically, so there's nothing we need to do. It bugs me a little to have to introduce another Node process for this one `if` statement. I did try to see if I could run Rollup in-process, however this seemed to require manually parsing the command line arguments and passing them through to Rollup in a structured manner, which I'd rather not deal with. If we find the extra process overhead is significant, we can maybe revisit that optimization. --- examples/no_scripts/BUILD.bazel | 41 +++++++++++++++ examples/no_scripts/README.md | 5 ++ examples/no_scripts/site.tsx | 15 ++++++ examples/no_scripts/test.mts | 20 ++++++++ packages/rules_prerender/BUILD.bazel | 7 +-- packages/rules_prerender/prerender_pages.bzl | 4 +- tools/binaries/js_bundler/BUILD.bazel | 23 +++++++++ .../binaries/js_bundler/js_bundle.bzl | 14 ++--- tools/binaries/js_bundler/js_bundler.mts | 51 +++++++++++++++++++ 9 files changed, 165 insertions(+), 15 deletions(-) create mode 100644 examples/no_scripts/BUILD.bazel create mode 100644 examples/no_scripts/README.md create mode 100644 examples/no_scripts/site.tsx create mode 100644 examples/no_scripts/test.mts create mode 100644 tools/binaries/js_bundler/BUILD.bazel rename packages/rules_prerender/scripts_bundle.bzl => tools/binaries/js_bundler/js_bundle.bzl (93%) create mode 100644 tools/binaries/js_bundler/js_bundler.mts diff --git a/examples/no_scripts/BUILD.bazel b/examples/no_scripts/BUILD.bazel new file mode 100644 index 00000000..28ebd6f8 --- /dev/null +++ b/examples/no_scripts/BUILD.bazel @@ -0,0 +1,41 @@ +load("//:index.bzl", "prerender_pages", "web_resources_devserver") +load("//tools/jasmine:defs.bzl", "jasmine_web_test_suite") +load("//tools/typescript:defs.bzl", "ts_project") + +prerender_pages( + name = "site", + entry_point = "./site.js", + prerender = ":prerender", +) + +ts_project( + name = "prerender", + srcs = ["site.tsx"], + deps = [ + "//:node_modules/@rules_prerender/preact", + "//:node_modules/preact", + ], +) + +web_resources_devserver( + name = "devserver", + resources = ":site", +) + +ts_project( + name = "test_lib", + srcs = ["test.mts"], + testonly = True, + deps = [ + "//common/testing:devserver", + "//common/testing:webdriver", + "//:node_modules/@types/jasmine", + ], +) + +jasmine_web_test_suite( + name = "test", + browsers = ["//tools/browsers:chromium-local"], + data = [":devserver"], + deps = [":test_lib"], +) diff --git a/examples/no_scripts/README.md b/examples/no_scripts/README.md new file mode 100644 index 00000000..d4b654fe --- /dev/null +++ b/examples/no_scripts/README.md @@ -0,0 +1,5 @@ +# No scripts + +Test case which does _not_ include any client-side JavaScript. This should not +emit any errors or warnings during the build process. It also should _not_ +inject any `