diff --git a/package.json b/package.json
index 9e2c64e67579..e785772c12b6 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"build-docs-content": "ts-node --esm --project scripts/tsconfig.json ./scripts/build-docs-content-main.mts",
"build-and-check-release-output": "ts-node --esm --project scripts/tsconfig.json scripts/build-and-check-release-output.mts",
"dev-app": "ibazel run //src/dev-app:devserver",
+ "universal-app": "bazel run //src/universal-app:server",
"test": "node ./scripts/run-component-tests.js",
"test-local": "yarn -s test --local",
"test-firefox": "yarn -s test --firefox",
diff --git a/src/universal-app/BUILD.bazel b/src/universal-app/BUILD.bazel
index f981c0546e08..ae0c52b272fa 100644
--- a/src/universal-app/BUILD.bazel
+++ b/src/universal-app/BUILD.bazel
@@ -1,9 +1,10 @@
-load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_test")
+load("@bazel_skylib//rules:build_test.bzl", "build_test")
+load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "npm_package_bin")
load("//src/cdk:config.bzl", "CDK_TARGETS")
load("//src/cdk-experimental:config.bzl", "CDK_EXPERIMENTAL_TARGETS")
load("//src/material:config.bzl", "MATERIAL_TARGETS")
load("//src/material-experimental:config.bzl", "MATERIAL_EXPERIMENTAL_TARGETS")
-load("//tools:defaults.bzl", "devmode_esbuild", "ng_module", "sass_binary", "ts_library")
+load("//tools:defaults.bzl", "devmode_esbuild", "http_server", "ng_module", "sass_binary", "ts_library")
load("//tools/angular:index.bzl", "LINKER_PROCESSED_FW_PACKAGES")
package(default_visibility = ["//visibility:public"])
@@ -24,7 +25,18 @@ ng_module(
)
ts_library(
- name = "server",
+ name = "client_lib",
+ srcs = [
+ "main.ts",
+ ],
+ deps = [
+ ":kitchen-sink",
+ "@npm//@angular/platform-browser",
+ ],
+)
+
+ts_library(
+ name = "prerender_lib",
srcs = [
"prerender.ts",
],
@@ -35,22 +47,45 @@ ts_library(
"@npm//@angular/platform-server",
"@npm//@bazel/runfiles",
"@npm//@types/node",
- "@npm//reflect-metadata",
- "@npm//zone.js",
],
)
sass_binary(
- name = "theme_scss",
- src = "theme.scss",
+ name = "styles_scss",
+ src = "styles.scss",
deps = [
"//src/material:sass_lib",
"//src/material-experimental:sass_lib",
],
)
+nodejs_binary(
+ name = "prerender",
+ data = [
+ "index-source.html",
+ ":prerender_bundle",
+ ":styles_scss",
+ ],
+ entry_point = ":prerender_bundle.js",
+ templated_args = [
+ # TODO(josephperrott): update dependency usages to no longer need bazel patch module resolver
+ # See: https://github.com/bazelbuild/rules_nodejs/wiki#--bazel_patch_module_resolver-now-defaults-to-false-2324
+ "--bazel_patch_module_resolver",
+ ],
+)
+
+devmode_esbuild(
+ name = "client_bundle",
+ entry_points = [":main.ts"],
+ platform = "browser",
+ target = "es2016",
+ deps = LINKER_PROCESSED_FW_PACKAGES + [
+ ":client_lib",
+ ],
+)
+
devmode_esbuild(
- name = "server_bundle",
+ name = "prerender_bundle",
entry_point = ":prerender.ts",
platform = "node",
# We cannot use `ES2017` or higher as that would result in `async/await` not being downleveled.
@@ -59,21 +94,46 @@ devmode_esbuild(
# Note: We add all linker-processed FW packages as dependencies here so that ESBuild will
# map all framework packages to their linker-processed bundles from `tools/angular`.
deps = LINKER_PROCESSED_FW_PACKAGES + [
- ":server",
+ ":prerender_lib",
],
)
-nodejs_test(
- name = "server_test",
- data = [
- "index.html",
- ":server_bundle",
- ":theme_scss",
+npm_package_bin(
+ name = "prerender_test_bin",
+ outs = ["index-prerendered.html"],
+ args = ["$@"],
+ tool = ":prerender",
+)
+
+npm_package_bin(
+ name = "debug_prerender_bin",
+ # Note: the file needs to be called `index.html` specifically so the server can pick it up.
+ outs = ["index.html"],
+ args = [
+ "$@",
+ "--debug", # Disables some testing behavior that can be annoying while debugging.
],
- entry_point = ":server_bundle.js",
- templated_args = [
- # TODO(josephperrott): update dependency usages to no longer need bazel patch module resolver
- # See: https://github.com/bazelbuild/rules_nodejs/wiki#--bazel_patch_module_resolver-now-defaults-to-false-2324
- "--bazel_patch_module_resolver",
+ tool = ":prerender",
+)
+
+build_test(
+ name = "prerender_test",
+ targets = [
+ ":prerender_test_bin",
+ ],
+)
+
+http_server(
+ name = "server",
+ srcs = [
+ ":debug_prerender_bin",
+ ],
+ additional_root_paths = [
+ "npm/node_modules",
+ ],
+ tags = ["manual"],
+ deps = [
+ ":client_bundle",
+ ":styles_scss",
],
)
diff --git a/src/universal-app/DEBUG.md b/src/universal-app/DEBUG.md
deleted file mode 100644
index cf1190863bd3..000000000000
--- a/src/universal-app/DEBUG.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### Debugging the pre-rendered HTML file
-
-Since the pre-rendered HTML file is built through a Bazel test target, the
-generated HTML file will not be stored in a folder of the repository. Instead,
-the file will be stored in the `bazel-out` folder.
-
-You can retrieve the path to the file by either running:
-
-* `bazel run //src/universal-app:server_test --test_output=all`
-* `echo $(bazel info bazel-testlogs)/src/universal-app/server_test/test.outputs/index-prerendered.html`
diff --git a/src/universal-app/README.md b/src/universal-app/README.md
new file mode 100644
index 000000000000..7236f8ac0e04
--- /dev/null
+++ b/src/universal-app/README.md
@@ -0,0 +1,8 @@
+### Server-side debugging app
+
+Application that renders all components on the server and hydrates them on the client. Common tasks:
+
+* Run `yarn universal-app` to start a local server. **Does not support live reload**
+* To inspect the server-side-generated HTML, run `yarn universal-app`, visit the local server and
+use either the dev tools or "View source" to see the `index.html` provided by the server.
+* To test if all components would render on the server, run `yarn bazel test src/universal-app:prerender_test`.
diff --git a/src/universal-app/index.html b/src/universal-app/index-source.html
similarity index 53%
rename from src/universal-app/index.html
rename to src/universal-app/index-source.html
index 7a2332c9b242..793b41b6725c 100644
--- a/src/universal-app/index.html
+++ b/src/universal-app/index-source.html
@@ -4,32 +4,18 @@