build: migrate adev to use rules_angular based cli rules (#62435)

Use the @angular/cli rules from rules_angular instead of the npm package directly

PR Close #62435
This commit is contained in:
Joey Perrott
2025-07-02 18:48:15 +00:00
committed by Jessica Janiuk
parent 44a203916a
commit a024c4af77
17 changed files with 5533 additions and 3132 deletions
@@ -3,6 +3,8 @@
# This file should be checked into version control along with the pnpm-lock.yaml file.
.npmrc=-1406867100
.pnpmfile.cjs=-673465510
adev/package.json=-2121383837
adev/shared-docs/package.json=450629456
adev/shared-docs/pipeline/api-gen/package.json=939673974
integration/package.json=-239561259
modules/package.json=-2081919225
+2
View File
@@ -40,6 +40,8 @@ modules/ssr-benchmarks/node_modules
# For rules_js
adev/node_modules
adev/shared-docs/node_modules
adev/shared-docs/pipeline/api-gen/node_modules
modules/node_modules
integration/node_modules
+1 -1
View File
@@ -35,4 +35,4 @@ jobs:
workflow-artifact-name: 'adev-preview'
pull-number: '${{github.event.pull_request.number}}'
artifact-build-revision: '${{github.event.pull_request.head.sha}}'
deploy-directory: './dist/bin/adev/build/browser'
deploy-directory: './dist/bin/adev/dist/browser'
+1 -1
View File
@@ -213,4 +213,4 @@ jobs:
serviceKey: ${{ secrets.ANGULAR_DEV_SITE_DEPLOY }}
githubReleaseTrainReadToken: ${{ secrets.DOCS_DEPLOY_GITHUB_RELEASE_TRAIN_TOKEN }}
configPath: 'adev/firebase.json'
distDir: 'dist/bin/adev/build/browser'
distDir: 'dist/bin/adev/dist/browser'
+9
View File
@@ -110,6 +110,8 @@ npm_translate_lock(
"//:.pnpmfile.cjs",
"//:package.json",
"//:pnpm-workspace.yaml",
"//adev:package.json",
"//adev/shared-docs:package.json",
"//adev/shared-docs/pipeline/api-gen:package.json",
"//integration:package.json",
"//modules:package.json",
@@ -360,3 +362,10 @@ git_repository(
load("@rules_sass//src/toolchain:repositories.bzl", "setup_rules_sass")
setup_rules_sass()
http_archive(
name = "jq.bzl",
sha256 = "7b63435aa19cc6a0cfd1a82fbdf2c7a2f0a94db1a79ff7a4469ffa94286261ab",
strip_prefix = "jq.bzl-0.1.0",
url = "https://github.com/bazel-contrib/jq.bzl/releases/download/v0.1.0/jq.bzl-v0.1.0.tar.gz",
)
+91 -133
View File
@@ -1,41 +1,20 @@
load("@bazel_skylib//lib:collections.bzl", "collections")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
load("@devinfra//bazel/remote-execution:index.bzl", "ENABLE_NETWORK")
load("@npm//@angular-devkit/architect-cli:index.bzl", "architect", "architect_test")
load("//adev/tools/local_deps:index.bzl", "ensure_local_package_deps", "link_local_packages")
load("//tools:defaults.bzl", "http_server")
load("@npm2//:defs.bzl", "npm_link_all_packages")
load("@rules_angular//src/architect:ng_application.bzl", "ng_application")
load("@rules_angular//src/architect:ng_config.bzl", "ng_config")
load("@rules_angular//src/architect:ng_test.bzl", "ng_test")
package(default_visibility = ["//visibility:public"])
npm_link_all_packages(
name = "node_modules",
)
exports_files([
"tsconfig.json",
])
# All source and configuration files required to build the docs app
APPLICATION_FILES = [
"angular.json",
"tsconfig.app.json",
"tsconfig.json",
"tsconfig.worker.json",
] + glob(
["src/**/*"],
exclude = [
"src/**/*.spec.ts",
],
) + [
"//adev/src/content/examples:embeddable",
]
TEST_FILES = APPLICATION_FILES + [
"karma.conf.js",
"test-main.ts",
"tsconfig.spec.json",
] + glob(
["src/**/*.spec.ts"],
)
APPLICATION_ASSETS = [
"//adev/src/assets/images",
"//adev/src/assets/others",
"//adev/src/assets/previews",
@@ -44,77 +23,75 @@ APPLICATION_ASSETS = [
"//adev/src/assets:api",
"//adev/src/assets:content",
"//adev/src/assets:context",
]
"//adev/src/content/examples:embeddable",
] + glob(
["src/**/*"],
exclude = ["src/**/*.spec.ts"],
)
APPLICATION_DEPS = [
"@npm//@angular/docs",
"@npm//@angular/build",
"@npm//@angular-devkit/build-angular",
"@npm//@angular/animations",
"@npm//@angular/cdk",
"@npm//@angular/common",
"@npm//@angular/compiler",
"@npm//@angular/compiler-cli",
"@npm//@angular/core",
"@npm//@angular/forms",
"@npm//@angular/material",
"@npm//@angular/platform-browser",
"@npm//@angular/platform-server",
"@npm//@angular/router",
"@npm//@angular/ssr",
"@npm//@types/dom-navigation",
"@npm//fflate",
"@npm//marked",
"@npm//ngx-progressbar",
"@npm//rxjs",
"@npm//xhr2",
"@npm//typescript",
"@npm//@typescript/vfs",
"@npm//@codemirror/state",
"@npm//@codemirror/view",
"@npm//@codemirror/language",
"@npm//@codemirror/commands",
"@npm//@codemirror/search",
"@npm//@codemirror/autocomplete",
"@npm//@codemirror/lint",
"@npm//@codemirror/lang-html",
"@npm//@codemirror/lang-angular",
"@npm//@codemirror/lang-css",
"@npm//@codemirror/lang-sass",
"@npm//@codemirror/lang-javascript",
"@npm//@lezer/highlight",
"@npm//@lezer/javascript",
"@npm//@lezer/common",
"@npm//@stackblitz/sdk",
"@npm//open-in-idx",
"@npm//@webcontainer/api",
"@npm//@xterm/xterm",
"@npm//@xterm/addon-fit",
"@npm//algoliasearch",
"@npm//angular-split",
"//adev:node_modules/@angular-devkit/build-angular",
"//adev:node_modules/@codemirror/autocomplete",
"//adev:node_modules/@codemirror/commands",
"//adev:node_modules/@codemirror/lang-angular",
"//adev:node_modules/@codemirror/lang-css",
"//adev:node_modules/@codemirror/lang-html",
"//adev:node_modules/@codemirror/lang-javascript",
"//adev:node_modules/@codemirror/lang-sass",
"//adev:node_modules/@codemirror/language",
"//adev:node_modules/@codemirror/lint",
"//adev:node_modules/@codemirror/search",
"//adev:node_modules/@codemirror/state",
"//adev:node_modules/@codemirror/view",
"//adev:node_modules/@lezer/common",
"//adev:node_modules/@lezer/highlight",
"//adev:node_modules/@lezer/javascript",
"//adev:node_modules/@stackblitz/sdk",
"//adev:node_modules/@typescript/vfs",
"//adev:node_modules/@webcontainer/api",
"//adev:node_modules/@xterm/addon-fit",
"//adev:node_modules/@xterm/xterm",
"//adev:node_modules/algoliasearch",
"//adev:node_modules/angular-split",
"//adev:node_modules/fflate",
"//adev:node_modules/marked",
"//adev:node_modules/ngx-progressbar",
"//adev:node_modules/open-in-idx",
"//adev:node_modules/typescript",
"//adev:node_modules/xhr2",
"//adev:node_modules/@types/node",
"//adev:node_modules/@types/dom-navigation",
# Deep imports
"//adev:node_modules/@algolia/client-common",
"//adev:node_modules/@algolia/requester-browser-xhr",
"//adev:node_modules/@algolia/requester-node-http",
"//adev:node_modules/@lezer/css",
"//adev:node_modules/@lezer/html",
"//adev:node_modules/@lezer/lr",
"//adev:node_modules/@lezer/sass",
"//adev:node_modules/@marijn/find-cluster-break",
"//adev:node_modules/crelt",
"//adev:node_modules/style-mod",
"//adev:node_modules/w3c-keyname",
]
TEST_DEPS = APPLICATION_DEPS + [
"@npm//@types/jasmine",
"@npm//@types/node",
"@npm//jasmine",
"@npm//jasmine-core",
"@npm//karma-chrome-launcher",
"@npm//karma-coverage",
"@npm//karma-jasmine",
"@npm//karma-jasmine-html-reporter",
TEST_FILES = APPLICATION_FILES + [
"karma.conf.js",
"test-main.ts",
] + glob(["src/**/*.spec.ts"])
TEST_DEPS = [
dep
for dep in APPLICATION_DEPS
if dep != "//adev:node_modules/@types/node"
] + [
"@rules_browsers//src/browsers/chromium",
"@rules_browsers//src/browsers/firefox",
"//adev/tools:windows-chromium-path",
]
# Create `npm_link` targets for all dependencies that correspond to a
# first-party Angular package that can be built from `HEAD`.
link_local_packages(
all_deps = collections.uniq(APPLICATION_DEPS + TEST_DEPS),
)
copy_to_bin(
name = "application_files_bin",
srcs = APPLICATION_FILES,
)
ng_config(name = "ng_config")
bool_flag(
name = "full_build_adev",
@@ -146,57 +123,38 @@ config_based_architect_env = select({
config_based_architect_flags = select({
":dev_build": [
"angular-dev:build:development",
"--configuration",
"development",
],
":prod_build": [
"angular-dev:build:production",
"--configuration",
"production",
],
})
architect(
ng_application(
name = "build",
args = config_based_architect_flags + [
"--output-path=build",
"",
],
chdir = "$(RULEDIR)",
data = ensure_local_package_deps(APPLICATION_DEPS) + APPLICATION_ASSETS + [
":application_files_bin",
],
srcs = APPLICATION_FILES + APPLICATION_DEPS,
args = config_based_architect_flags,
env = config_based_architect_env,
# Network is required to inline fonts.
exec_properties = ENABLE_NETWORK,
output_dir = True,
tags = [
"no-remote-exec",
],
ng_config = ":ng_config",
node_modules = "//adev:node_modules",
project_name = "angular-dev",
)
http_server(
name = "serve",
additional_root_paths = [
"angular/adev/build/browser",
],
enable_dev_ui = True,
relax_cors = True,
deps = [":build"],
)
architect_test(
ng_test(
name = "test",
args = [
"angular-dev:test",
"--no-watch",
],
chdir = package_name(),
data = ensure_local_package_deps(TEST_DEPS) + TEST_FILES + APPLICATION_ASSETS + [
"//adev/tools:windows-chromium-path",
"@npm//@angular/build-tooling/bazel/browsers/chromium",
],
srcs = TEST_FILES + TEST_DEPS,
env = {
"CHROME_BIN": "../$(CHROMIUM)",
# Move one level up because we are in `//adev`
"CHROME_BIN": "../" + "$(CHROME-HEADLESS-SHELL)",
"CHROMEDRIVER_BIN": "../" + "$(CHROMEDRIVER)",
},
ng_config = ":ng_config",
node_modules = "//adev:node_modules",
project_name = "angular-dev",
toolchains = [
"@npm//@angular/build-tooling/bazel/browsers/chromium:toolchain_alias",
"@rules_browsers//src/browsers/chromium:toolchain_alias",
"@rules_browsers//src/browsers/firefox:toolchain_alias",
],
)
+5 -13
View File
@@ -20,16 +20,8 @@
"builder": "@angular/build:application",
"options": {
"externalDependencies": ["path"],
"define": {
// We need this until xterm 5.6.0 is released
// see https://github.com/xtermjs/xterm.js/pull/4940
"self": "this"
},
// Ensures we don't escape sandbox to the workspace root with the full node modules that
// might contain e.g. `@angular/core` from npm.
"preserveSymlinks": true,
"outputMode": "static",
"outputPath": "dist/angular-dev",
"outputPath": "dist",
"index": "src/index.html",
"browser": "src/main.ts",
"server": "src/main.server.ts",
@@ -44,12 +36,14 @@
"src/llms-full.txt",
"src/context"
],
"styles": ["@angular/docs/styles/global-styles.scss", "./src/local-styles.scss"],
"styles": [
"@angular/docs/styles/global-styles.scss",
"./src/local-styles.scss"
],
"scripts": [],
"webWorkerTsConfig": "tsconfig.worker.json",
"optimization": {
"fonts": {
// TODO(josephperrott): enabled inline scripts
"inline": false
}
}
@@ -111,8 +105,6 @@
"cli": {
"analytics": "dca119a9-da31-47f7-a6cb-b60541037021",
"cache": {
// Disable build caching as the cache folder will just be dropped
// when run under Bazel sandboxed execution.
"enabled": false
}
}
+1 -1
View File
@@ -9,7 +9,7 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
const {getAdjustedChromeBinPathForWindows} = require('../adev/tools/windows-chromium-path');
const {getAdjustedChromeBinPathForWindows} = require('./tools/windows-chromium-path');
process.env.CHROME_BIN = getAdjustedChromeBinPathForWindows();
+73
View File
@@ -0,0 +1,73 @@
{
"dependencies": {
"@angular/animations": "workspace:*",
"@angular/build": "20.0.5",
"@angular-devkit/build-angular": "20.0.5",
"@angular/cdk": "20.0.4",
"@angular/cli": "20.0.5",
"@angular/common": "workspace:*",
"@angular/compiler": "workspace:*",
"@angular/core": "workspace:*",
"@angular/docs": "workspace:*",
"@angular/forms": "workspace:*",
"@angular/material": "20.0.4",
"@angular/platform-browser": "workspace:*",
"@angular/platform-server": "workspace:*",
"@angular/router": "workspace:*",
"@angular/ssr": "20.0.5",
"@codemirror/autocomplete": "6.18.6",
"@codemirror/commands": "6.8.1",
"@codemirror/lang-angular": "0.1.4",
"@codemirror/lang-css": "6.3.1",
"@codemirror/lang-html": "6.4.9",
"@codemirror/lang-javascript": "6.2.4",
"@codemirror/lang-sass": "6.0.2",
"@codemirror/language": "6.11.2",
"@codemirror/lint": "6.8.5",
"@codemirror/search": "6.5.11",
"@codemirror/state": "6.5.2",
"@codemirror/view": "6.38.0",
"@lezer/common": "1.2.3",
"@lezer/highlight": "1.2.1",
"@lezer/javascript": "1.5.1",
"@stackblitz/sdk": "1.11.0",
"@types/dom-navigation": "1.0.5",
"@types/node": "24.0.10",
"@typescript/vfs": "1.6.1",
"@webcontainer/api": "1.6.1",
"@xterm/addon-fit": "0.10.0",
"@xterm/xterm": "5.5.0",
"algoliasearch": "5.30.0",
"angular-split": "19.0.0",
"fflate": "0.8.2",
"marked": "16.0.0",
"ngx-progressbar": "14.0.0",
"open-in-idx": "0.1.1",
"rxjs": "7.8.2",
"tslib": "2.8.1",
"typescript": "5.8.3",
"xhr2": "0.2.1",
"zone.js": "0.15.1",
"karma-jasmine-html-reporter": "2.1.0",
"karma-jasmine": "5.1.0",
"karma-coverage": "2.2.1",
"karma-chrome-launcher": "3.2.0",
"jasmine-core": "5.8.0",
"@types/jasmine": "5.1.8",
"@algolia/client-common": "5.30.0",
"@algolia/requester-browser-xhr": "5.30.0",
"@algolia/requester-node-http": "5.30.0",
"@lezer/css": "1.2.1",
"@lezer/html": "1.3.10",
"@lezer/lr": "1.4.2",
"@lezer/sass": "1.1.0",
"@marijn/find-cluster-break": "1.0.2",
"crelt": "1.0.6",
"style-mod": "4.1.2",
"w3c-keyname": "2.2.8"
}
}
+3 -1
View File
@@ -1,3 +1,5 @@
load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin")
# All example files.
filegroup(
name = "examples",
@@ -6,7 +8,7 @@ filegroup(
)
# Example files that can be embedded as preview components.
filegroup(
copy_to_bin(
name = "embeddable",
srcs = glob(
["**/app/**"],
View File
@@ -1,55 +0,0 @@
"""Rule for filtering external NPM dependency targets to not include
transitive dependencies onto first-party linked `HEAD` dependencies."""
load("@build_bazel_rules_nodejs//:providers.bzl", "ExternalNpmPackageInfo", "LinkablePackageInfo")
def _filter_external_npm_deps_impl(ctx):
problematic_paths = ["external/npm/node_modules/%s" % pkg for pkg in ctx.attr.angular_packages]
package_name = ctx.attr.target.label.package
has_problematic_transitive_dep = package_name.startswith("@angular-devkit/") or package_name.startswith("@angular/build")
filtered_deps = []
# Note: to_list() is expensive; we need to invoke it here to get the path
# of each transitive dependency to check if it's an angular npm package.
for file in ctx.attr.target[DefaultInfo].default_runfiles.files.to_list():
if not any([file.path.startswith(path) for path in problematic_paths]):
filtered_deps.append(file)
else:
has_problematic_transitive_dep = True
filtered_depset = depset(filtered_deps)
providers = [
DefaultInfo(files = filtered_depset),
]
# Re-route all problematic direct dependency external NPM packages into `adev/node_modules`
# without their transitive packages. This allows transitive dependency resolution to first look for
# e.g. `@angular/core` in `adev/node_modules`, and falls back to top-level node modules.
if has_problematic_transitive_dep and ctx.attr.target.label.workspace_name == "npm":
providers.append(LinkablePackageInfo(
package_name = package_name,
package_path = "adev",
path = "external/npm/node_modules/%s" % package_name,
files = ctx.attr.target[ExternalNpmPackageInfo].direct_sources,
))
elif LinkablePackageInfo in ctx.attr.target:
providers.append(ctx.attr.target[LinkablePackageInfo])
return providers
filter_external_npm_deps = rule(
doc = "Filter out transitive angular dependencies from a target",
implementation = _filter_external_npm_deps_impl,
attrs = {
"angular_packages": attr.string_list(
mandatory = True,
doc = "Angular packages to filter (useful for sandbox environments without linker)",
),
"target": attr.label(
mandatory = True,
doc = "Target to filter",
providers = [],
),
},
)
-77
View File
@@ -1,77 +0,0 @@
load("@build_bazel_rules_nodejs//internal/linker:npm_link.bzl", "npm_link")
load("//:packages.bzl", "ALL_PACKAGES", "to_package_label")
load("//adev/tools/local_deps:filter_external_npm_deps.bzl", "filter_external_npm_deps")
def ensure_local_package_deps(deps):
"""Replaces dependencies with their local-linked variants."""
return [":%s" % _filtered_transitives_name(dep) for dep in deps]
def link_local_packages(all_deps):
"""Create targets needed for building adev against local angular packages.
Creates targets that link Angular packages, as well as targets to be used
in place of any deps required to build and test adev. These targets filter
out any transitive deps on the npm packages and must be used in place of
any original list of deps.
Use the helper `ensure_local_package_deps()` to translate a list of deps
to the equivalent "filtered" target that this rule creates.
Args:
all_deps: label list of all deps required to build and test adev
"""
local_angular_deps = [dep for dep in all_deps if _is_angular_dep(dep)]
local_angular_package_names = [_angular_dep_to_pkg_name(dep) for dep in local_angular_deps]
# Link local angular packages in place of their npm equivalent
for dep in local_angular_deps:
pkg_name = _angular_dep_to_pkg_name(dep)
npm_link(
name = _npm_link_name(pkg_name),
target = to_package_label(pkg_name) + "__adev_link",
package_name = pkg_name,
package_path = native.package_name(),
tags = ["manual"],
)
# Special case deps that must be testonly
testonly_deps = [
"@npm//@angular/build-tooling/bazel/browsers/chromium",
]
# Stamp a corresponding target for each dep that filters out transitive
# dependencies on external npm packages. This help the rules_nodejs linker,
# which fails to link local packages into transitive dependencies of npm deps.
for dep in all_deps:
target = dep
if dep in local_angular_deps:
pkg_name = _angular_dep_to_pkg_name(dep)
target = ":%s" % _npm_link_name(pkg_name)
filter_external_npm_deps(
name = _filtered_transitives_name(dep),
target = target,
testonly = True if dep in testonly_deps else False,
angular_packages = local_angular_package_names,
tags = ["manual"],
)
def _is_angular_dep(dep):
"""Check if a dep , e.g., @npm//@angular/core corresonds to a local Angular pacakge."""
return dep.startswith("@npm//") and (_angular_dep_to_pkg_name(dep) in ALL_PACKAGES)
def _angular_dep_to_pkg_name(dep):
"""E.g., @npm//@angular/core => '@angular/core'"""
label = Label(dep)
return label.package
def _npm_link_name(pkg_name):
return "local_head_%s" % pkg_name.replace("@", "_").replace("/", "_")
def _filtered_transitives_name(dep):
if dep.startswith(":"):
return "%s_without_transitive_deps" % dep[1:]
else:
label = Label(dep)
return "%s_without_transitive_deps" % label.package.replace("@", "_").replace("/", "_")
+1 -7
View File
@@ -1,4 +1,3 @@
/* To learn more about this file see: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
{
"ts-node": {
"compilerOptions": {
@@ -28,12 +27,7 @@
"jsx": "react",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",
// TODO(crisbeto): temporarily disabled while adding support for TS 5.4. Should be re-enabled.
"skipLibCheck": true,
"paths": {
"@angular/docs": ["./shared-docs"],
"@angular/*": ["../packages/*"]
}
"skipLibCheck": true
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
+1 -1
View File
@@ -45,7 +45,7 @@
"devtools:build:firefox:release": "yarn run -s devtools:build:firefox --jobs 4",
"devtools:test": "bazelisk test --//devtools/projects/shell-browser/src:flag_browser=chrome -- //devtools/...",
"devtools:test:unit": "bazelisk test -- //devtools/...",
"docs": "[[ -n $CI ]] && echo 'Cannot run this yarn script on CI' && exit 1 || yarn ibazel run //adev:serve",
"docs": "[[ -n $CI ]] && echo 'Cannot run this yarn script on CI' && exit 1 || yarn ibazel run //adev:build.serve",
"docs:build": "[[ -n $CI ]] && echo 'Cannot run this yarn script on CI' && exit 1 || yarn bazel build //adev:build",
"benchmarks": "tsx --tsconfig=scripts/tsconfig.json scripts/benchmarks/index.mts",
"diff-release-package": "tsx --tsconfig=scripts/tsconfig.json scripts/diff-release-package.mts"
+5341 -2842
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -1,5 +1,7 @@
packages:
- .
- adev
- adev/shared-docs
- adev/shared-docs/pipeline/api-gen
- modules
- integration