| load("@build_bazel_rules_nodejs//:index.bzl", "pkg_web") | |
| load("@io_bazel_rules_docker//container:container.bzl", "container_image") | |
| load("@io_bazel_rules_docker//nodejs:image.bzl", "nodejs_image") | |
| load("@io_bazel_rules_sass//:defs.bzl", "sass_binary") | |
| load("@npm//@babel/cli:index.bzl", "babel") | |
| load("@npm//@bazel/rollup:index.bzl", "rollup_bundle") | |
| load("@npm//@bazel/terser:index.bzl", "terser_minified") | |
| load("@npm//@bazel/typescript:index.bzl", "ts_config") | |
| load("@npm//history-server:index.bzl", "history_server") | |
| load("@npm//html-insert-assets:index.bzl", "html_insert_assets") | |
| load("//tools:angular_ts_project.bzl", "ng_ts_project") | |
| load("//tools:typescript.bzl", "ts_test_project") | |
| load("//tools:ngsw_config.bzl", "ngsw_config") | |
| package(default_visibility = ["//:__subpackages__"]) | |
| ts_config( | |
| name = "tsconfig", | |
| src = "tsconfig.json", | |
| ) | |
| ts_config( | |
| name = "tsconfig-test", | |
| src = "tsconfig-test.json", | |
| deps = [":tsconfig"], | |
| ) | |
| # Run the sass compiler to output "styles.css" | |
| # TODO(alexeagle): demonstrate the sass_library rule too | |
| sass_binary( | |
| name = "styles", | |
| src = "styles.scss", | |
| ) | |
| ts_test_project( | |
| name = "initialize_testbed", | |
| srcs = [ | |
| "initialize_testbed.ts", | |
| ], | |
| deps = [ | |
| "@npm//@angular/core", | |
| "@npm//@angular/platform-browser-dynamic", | |
| ], | |
| ) | |
| ng_ts_project( | |
| name = "src", | |
| srcs = [ | |
| "main.dev.ts", | |
| "main.prod.ts", | |
| ], | |
| deps = [ | |
| "//src/app", | |
| "@npm//@angular/core", | |
| "@npm//@angular/platform-browser", | |
| "@npm//@angular/router", | |
| "@npm//@ngrx/store", | |
| ], | |
| ) | |
| # Files that we serve in both development and production | |
| _ASSETS = [ | |
| # This label references an output of the "styles" sass_binary above. | |
| ":styles.css", | |
| ":manifest.webmanifest", | |
| "//:favicon.ico", | |
| # Directly reference a file that came from @angular/material npm package | |
| "@npm//:node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css", | |
| # We load zone.js outside the bundle. That's because it's a "pollyfill" | |
| # which speculates that such features might be available in a browser. | |
| # Also it's tricky to configure dead code elimination to understand that | |
| # zone.js is used, given that we don't have any import statement that | |
| # imports from it. | |
| "@npm//:node_modules/zone.js/dist/zone.min.js", | |
| ] | |
| rollup_bundle( | |
| name = "bundle-es2015", | |
| config_file = "rollup.config.js", | |
| entry_points = { | |
| ":main.prod.ts": "index.prod", | |
| ":main.dev.ts": "index.dev", | |
| }, | |
| output_dir = True, | |
| deps = [ | |
| "//src", | |
| "@npm//@rollup/plugin-commonjs", | |
| "@npm//@rollup/plugin-node-resolve", | |
| ], | |
| ) | |
| babel( | |
| name = "bundle-es5", | |
| args = [ | |
| "$(execpath :bundle-es2015)", | |
| "--no-babelrc", | |
| "--source-maps", | |
| "--presets=@babel/preset-env", | |
| "--plugins=@babel/plugin-transform-modules-systemjs", | |
| "--out-dir", | |
| "$(@D)", | |
| ], | |
| data = [ | |
| ":bundle-es2015", | |
| "@npm//@babel/preset-env", | |
| ], | |
| output_dir = True, | |
| ) | |
| html_insert_assets( | |
| name = "inject_scripts_for_dev", | |
| outs = ["index.html"], | |
| args = [ | |
| "--html=$(execpath //src:example/index.html)", | |
| "--out=$@", | |
| "--roots=. $(RULEDIR)", | |
| "--assets", | |
| ] + ["$(execpath %s)" % s for s in _ASSETS] + [ | |
| "--scripts --module $(execpath :bundle-es2015)/index.dev.js", | |
| ], | |
| data = [ | |
| "//src:example/index.html", | |
| ":bundle-es2015", | |
| ] + _ASSETS, | |
| ) | |
| pkg_web( | |
| name = "devapp", | |
| srcs = _ASSETS + [ | |
| ":bundle-es2015", | |
| ":inject_scripts_for_dev", | |
| "//src/assets", | |
| # Include polyfills that will be requested by old browsers | |
| "@npm//:node_modules/systemjs/dist/system.js", | |
| "@npm//:node_modules/core-js/client/core.min.js", | |
| ], | |
| # In production mode we serve some polyfills with script tags that have hard-coded paths in the index.html | |
| # so we must serve them at that path, by stripping a prefix | |
| additional_root_paths = [ | |
| "npm/node_modules/core-js/client", | |
| "npm/node_modules/systemjs/dist", | |
| ], | |
| ) | |
| history_server( | |
| name = "devserver", | |
| data = [":devapp"], | |
| templated_args = ["-a $$(rlocation $(rootpath :devapp))"], | |
| ) | |
| terser_minified( | |
| name = "bundle-es2015.min", | |
| src = ":bundle-es2015", | |
| ) | |
| terser_minified( | |
| name = "bundle-es5.min", | |
| src = ":bundle-es5", | |
| ) | |
| html_insert_assets( | |
| name = "inject_scripts_for_prod", | |
| # we can't output "src/example/index.html" since that collides with the devmode file. | |
| # pkg_web rule will re-root paths that start with _{name} by default | |
| # so we output "_prodapp/src/example/index.html" so that it is mapped to | |
| # `example/index.html` in the web package. | |
| outs = ["_prodapp/src/index.html"], | |
| args = [ | |
| "--html=$(execpath //src:example/index.html)", | |
| "--out=$@", | |
| "--roots=. $(RULEDIR)", | |
| "--assets", | |
| ] + ["$(execpath %s)" % s for s in _ASSETS] + [ | |
| "--scripts --module $(execpath :bundle-es2015.min)/index.prod.js", | |
| "--scripts --nomodule $(execpath :bundle-es5.min)/index.prod.js", | |
| ], | |
| data = [ | |
| "//src:example/index.html", | |
| ":bundle-es2015.min", | |
| ":bundle-es5.min", | |
| ] + _ASSETS, | |
| ) | |
| pkg_web( | |
| name = "prodapp", | |
| srcs = _ASSETS + [ | |
| ":bundle-es2015.min", | |
| ":bundle-es5.min", | |
| # each injected index file should be listed here | |
| ":inject_scripts_for_prod", | |
| "//src/assets", | |
| ":robots.txt", | |
| # Service worker | |
| "@npm//:node_modules/@angular/service-worker/ngsw-worker.js", | |
| # Include polyfills that will be requested by old browsers | |
| "@npm//:node_modules/systemjs/dist/system.js", | |
| "@npm//:node_modules/core-js/client/core.min.js", | |
| ], | |
| # In production mode we serve some polyfills with script tags that have hard-coded paths in the index.html | |
| # so we must serve them at that path, by stripping a prefix | |
| additional_root_paths = [ | |
| "npm/node_modules/core-js/client", | |
| "npm/node_modules/systemjs/dist", | |
| "npm/node_modules/@angular/service-worker", | |
| ], | |
| ) | |
| ngsw_config( | |
| name = "pwa", | |
| src = ":prodapp", | |
| out = "pwa-config", | |
| config = "//src:ngsw-config.json", | |
| ) | |
| history_server( | |
| name = "prodserver", | |
| data = [":pwa"], | |
| templated_args = ["-a $$(rlocation $(rootpath :pwa))"], | |
| ) | |
| nodejs_image( | |
| name = "nodejs_image", | |
| binary = ":prodserver", | |
| include_node_repo_args = False, | |
| node_repository_name = "nodejs_linux_amd64", | |
| # Actions created by this rule are I/O-bound, | |
| # so there is no benefit to running them remotely | |
| tags = ["local"], | |
| ) | |
| container_image( | |
| name = "image", | |
| base = ":nodejs_image", | |
| # Actions created by this rule are I/O-bound, | |
| # so there is no benefit to running them remotely | |
| tags = ["local"], | |
| ) |