Skip to content

Commit

Permalink
Setup prod build for Angular app (no runtime deps on node_modules)
Browse files Browse the repository at this point in the history
  • Loading branch information
wwwillchen committed Nov 13, 2023
1 parent 78b5f79 commit 1a64118
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 83 deletions.
2 changes: 1 addition & 1 deletion optic/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ py_binary(
name = "prod_server",
srcs = ["prod_server.py"],
data = [
"//web/src/app:web_package",
"//web/src/app/prod:web_package",
],
deps = [
":server",
Expand Down
2 changes: 1 addition & 1 deletion optic/server/prod_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

def get_path():
r = runfiles.Create()
return r.Rlocation("optic/web/src/app/web_package")
return r.Rlocation("optic/web/src/app/prod/web_package")


@app.route("/")
Expand Down
1 change: 1 addition & 0 deletions scripts/run_prod.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bazel run //optic:cli -- --path="optic/examples/simple.py"
2 changes: 1 addition & 1 deletion scripts/run_web_dev.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
OPTIC_SERVER_HOST="http://localhost:8080" bazel run //web/src/app:devserver
OPTIC_SERVER_HOST="http://localhost:8080" bazel run //web/src/app/dev:server
80 changes: 1 addition & 79 deletions web/src/app/BUILD
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
# Forked from: https://github.com/angular/components/blob/ff67a416d19e9237607605bec0d7cc372025387f/src/dev-app/BUILD.bazel

load("@build_bazel_rules_nodejs//:index.bzl", "pkg_web")
load("//tools:defaults.bzl", "devmode_esbuild", "esbuild_config", "http_server", "ng_module", "sass_binary")
load("//tools/angular:index.bzl", "LINKER_PROCESSED_FW_PACKAGES")
load("//tools:defaults.bzl", "esbuild_config", "ng_module")

package(
default_visibility = ["//:optic_internal"],
Expand All @@ -28,77 +24,3 @@ esbuild_config(
name = "esbuild_config",
config_file = "esbuild.config.mjs",
)

devmode_esbuild(
name = "bundles",
config = ":esbuild_config",
entry_points = [":main.ts"],
platform = "browser",
splitting = True,
# We cannot use `ES2017` or higher as that would result in `async/await` not being downleveled.
# ZoneJS needs to be able to intercept these as otherwise change detection would not work properly.
target = "es2016",
# 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 + [
":app",
],
)

# Variables that are going to be inlined into the dev app index.html.
filegroup(
name = "variables",
# Note that we need the * in the pattern, because there's a lint rule which
# doesn't allow single files in a `glob`. We have to use a glob, because the file is optional.
srcs = glob(["*variables.json"]),
)

# File group for all static files which are needed to serve the dev-app. These files are
# used in the devserver as runfiles and will be copied into the static web package that can
# be deployed on static hosting services (like firebase).
filegroup(
name = "dev_app_static_files",
srcs = [
"index.html",
":variables",
"@npm//:node_modules/moment/min/moment-with-locales.min.js",
"@npm//:node_modules/rxjs/bundles/rxjs.umd.min.js",
"@npm//:node_modules/zone.js/dist/zone.js",
],
)

http_server(
name = "devserver",
srcs = [":dev_app_static_files"],
additional_root_paths = [
"npm/node_modules",
# Needed for compatibility with "pkg_web" which always uses the tree
# artifact output as workspace root.
"angular_material",
],
enable_dev_ui = True,
# List of environment variables that will be made available as `window.<NAME>` in the
# served `index.html` throuhg an injected script. Useful for allowing developers to
# configure API keys without requiring secrets to be committed.
environment_variables = [
"OPTIC_SERVER_HOST",
],
tags = ["manual"],
deps = [
":bundles",
],
)

# Target that builds a static web package of the dev-app. The web package can be
# deployed on static hosting services (such as firebase).
pkg_web(
name = "web_package",
srcs = [
":bundles",
":dev_app_static_files",
],
additional_root_paths = [
"npm/node_modules",
],
tags = ["manual"],
)
69 changes: 69 additions & 0 deletions web/src/app/dev/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
load("@build_bazel_rules_nodejs//:index.bzl", "pkg_web")
load("//tools:defaults.bzl", "devmode_esbuild", "esbuild", "esbuild_config", "http_server", "ng_module", "sass_binary")
load("//tools/angular:index.bzl", "LINKER_PROCESSED_FW_PACKAGES")

package(
default_visibility = ["//:optic_internal"],
)

ng_module(
name = "main",
srcs = glob([
"*.ts",
]),
deps = [
"//web/src/app",
"@npm//@angular/compiler",
],
)

devmode_esbuild(
name = "bundles",
config = "//web/src/app:esbuild_config",
entry_points = [":main.ts"],
platform = "browser",
splitting = True,
# We cannot use `ES2017` or higher as that would result in `async/await` not being downleveled.
# ZoneJS needs to be able to intercept these as otherwise change detection would not work properly.
target = "es2016",
# 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 + [
":main",
],
)

# File group for all static files which are needed to serve the dev-app. These files are
# used in the devserver as runfiles and will be copied into the static web package that can
# be deployed on static hosting services (like firebase).
filegroup(
name = "dev_app_static_files",
srcs = [
"index.html",
"@npm//:node_modules/moment/min/moment-with-locales.min.js",
"@npm//:node_modules/rxjs/bundles/rxjs.umd.min.js",
"@npm//:node_modules/zone.js/dist/zone.js",
],
)

http_server(
name = "server",
srcs = [":dev_app_static_files"],
additional_root_paths = [
"npm/node_modules",
# Needed for compatibility with "pkg_web" which always uses the tree
# artifact output as workspace root.
"angular_material",
],
enable_dev_ui = True,
# List of environment variables that will be made available as `window.<NAME>` in the
# served `index.html` throuhg an injected script. Useful for allowing developers to
# configure API keys without requiring secrets to be committed.
environment_variables = [
"OPTIC_SERVER_HOST",
],
tags = ["manual"],
deps = [
":bundles",
],
)
File renamed without changes.
2 changes: 1 addition & 1 deletion web/src/app/main.ts → web/src/app/dev/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { bootstrapApplication } from "@angular/platform-browser";
import { App } from "./app";
import { App } from "../app";

bootstrapApplication(App);
59 changes: 59 additions & 0 deletions web/src/app/prod/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
load("@build_bazel_rules_nodejs//:index.bzl", "pkg_web")
load("//tools:defaults.bzl", "devmode_esbuild", "esbuild", "esbuild_config", "http_server", "ng_module", "sass_binary")
load("//tools/angular:index.bzl", "LINKER_PROCESSED_FW_PACKAGES")

package(
default_visibility = ["//:optic_internal"],
)

ng_module(
name = "main",
srcs = glob([
"*.ts",
]),
deps = [
"//web/src/app",
"@npm//@angular/compiler",
],
)

esbuild(
name = "bundles",
config = "//web/src/app:esbuild_config",
entry_points = [":main.ts"],
platform = "browser",
splitting = True,
# We cannot use `ES2017` or higher as that would result in `async/await` not being downleveled.
# ZoneJS needs to be able to intercept these as otherwise change detection would not work properly.
target = "es2016",
deps = LINKER_PROCESSED_FW_PACKAGES + [
":main",
],
)

# File group for all static files which are needed to serve the dev-app. These files are
# used in the devserver as runfiles and will be copied into the static web package that can
# be deployed on static hosting services (like firebase).
filegroup(
name = "static_files",
srcs = [
"index.html",
"@npm//:node_modules/moment/min/moment-with-locales.min.js",
"@npm//:node_modules/rxjs/bundles/rxjs.umd.min.js",
"@npm//:node_modules/zone.js/dist/zone.js",
],
)

# Target that builds a static web package of the dev-app. The web package can be
# deployed on static hosting services (such as firebase).
pkg_web(
name = "web_package",
srcs = [
":bundles",
":static_files",
],
additional_root_paths = [
"npm/node_modules",
],
tags = ["manual"],
)
14 changes: 14 additions & 0 deletions web/src/app/prod/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Optic</title>
<base href="/">
</head>
<body>
<app>Loading...</app>
<script src="zone.js/dist/zone.js"></script>
<script src="bundles/main.js" type="module"></script>
</body>
</html>
4 changes: 4 additions & 0 deletions web/src/app/prod/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { bootstrapApplication } from "@angular/platform-browser";
import { App } from "../app";

bootstrapApplication(App);

0 comments on commit 1a64118

Please sign in to comment.