| 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, |
| # 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"], |
| ) |