Compare commits
73 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aec2589492 | |||
| 6d95131d84 | |||
| f7894885b8 | |||
| b89c88c73b | |||
| 7aadf42466 | |||
| cae0d3167d | |||
| 9884875c96 | |||
| eddb4051b8 | |||
| 0e23ed716e | |||
| 13601105ec | |||
| 400911e3b8 | |||
| abdf453b85 | |||
| 2bb12ac02f | |||
| 20a530acb6 | |||
| f3b0e2fbc1 | |||
| 3d5c3d9fff | |||
| 23eafb4aa2 | |||
| 7a172f7e03 | |||
| 84b2351d50 | |||
| 99bd9f13f8 | |||
| 53b0d6adb8 | |||
| cd13d1b290 | |||
| 4141d70124 | |||
| 35238a2f21 | |||
| 36e4ac6ecb | |||
| 4bc05410dd | |||
| 65b7cb2826 | |||
| f1e3ec2601 | |||
| caedd10597 | |||
| 3fae2f1e42 | |||
| 56fb556f65 | |||
| f736bea8ee | |||
| b6ca7fca96 | |||
| 1b8000dd63 | |||
| ccde17db0c | |||
| af065cc005 | |||
| 0eade1c4db | |||
| 3ad120dfe8 | |||
| 629b255ddb | |||
| ef029b8d00 | |||
| 0cb50317e1 | |||
| 7187394ffe | |||
| 8dd5c735c6 | |||
| c8472e5e9e | |||
| b90c6aa2ea | |||
| 7c9f4cbf47 | |||
| aa8df1d029 | |||
| 533ec52aca | |||
| 801e5e1577 | |||
| 2c0e60eceb | |||
| 76d0aea89b | |||
| 3068de4369 | |||
| 85ac2de744 | |||
| 28fb385eec | |||
| f5b6b7fa40 | |||
| fedeaac8ba | |||
| c1915f19c6 | |||
| c0012865eb | |||
| fb54863773 | |||
| eb1af1ed5c | |||
| b9c88dc366 | |||
| 0b790891f4 | |||
| 7287fefe7a | |||
| 8305e50f8e | |||
| 8630dc8149 | |||
| ca6cdcd269 | |||
| abbaf8f639 | |||
| 8cb838f9f6 | |||
| 0fb455f72e | |||
| 67bb310376 | |||
| a9460d08a0 | |||
| afc057ee92 | |||
| 0fffe5389f |
@@ -17,6 +17,7 @@ integration/cli-hello-world-ivy-i18n/node_modules
|
||||
integration/cli-hello-world-lazy/node_modules
|
||||
integration/cli-hello-world-mocha/node_modules
|
||||
integration/cli-signal-inputs/node_modules
|
||||
integration/platform-server-hydration/node_modules
|
||||
integration/defer/node_modules
|
||||
integration/dynamic-compiler/node_modules
|
||||
integration/forms/node_modules
|
||||
|
||||
@@ -60,6 +60,13 @@ build:release --stamp
|
||||
build:snapshot-build --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
|
||||
build:snapshot-build --stamp
|
||||
|
||||
# Angular DevTools for Firefox releases *cannot* be stamped and `--config snapshot-build-firefox` is a no-op.
|
||||
# This is because Mozilla requires add-on source code to be uploaded and then they manually reproduce the build.
|
||||
# If we stamp the build based on Git information such as the current commit, then reproducing the build would require
|
||||
# uploading the entire `.git` directory. We already must upload the entire monorepo, and uploading `.git` as well
|
||||
# exceeds the max source file size. To address this, we just *don't* stamp Firefox builds of Angular DevTools.
|
||||
build:snapshot-build-firefox --nostamp
|
||||
|
||||
##########################################################
|
||||
# AIO architect build configuration #
|
||||
# See aio/angular.json for available configurations. #
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
load("//tools:defaults.bzl", "esbuild_checked_in")
|
||||
|
||||
exports_files([
|
||||
"tsconfig.json",
|
||||
])
|
||||
|
||||
esbuild_checked_in(
|
||||
name = "main",
|
||||
entry_point = "//.github/actions/deploy-docs-site/lib:main.ts",
|
||||
external = [
|
||||
"undici",
|
||||
],
|
||||
platform = "node",
|
||||
target = "node14",
|
||||
deps = [
|
||||
"//.github/actions/deploy-docs-site/lib",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
name: 'Deploy angular.dev site'
|
||||
description: 'Automatically deploy and set up redirects for angular.dev'
|
||||
author: 'Angular'
|
||||
inputs:
|
||||
serviceKey:
|
||||
description: 'The service key used for firebase deployments.'
|
||||
required: true
|
||||
configPath:
|
||||
description: 'The path to the firebase config file.'
|
||||
required: true
|
||||
distDir:
|
||||
description: 'The path to the firebase dist directory.'
|
||||
required: true
|
||||
runs:
|
||||
using: 'node20'
|
||||
main: 'main.js'
|
||||
@@ -0,0 +1,23 @@
|
||||
load("//tools:defaults.bzl", "ts_library")
|
||||
|
||||
package(default_visibility = ["//.github/actions/deploy-docs-site:__subpackages__"])
|
||||
|
||||
exports_files([
|
||||
"main.ts",
|
||||
])
|
||||
|
||||
ts_library(
|
||||
name = "lib",
|
||||
srcs = glob(
|
||||
["*.ts"],
|
||||
),
|
||||
#tsconfig = "//.github/actions/deploy-docs-site:tsconfig.json",
|
||||
deps = [
|
||||
"@npm//@actions/core",
|
||||
"@npm//@actions/github",
|
||||
"@npm//@angular/ng-dev",
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/tmp",
|
||||
"@npm//tmp",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
import {fileSync} from 'tmp';
|
||||
import {writeSync} from 'fs';
|
||||
import {getInput, setSecret} from '@actions/core';
|
||||
|
||||
let credentialFilePath: undefined | string;
|
||||
|
||||
export function getCredentialFilePath(): string {
|
||||
if (credentialFilePath === undefined) {
|
||||
const tmpFile = fileSync({postfix: '.json'});
|
||||
writeSync(tmpFile.fd, getInput('serviceKey', {required: true}));
|
||||
setSecret(tmpFile.name);
|
||||
credentialFilePath = tmpFile.name;
|
||||
}
|
||||
return credentialFilePath;
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import {cp, mkdtemp, readFile, rm, writeFile} from 'fs/promises';
|
||||
import {Deployment} from './deployments';
|
||||
import {join} from 'path';
|
||||
|
||||
import {tmpdir} from 'os';
|
||||
import {spawnSync} from 'child_process';
|
||||
import {getCredentialFilePath} from './credential';
|
||||
|
||||
export async function deployToFirebase(
|
||||
deployment: Deployment,
|
||||
configPath: string,
|
||||
distDirPath: string,
|
||||
) {
|
||||
if (deployment.destination == undefined) {
|
||||
console.log(`No deployment necessary for docs created from: ${deployment.branch}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Preparing for deployment to firebase...');
|
||||
|
||||
const tmpDeployDir = await mkdtemp(join(tmpdir(), 'deploy-directory'));
|
||||
const deployConfigPath = join(tmpDeployDir, 'firebase.json');
|
||||
|
||||
const config = JSON.parse(await readFile(configPath, {encoding: 'utf-8'})) as {
|
||||
hosting: {public: string};
|
||||
};
|
||||
config['hosting']['public'] = './dist';
|
||||
|
||||
await writeFile(deployConfigPath, JSON.stringify(config, null, 2));
|
||||
|
||||
await cp(distDirPath, join(tmpDeployDir, 'dist'), {recursive: true});
|
||||
spawnSync(`chmod 777 -R ${tmpDeployDir}`, {encoding: 'utf-8', shell: true});
|
||||
|
||||
firebase(
|
||||
`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`,
|
||||
tmpDeployDir,
|
||||
);
|
||||
firebase(
|
||||
`target:apply --config ${deployConfigPath} --project angular-dev-site hosting angular-docs ${deployment.destination}`,
|
||||
tmpDeployDir,
|
||||
);
|
||||
firebase(
|
||||
`deploy --config ${deployConfigPath} --project angular-dev-site --only hosting --non-interactive`,
|
||||
tmpDeployDir,
|
||||
);
|
||||
firebase(
|
||||
`target:clear --config ${deployConfigPath} --project angular-dev-site hosting angular-docs`,
|
||||
tmpDeployDir,
|
||||
);
|
||||
|
||||
await rm(tmpDeployDir, {recursive: true});
|
||||
}
|
||||
|
||||
export async function setupRedirect(deployment: Deployment) {
|
||||
if (deployment.redirect === undefined) {
|
||||
console.log(`No redirect necessary for docs created from: ${deployment.branch}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Preparing to set up redirect on firebase...');
|
||||
|
||||
const redirectConfig = JSON.stringify(
|
||||
{
|
||||
hosting: {
|
||||
target: 'angular-docs',
|
||||
redirects: [
|
||||
{
|
||||
type: 302,
|
||||
regex: '^(.*)$',
|
||||
destination: `${deployment.redirect.to}:1`,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
|
||||
const tmpRedirectDir = await mkdtemp(join(tmpdir(), 'redirect-directory'));
|
||||
const redirectConfigPath = join(tmpRedirectDir, 'firebase.json');
|
||||
|
||||
await writeFile(redirectConfigPath, redirectConfig);
|
||||
spawnSync(`chmod 777 -R ${tmpRedirectDir}`, {encoding: 'utf-8', shell: true});
|
||||
|
||||
firebase(
|
||||
`target:clear --config ${redirectConfigPath} --project angular-dev-site hosting angular-docs`,
|
||||
tmpRedirectDir,
|
||||
);
|
||||
firebase(
|
||||
`target:apply --config ${redirectConfigPath} --project angular-dev-site hosting angular-docs ${deployment.redirect.from}`,
|
||||
tmpRedirectDir,
|
||||
);
|
||||
firebase(
|
||||
`deploy --config ${redirectConfigPath} --project angular-dev-site --only hosting --non-interactive`,
|
||||
tmpRedirectDir,
|
||||
);
|
||||
firebase(
|
||||
`target:clear --config ${redirectConfigPath} --project angular-dev-site hosting angular-docs`,
|
||||
tmpRedirectDir,
|
||||
);
|
||||
|
||||
await rm(tmpRedirectDir, {recursive: true});
|
||||
}
|
||||
|
||||
function firebase(cmd: string, cwd?: string) {
|
||||
spawnSync('npx', `-y firebase-tools@latest ${cmd}`.split(' '), {
|
||||
cwd,
|
||||
encoding: 'utf-8',
|
||||
shell: true,
|
||||
stdio: 'inherit',
|
||||
env: {
|
||||
...process.env,
|
||||
GOOGLE_APPLICATION_CREDENTIALS: getCredentialFilePath(),
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import {fetchLongTermSupportBranchesFromNpm, ActiveReleaseTrains} from '@angular/ng-dev';
|
||||
import {ReleaseConfig} from '@angular/ng-dev';
|
||||
import {GitClient} from '@angular/ng-dev';
|
||||
|
||||
export interface Deployment {
|
||||
branch: string;
|
||||
redirect?: {
|
||||
from: string;
|
||||
to: string;
|
||||
};
|
||||
destination?: string;
|
||||
}
|
||||
|
||||
export type Deployments = Map<string, Deployment>;
|
||||
|
||||
export async function getDeployments(): Promise<Deployments> {
|
||||
const {github} = await GitClient.get();
|
||||
const releaseTrains = await ActiveReleaseTrains.fetch({
|
||||
api: github,
|
||||
name: 'angular',
|
||||
owner: 'angular',
|
||||
nextBranchName: 'main',
|
||||
});
|
||||
const ltsBranches = await fetchLongTermSupportBranchesFromNpm({
|
||||
representativeNpmPackage: '@angular/core',
|
||||
} as ReleaseConfig);
|
||||
|
||||
const docSites = new Map<string, Deployment>();
|
||||
|
||||
[...ltsBranches.active, ...ltsBranches.inactive].forEach((branch) => {
|
||||
docSites.set(branch.name, {
|
||||
branch: branch.name,
|
||||
destination: `v${branch.version.major}-angular-dev`,
|
||||
});
|
||||
});
|
||||
|
||||
docSites.set(releaseTrains.latest.branchName, {
|
||||
branch: releaseTrains.latest.branchName,
|
||||
redirect: {
|
||||
from: `v${releaseTrains.latest.version.major}-angular-dev`,
|
||||
to: 'https://angular.dev',
|
||||
},
|
||||
destination: 'angular-dev-site',
|
||||
});
|
||||
|
||||
if (releaseTrains.releaseCandidate) {
|
||||
docSites.set(releaseTrains.next.branchName, {
|
||||
branch: releaseTrains.next.branchName,
|
||||
});
|
||||
|
||||
docSites.set(releaseTrains.releaseCandidate.branchName, {
|
||||
branch: releaseTrains.releaseCandidate.branchName,
|
||||
destination: 'next-angular-dev',
|
||||
});
|
||||
} else {
|
||||
docSites.set(releaseTrains.next.branchName, {
|
||||
branch: releaseTrains.next.branchName,
|
||||
destination: 'next-angular-dev',
|
||||
redirect: {
|
||||
from: `v${releaseTrains.next.version.major}-angular-dev`,
|
||||
to: 'https://next.angular.dev',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return docSites;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import {getInput, setFailed} from '@actions/core';
|
||||
import {context} from '@actions/github';
|
||||
import {deployToFirebase, setupRedirect} from './deploy';
|
||||
import {getDeployments} from './deployments';
|
||||
import {GithubConfig, setConfig} from '@angular/ng-dev';
|
||||
|
||||
const refMatcher = /refs\/heads\/(.*)/;
|
||||
|
||||
async function deployDocs() {
|
||||
setConfig({
|
||||
github: <GithubConfig>{
|
||||
mainBranchName: 'main',
|
||||
name: 'angular',
|
||||
owner: 'angular',
|
||||
},
|
||||
});
|
||||
if (context.eventName !== 'push') {
|
||||
throw Error();
|
||||
}
|
||||
const matchedRef = context.ref.match(refMatcher);
|
||||
if (matchedRef === null) {
|
||||
throw Error();
|
||||
}
|
||||
|
||||
const currentBranch = matchedRef[1];
|
||||
const configPath = getInput('configPath');
|
||||
const distDir = getInput('distDir');
|
||||
|
||||
const deployment = (await getDeployments()).get(currentBranch);
|
||||
if (deployment === undefined) {
|
||||
console.log(`Current branch (${currentBranch}) does not deploy a documentation site.`);
|
||||
console.log(`Exiting...`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
console.log('Doc site deployment information');
|
||||
console.log('');
|
||||
console.log('Current Branch:');
|
||||
console.log(` ${deployment.branch}`);
|
||||
console.log('');
|
||||
console.log('Firebase Site:');
|
||||
if (deployment.destination === undefined) {
|
||||
console.log(' No deployment of a documenation site is necessary');
|
||||
} else {
|
||||
console.log(` Deploying to: ${deployment.destination}`);
|
||||
}
|
||||
console.log('');
|
||||
console.log('Redirect Configuration:');
|
||||
if (deployment.redirect === undefined) {
|
||||
console.log(' No redirects are necessary');
|
||||
} else {
|
||||
console.log(` From: ${deployment.redirect.from}`);
|
||||
console.log(` To: ${deployment.redirect.to}`);
|
||||
}
|
||||
|
||||
await deployToFirebase(deployment, configPath, distDir);
|
||||
await setupRedirect(deployment);
|
||||
}
|
||||
|
||||
// Only run if the action is executed in a repository with is in the Angular org. This is in place
|
||||
// to prevent the action from actually running in a fork of a repository with this action set up.
|
||||
if (context.repo.owner === 'angular') {
|
||||
deployDocs().catch((e: Error) => {
|
||||
setFailed(e.message);
|
||||
console.error(e);
|
||||
});
|
||||
} else {
|
||||
console.warn(
|
||||
'The action was skipped as this action is only meant to run in repos belonging to the Angular organization.',
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "Node16",
|
||||
"target": "es2020",
|
||||
"lib": ["es2021", "dom"],
|
||||
"experimentalDecorators": true,
|
||||
"strict": true,
|
||||
"outDir": "../../../dist/tsc-non-bazel-out",
|
||||
"skipLibCheck": true,
|
||||
"noImplicitOverride": true,
|
||||
// TODO(ESM): Remove this when Bazel also uses the Node resolution.
|
||||
"esModuleInterop": true,
|
||||
"noImplicitReturns": true,
|
||||
"jsx": "react",
|
||||
"jsxFactory": "h",
|
||||
"jsxFragmentFactory": "Fragment"
|
||||
},
|
||||
"exclude": []
|
||||
}
|
||||
@@ -21,16 +21,16 @@ jobs:
|
||||
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'adev: preview'))
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev to ensure it continues to work
|
||||
run: yarn bazel build //adev:build
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: angular/dev-infra/github-actions/previews/pack-and-upload-artifact@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
workflow-artifact-name: 'adev-preview'
|
||||
pull-number: '${{github.event.pull_request.number}}'
|
||||
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs
|
||||
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{env.PREVIEW_PROJECT}} hosting angular-docs ${{env.PREVIEW_SITE}}
|
||||
|
||||
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: angular/dev-infra/github-actions/previews/upload-artifacts-to-firebase@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
github-token: '${{secrets.GITHUB_TOKEN}}'
|
||||
workflow-artifact-name: 'adev-preview'
|
||||
|
||||
@@ -13,9 +13,9 @@ jobs:
|
||||
assistant_to_the_branch_manager:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: angular/dev-infra/github-actions/branch-manager@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- uses: alessbell/pull-request-comment-branch@aad01d65d6982b8eacabed5e9a684cd8ceb98da6 # v1.1
|
||||
id: comment-branch
|
||||
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
with:
|
||||
# Specify repository as the PR branch might be from a fork.
|
||||
repository: ${{steps.comment-branch.outputs.head_owner}}/${{steps.comment-branch.outputs.head_repo}}
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
- uses: ./.github/actions/yarn-install
|
||||
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
bazelrc: ./.bazelrc.user
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- '[0-9]+.[0-9]+.x'
|
||||
- 'remove-aio-stuff'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
@@ -24,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
@@ -59,13 +58,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Run unit tests
|
||||
@@ -77,13 +76,13 @@ jobs:
|
||||
runs-on: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile --network-timeout 100000
|
||||
- name: Run CI tests for framework
|
||||
@@ -94,11 +93,11 @@ jobs:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev in fast mode to ensure it continues to work
|
||||
@@ -112,13 +111,13 @@ jobs:
|
||||
labels: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: echo "https://${{secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN}}:@github.com" > ${HOME}/.git_credentials
|
||||
@@ -130,7 +129,7 @@ jobs:
|
||||
labels: ubuntu-latest-4core
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
@@ -138,9 +137,9 @@ jobs:
|
||||
./packages/zone.js/node_modules
|
||||
./packages/zone.js/test/typings/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- run: |
|
||||
@@ -179,7 +178,7 @@ jobs:
|
||||
JOBS: 2
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
cache-node-modules: true
|
||||
# Checking out the pull request commit is intended here as we need to run the changed code tests.
|
||||
@@ -187,11 +186,11 @@ jobs:
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel Remote Caching
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/saucelabs@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Set up Sauce Tunnel Daemon
|
||||
run: yarn bazel run //tools/saucelabs-daemon/background-service -- $JOBS &
|
||||
env:
|
||||
@@ -207,15 +206,15 @@ jobs:
|
||||
SAUCE_TUNNEL_IDENTIFIER: angular-framework-${{ github.run_number }}
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
cache-node-modules: true
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Saucelabs Variables
|
||||
uses: angular/dev-infra/github-actions/saucelabs@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/saucelabs@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Starting Saucelabs tunnel service
|
||||
run: ./tools/saucelabs/sauce-service.sh run &
|
||||
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
|
||||
@@ -249,32 +248,22 @@ jobs:
|
||||
|
||||
adev-deploy:
|
||||
needs: [adev]
|
||||
if: needs.adev.result == 'success' && github.event_name == 'push' && github.ref_name == 'main'
|
||||
env:
|
||||
DEPLOY_PROJECT: angular-dev-site
|
||||
DEPLOY_SITE: angular-dev-site
|
||||
if: needs.adev.result == 'success' && github.event_name == 'push'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Install node modules
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Build adev to ensure it continues to work
|
||||
run: yarn bazel build //adev:build
|
||||
- name: Move generated project files into deployment directory
|
||||
run: cp -r dist/bin/adev/build adev/build
|
||||
- name: Setup firebase context
|
||||
run: |
|
||||
npx -y firebase-tools@latest target:clear --config adev/firebase.json --project ${{ env.DEPLOY_PROJECT }} hosting angular-docs
|
||||
npx -y firebase-tools@latest target:apply --config adev/firebase.json --project ${{ env.DEPLOY_PROJECT }} hosting angular-docs ${{ env.DEPLOY_SITE }}
|
||||
- name: Deploy to firebase
|
||||
uses: FirebaseExtended/action-hosting-deploy@120e124148ab7016bec2374e5050f15051255ba2 # v0.7.1
|
||||
uses: ./.github/actions/deploy-docs-site
|
||||
with:
|
||||
entryPoint: './adev'
|
||||
firebaseServiceAccount: ${{ secrets.ANGULAR_DEV_SITE_DEPLOY }}
|
||||
projectId: ${{ env.DEPLOY_PROJECT }}
|
||||
channelId: live
|
||||
serviceKey: ${{ secrets.ANGULAR_DEV_SITE_DEPLOY }}
|
||||
configPath: 'adev/firebase.json'
|
||||
distDir: 'dist/bin/adev/build/browser'
|
||||
|
||||
@@ -12,14 +12,14 @@ jobs:
|
||||
labels:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
- uses: angular/dev-infra/github-actions/commit-message-based-labels@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
post_approval_changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
- uses: angular/dev-infra/github-actions/post-approval-changes@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -13,8 +13,8 @@ jobs:
|
||||
statuses: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
- uses: angular/dev-infra/github-actions/google-internal-tests@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
run-tests-guide-url: http://go/angular-g3sync-start
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -9,6 +9,6 @@ jobs:
|
||||
status:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
- uses: angular/dev-infra/github-actions/unified-status-check@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }}
|
||||
|
||||
@@ -22,15 +22,15 @@ jobs:
|
||||
version: ['https://next.angular.io/', 'https://angular.io/']
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
./aio/node_modules
|
||||
- name: Setup Bazel
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/setup@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Setup Bazel RBE
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/bazel/configure-remote@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
- name: Install node modules in aio
|
||||
run: yarn install --frozen-lockfile --cwd aio
|
||||
- name: Run basic e2e and deployment config tests.
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Initialize environment
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
cache-node-modules: true
|
||||
node-module-directories: |
|
||||
|
||||
@@ -25,12 +25,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout code'
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: 'Run analysis'
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -47,6 +47,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: 'Upload to code-scanning'
|
||||
uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3
|
||||
uses: github/codeql-action/upload-sarif@b7cec7526559c32f1616476ff32d17ba4c59b2d6 # v3.25.5
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
|
||||
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
|
||||
with:
|
||||
# Setting `persist-credentials: false` prevents the github-action account from being the
|
||||
# account that is attempted to be used for authentication, instead the remote is set to
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
env:
|
||||
ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN: ${{ secrets.ANGULAR_CLI_BUILDS_READONLY_GITHUB_TOKEN }}
|
||||
- name: Create a PR (if necessary)
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@e6e98d32d7d4d350ecf4ec10ad9c7e75198daabd
|
||||
uses: angular/dev-infra/github-actions/create-pr-for-changes@8b117748ae8243f98d261a9731908867b8e3d876
|
||||
with:
|
||||
branch-prefix: update-cli-help
|
||||
pr-title: 'docs: update Angular CLI help [${{github.ref_name}}]'
|
||||
|
||||
@@ -24,6 +24,9 @@ export const format: FormatConfig = {
|
||||
'!packages/compiler-cli/test/compliance/test_cases/**/*.{js,ts}',
|
||||
// Ignore AIO as its pending removal.
|
||||
'!aio/**/*.{js,ts}',
|
||||
|
||||
// Ignore generated javascript file(s)
|
||||
'!.github/actions/deploy-docs-site/main.js',
|
||||
],
|
||||
},
|
||||
'buildifier': true,
|
||||
|
||||
@@ -1,3 +1,76 @@
|
||||
<a name="18.0.0-rc.2"></a>
|
||||
# 18.0.0-rc.2 (2024-05-15)
|
||||
## Deprecations
|
||||
### core
|
||||
- `@Component.interpolation` is deprecated. Use Angular's
|
||||
delimiters instead.
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [1fd63e9cff](https://github.com/angular/angular/commit/1fd63e9cff9159a8c10c35a0af43bc986e4e8e26) | refactor | deprecate `@Component.interpolation` ([#55778](https://github.com/angular/angular/pull/55778)) |
|
||||
### forms
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [61007dced0](https://github.com/angular/angular/commit/61007dced0f3396c40efcd2617c130633fb9837a) | fix | Add event for forms submitted & reset ([#55667](https://github.com/angular/angular/pull/55667)) |
|
||||
| [2e27ca9ddf](https://github.com/angular/angular/commit/2e27ca9ddfc1f3f0387cd720071e85ff46f19db6) | fix | Allow canceled async validators to emit. ([#55134](https://github.com/angular/angular/pull/55134)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c4b2f18709](https://github.com/angular/angular/commit/c4b2f18709076f8c400bd26226be37ae07e5e83d) | fix | migrate HttpClientTestingModule in test modules ([#55803](https://github.com/angular/angular/pull/55803)) |
|
||||
| [bb4a4016a9](https://github.com/angular/angular/commit/bb4a4016a9a29a9c56342ee01d866b0c8a3fb419) | fix | preserve existing properties in HttpClientModule migration ([#55777](https://github.com/angular/angular/pull/55777)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.9"></a>
|
||||
# 17.3.9 (2024-05-15)
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.0-rc.1"></a>
|
||||
# 18.0.0-rc.1 (2024-05-08)
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [91b007e58f](https://github.com/angular/angular/commit/91b007e58ffb91f7c396cbc0333a91d18f02bd27) | fix | add math elements to schema ([#55631](https://github.com/angular/angular/pull/55631)) |
|
||||
| [a040fb720a](https://github.com/angular/angular/commit/a040fb720af7db08b328a9f78511c9881f50482d) | fix | maintain multiline CSS selectors during CSS scoping ([#55509](https://github.com/angular/angular/pull/55509)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d5edfde6ee](https://github.com/angular/angular/commit/d5edfde6ee3d65bf7f938ecfeac9f30633f8731b) | fix | afterRender hooks registered outside change detection can mark views dirty ([#55623](https://github.com/angular/angular/pull/55623)) |
|
||||
| [36130b2e72](https://github.com/angular/angular/commit/36130b2e720b509e064368382eb0f7c2686154fb) | fix | don't schedule timer triggers on the server ([#55605](https://github.com/angular/angular/pull/55605)) |
|
||||
| [0510930a25](https://github.com/angular/angular/commit/0510930a257e610460c875dbbc5566fd06547814) | fix | TestBed should not override NgZone from initTestEnvironment ([#55226](https://github.com/angular/angular/pull/55226)) |
|
||||
### http
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [d9b339fdbc](https://github.com/angular/angular/commit/d9b339fdbc0f8d1e9bb7b1e4190e7d80e68542f9) | fix | resolve `withRequestsMadeViaParent` behavior with `withFetch` ([#55652](https://github.com/angular/angular/pull/55652)) |
|
||||
### migrations
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [8459ee46cb](https://github.com/angular/angular/commit/8459ee46cba7f63966c41a2fb7199ec295a91cbb) | fix | handle more cases in HttpClientModule migration ([#55640](https://github.com/angular/angular/pull/55640)) |
|
||||
### platform-browser
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [23f914f101](https://github.com/angular/angular/commit/23f914f1012545330f6a5aeed4e862bf0e66117b) | fix | Use the right namespace for mathML. ([#55622](https://github.com/angular/angular/pull/55622)) |
|
||||
### platform-server
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [e71e869112](https://github.com/angular/angular/commit/e71e869112af1c0ee7a9dd64a963ad7af14a40e2) | fix | remove event dispatch script from HTML when hydration is disabled ([#55681](https://github.com/angular/angular/pull/55681)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="17.3.8"></a>
|
||||
# 17.3.8 (2024-05-08)
|
||||
### compiler
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [c21b459ba6](https://github.com/angular/angular/commit/c21b459ba6520fd5835e23800338ac9c997fee91) | fix | add math elements to schema ([#55631](https://github.com/angular/angular/pull/55631)) ([#55645](https://github.com/angular/angular/pull/55645)) |
|
||||
### core
|
||||
| Commit | Type | Description |
|
||||
| -- | -- | -- |
|
||||
| [3818436ebc](https://github.com/angular/angular/commit/3818436ebc649267bb39b976b6b567b7f2b06a64) | fix | don't schedule timer triggers on the server ([#55605](https://github.com/angular/angular/pull/55605)) |
|
||||
|
||||
<!-- CHANGELOG SPLIT MARKER -->
|
||||
|
||||
<a name="18.0.0-rc.0"></a>
|
||||
# 18.0.0-rc.0 (2024-05-01)
|
||||
### core
|
||||
|
||||
@@ -167,10 +167,10 @@ cldr_xml_data_repository(
|
||||
# sass rules
|
||||
http_archive(
|
||||
name = "io_bazel_rules_sass",
|
||||
sha256 = "845061fad5cb42a353ac394fe6450ec9f21d337acf5b98011ef29ddcb33e3671",
|
||||
strip_prefix = "rules_sass-9f8be59f5175d0dd3438d7da994b2782299e0c2c",
|
||||
sha256 = "e50e1ca1b0a737d2c09efbbb886e0194d99caed617337a766b17c1ee4bae93f2",
|
||||
strip_prefix = "rules_sass-fcce06104e072bbebbf92c1a244ea9f8c2fc8402",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_sass/archive/9f8be59f5175d0dd3438d7da994b2782299e0c2c.zip",
|
||||
"https://github.com/bazelbuild/rules_sass/archive/fcce06104e072bbebbf92c1a244ea9f8c2fc8402.zip",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
@defer (when isBrowser) {
|
||||
<adev-progress-bar />
|
||||
<adev-progress-bar />
|
||||
}
|
||||
<button (click)="focusFirstHeading()" class="adev-skip">Skip to main content</button>
|
||||
|
||||
<div class="adev-nav"></div>
|
||||
@if (displaySecondaryNav()) {
|
||||
<adev-secondary-navigation />
|
||||
<adev-secondary-navigation />
|
||||
}
|
||||
<div class="docs-app-main-content">
|
||||
<!--
|
||||
@@ -22,9 +22,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
<router-outlet />
|
||||
<router-outlet />
|
||||
|
||||
@if (displayFooter()) {
|
||||
<footer adev-footer></footer>
|
||||
<footer adev-footer></footer>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -82,7 +82,8 @@
|
||||
>
|
||||
<a aria-label="Angular homepage" routerLink="/">
|
||||
<!-- Logo Symbol -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 223 236" width="32">
|
||||
@if(!isUwu) {
|
||||
<svg class="angular-logo" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 223 236" width="32">
|
||||
<g clip-path="url(#a)">
|
||||
<path
|
||||
fill="url(#b)"
|
||||
@@ -125,6 +126,14 @@
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
} @else {
|
||||
<img
|
||||
src="assets/images/uwu.png"
|
||||
style="width: auto; margin: 0"
|
||||
class="uwu-logo"
|
||||
alt="Angular logo"
|
||||
height="34"/>
|
||||
}
|
||||
</a>
|
||||
|
||||
<!-- Version picker for v18+ -->
|
||||
|
||||
@@ -251,6 +251,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.adev-nav-item--logo a {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.adev-close-nav {
|
||||
display: none;
|
||||
@include mq.for-phone-only {
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
isApple,
|
||||
IS_SEARCH_DIALOG_OPEN,
|
||||
} from '@angular/docs';
|
||||
import {NavigationEnd, Router, RouterLink} from '@angular/router';
|
||||
import {ActivatedRoute, NavigationEnd, Router, RouterLink} from '@angular/router';
|
||||
import {filter, map, startWith} from 'rxjs/operators';
|
||||
import {DOCS_ROUTES, REFERENCE_ROUTES, TUTORIALS_ROUTES} from '../../../routes';
|
||||
import {GITHUB, MEDIUM, X, YOUTUBE} from '../../constants/links';
|
||||
@@ -83,6 +83,9 @@ export class Navigation implements OnInit {
|
||||
readonly PRIMARY_NAV_ID = PRIMARY_NAV_ID;
|
||||
readonly SECONDARY_NAV_ID = SECONDARY_NAV_ID;
|
||||
|
||||
// We can't use the ActivatedRouter queryParams as we're outside the router outlet
|
||||
readonly isUwu = 'location' in globalThis ? location.search.includes('uwu') : false;
|
||||
|
||||
miniMenuPositions = [
|
||||
new ConnectionPositionPair(
|
||||
{originX: 'end', originY: 'center'},
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {Component, Inject} from '@angular/core';
|
||||
import {ChangeDetectionStrategy, Component, Inject} from '@angular/core';
|
||||
import {MAT_SNACK_BAR_DATA, MatSnackBarAction, MatSnackBarRef} from '@angular/material/snack-bar';
|
||||
|
||||
export interface ErrorSnackBarData {
|
||||
@@ -16,6 +16,7 @@ export interface ErrorSnackBarData {
|
||||
|
||||
@Component({
|
||||
selector: 'error-snack-bar',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
template: `
|
||||
{{ message }}
|
||||
<button
|
||||
@@ -28,8 +29,8 @@ export interface ErrorSnackBarData {
|
||||
{{ actionText }}
|
||||
</button>
|
||||
`,
|
||||
imports: [MatSnackBarAction],
|
||||
standalone: true,
|
||||
imports: [MatSnackBarAction],
|
||||
styles: `:host { display: flex; align-items: center; button { margin-left: 16px }}`,
|
||||
})
|
||||
export class ErrorSnackBar {
|
||||
|
||||
@@ -8,6 +8,7 @@ $width-breakpoint: 950px;
|
||||
container-name: embedded-editor;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
border: 1px solid var(--senary-contrast);
|
||||
}
|
||||
|
||||
// The entire thing - editor, terminal, console
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {DocContent, DocViewer} from '@angular/docs';
|
||||
import {Component, inject} from '@angular/core';
|
||||
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
|
||||
import {toSignal} from '@angular/core/rxjs-interop';
|
||||
import {ActivatedRoute} from '@angular/router';
|
||||
import {map} from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'docs-docs',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [CommonModule, DocViewer],
|
||||
styleUrls: ['./docs.component.scss'],
|
||||
|
||||
@@ -11,51 +11,61 @@
|
||||
<div class="adev-canvas"></div>
|
||||
<div class="adev-logo">
|
||||
<div class="adev-logo-wordmark">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 982 241"
|
||||
style="width: max(calc(700 * min(100vw, 2560px) / 1470), 350px); height: auto;"
|
||||
>
|
||||
<g clip-path="url(#wordmark_a)">
|
||||
<path
|
||||
fill="url(#wordmark_b)"
|
||||
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#wordmark_c)"
|
||||
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<radialGradient
|
||||
id="wordmark_c"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#FF41F8" />
|
||||
<stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
|
||||
<stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
id="wordmark_b"
|
||||
x1="0"
|
||||
x2="982"
|
||||
y1="192"
|
||||
y2="192"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#F0060B" />
|
||||
<stop offset="0" stop-color="#F0070C" />
|
||||
<stop offset=".526" stop-color="#CC26D5" />
|
||||
<stop offset="1" stop-color="#7702FF" />
|
||||
</linearGradient>
|
||||
<clipPath id="wordmark_a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
@if (!isUwu) {
|
||||
<svg
|
||||
class="angular-logo"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 982 241"
|
||||
style="width: max(calc(700 * min(100vw, 2560px) / 1470), 350px); height: auto;"
|
||||
>
|
||||
<g clip-path="url(#wordmark_a)">
|
||||
<path
|
||||
fill="url(#wordmark_b)"
|
||||
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
<path
|
||||
fill="url(#wordmark_c)"
|
||||
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.603 64.311h-44.432Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.038-7.037 7.038 0 12.847 1.145 17.348 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.746 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.619 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.01 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.091 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.815 58.815 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<radialGradient
|
||||
id="wordmark_c"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#FF41F8" />
|
||||
<stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
|
||||
<stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
id="wordmark_b"
|
||||
x1="0"
|
||||
x2="982"
|
||||
y1="192"
|
||||
y2="192"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="#F0060B" />
|
||||
<stop offset="0" stop-color="#F0070C" />
|
||||
<stop offset=".526" stop-color="#CC26D5" />
|
||||
<stop offset="1" stop-color="#7702FF" />
|
||||
</linearGradient>
|
||||
<clipPath id="wordmark_a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
} @else {
|
||||
<img
|
||||
src="assets/images/uwu.png"
|
||||
class="uwu-logo"
|
||||
alt="Angular logo"
|
||||
style="width: max(calc(700 * min(100vw, 2560px) / 1470), 350px); height: auto;"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="adev-scale">
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
inject,
|
||||
} from '@angular/core';
|
||||
import {WINDOW, shouldReduceMotion, isIos} from '@angular/docs';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {ActivatedRoute, RouterLink} from '@angular/router';
|
||||
|
||||
import {injectAsync} from '../../core/services/inject-async';
|
||||
|
||||
@@ -48,8 +48,10 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
private readonly ngZone = inject(NgZone);
|
||||
private readonly platformId = inject(PLATFORM_ID);
|
||||
private readonly window = inject(WINDOW);
|
||||
private readonly activatedRoute = inject(ActivatedRoute);
|
||||
|
||||
protected readonly tutorialFiles = TUTORIALS_HOMEPAGE_DIRECTORY;
|
||||
protected readonly isUwu = 'uwu' in this.activatedRoute.snapshot.queryParams;
|
||||
private element!: HTMLDivElement;
|
||||
private homeAnimation?: HomeAnimation;
|
||||
private intersectionObserver: IntersectionObserver | undefined;
|
||||
@@ -74,7 +76,7 @@ export default class Home implements OnInit, AfterViewInit, OnDestroy {
|
||||
// at the end of the page, and to load the embedded editor.
|
||||
this.initIntersectionObserver();
|
||||
|
||||
if (this.isWebGLAvailable() && !shouldReduceMotion()) {
|
||||
if (this.isWebGLAvailable() && !shouldReduceMotion() && !this.isUwu) {
|
||||
this.ngZone.runOutsideAngular(async () => {
|
||||
await this.loadHomeAnimation();
|
||||
});
|
||||
|
||||
@@ -679,7 +679,7 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
contentPath: 'tools/cli/end-to-end',
|
||||
},
|
||||
{
|
||||
label: 'ESBuild',
|
||||
label: 'Migrating to new build system',
|
||||
path: 'tools/cli/esbuild',
|
||||
contentPath: 'tools/cli/esbuild',
|
||||
},
|
||||
|
||||
|
After Width: | Height: | Size: 311 KiB |
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 211 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 323 KiB |
@@ -3,7 +3,7 @@
|
||||
The `output()` function declares an output in a directive or component.
|
||||
Outputs allow you to emit values to parent components.
|
||||
|
||||
HELPFUL: The `output()` function is currently in [developer preview](/guide/releases#developer-preview).
|
||||
HELPFUL: The `output()` function is currently in [developer preview](/reference/releases#developer-preview).
|
||||
|
||||
<docs-code language="ts" highlight="[[5], [8]]">
|
||||
import {Component, output} from '@angular/core';
|
||||
|
||||
@@ -111,7 +111,7 @@ its `set` or `update` methods.
|
||||
## Customizing model inputs
|
||||
|
||||
You can mark a model input as required or provide an alias in the same way as a
|
||||
[standard input](guide/signal-inputs).
|
||||
[standard input](guide/signals/inputs).
|
||||
|
||||
Model inputs do not support input transforms.
|
||||
|
||||
|
||||
@@ -28,28 +28,6 @@ platformBrowser().bootstrapModule(AppModule, {ngZone: 'noop'});
|
||||
export class AppModule {}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
The zoneless provider function can also be used with `TestBed` to help
|
||||
ensure the components under test are compatible with a Zoneless
|
||||
Angular application.
|
||||
|
||||
```typescript
|
||||
TestBed.configureTestingModule({
|
||||
providers: [provideExperimentalZonelessChangeDetection()]
|
||||
});
|
||||
|
||||
const fixture = TestBed.createComponent(MyComponent);
|
||||
await fixture.whenStable();
|
||||
```
|
||||
|
||||
To ensure tests have the most similar behavior to production code,
|
||||
avoid using `fixture.detectChanges()` when possibe. This forces
|
||||
change detection to run when Angular might otherwise have not
|
||||
scheduled change detection. Tests should ensure these notifications
|
||||
are happening and allow Angular to handle when to synchronize
|
||||
state rather than manually forcing it to happen in the test.
|
||||
|
||||
## Requirements for Zoneless compatibility
|
||||
|
||||
Angular relies on notifications from core APIs in order to determine when to run change detection and on which views.
|
||||
@@ -106,3 +84,35 @@ taskCleanup();
|
||||
The framework uses this service internally as well to prevent serialization until asynchronous tasks are complete. These include, but are not limited to,
|
||||
an ongoing Router navigation and an incomplete `HttpClient` request.
|
||||
|
||||
## Testing and Debugging
|
||||
|
||||
### Using Zoneless in `TestBed`
|
||||
|
||||
The zoneless provider function can also be used with `TestBed` to help
|
||||
ensure the components under test are compatible with a Zoneless
|
||||
Angular application.
|
||||
|
||||
```typescript
|
||||
TestBed.configureTestingModule({
|
||||
providers: [provideExperimentalZonelessChangeDetection()]
|
||||
});
|
||||
|
||||
const fixture = TestBed.createComponent(MyComponent);
|
||||
await fixture.whenStable();
|
||||
```
|
||||
|
||||
To ensure tests have the most similar behavior to production code,
|
||||
avoid using `fixture.detectChanges()` when possibe. This forces
|
||||
change detection to run when Angular might otherwise have not
|
||||
scheduled change detection. Tests should ensure these notifications
|
||||
are happening and allow Angular to handle when to synchronize
|
||||
state rather than manually forcing it to happen in the test.
|
||||
|
||||
### Debug-mode check to ensure updates are detected
|
||||
|
||||
Angular also provides an additional tool to help verify that an application is making
|
||||
updates to state in a zoneless-compatible way. `provideExperimentalCheckNoChangesForDebug`
|
||||
can be used to periodically check to ensure that no bindings have been updated
|
||||
without a notification. Angular will throw `ExpressionChangedAfterItHasBeenCheckedError`
|
||||
if there is an updated binding that would not have refreshed by the zoneless change
|
||||
detection.
|
||||
|
||||
@@ -163,3 +163,9 @@ Occasionally we introduce new APIs under the label of "Developer Preview". These
|
||||
This may be because we want to gather feedback from real applications before stabilization, or because the associated documentation or migration tooling is not fully complete.
|
||||
|
||||
The policies and practices that are described in this document do not apply to APIs marked as Developer Preview. Such APIs can change at any time, even in new patch versions of the framework. Teams should decide for themselves whether the benefits of using Developer Preview APIs are worth the risk of breaking changes outside of our normal use of semantic versioning.
|
||||
|
||||
## Experimental
|
||||
|
||||
These are APIs might not become stable at all or have significant changes before becoming stable.
|
||||
|
||||
The policies and practices that are described in this document do not apply to APIs marked as experimental. Such APIs can change at any time, even in new patch versions of the framework. Teams should decide for themselves whether the benefits of using experimental APIs are worth the risk of breaking changes outside of our normal use of semantic versioning.
|
||||
|
||||
@@ -95,7 +95,7 @@ Read about how to enable CORS for specific servers at [enable-cors.org](https://
|
||||
| Features | Details |
|
||||
|:--- |:--- |
|
||||
| [Ahead-of-Time (AOT) Compilation](tools/cli/aot-compiler) | Pre-compiles Angular component templates. |
|
||||
| [Production mode](tools/cli/deployment#production-mode-at-runtime) | Optimizes the application for the best runtime performance |
|
||||
| [Production mode](tools/cli/deployment#development-only-features) | Optimizes the application for the best runtime performance |
|
||||
| Bundling | Concatenates your many application and library files into a minimum number of deployed files. |
|
||||
| Minification | Removes excess whitespace, comments, and optional tokens. |
|
||||
| Mangling | Renames functions, classes, and variables to use shorter, arbitrary identifiers. |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Getting started with the Angular CLI's new build system
|
||||
# Migrating to the new build system
|
||||
|
||||
In v17 and higher, the new build system provides an improved way to build Angular applications. This new build system includes:
|
||||
|
||||
@@ -20,7 +20,39 @@ New applications will use this new build system by default via the `application`
|
||||
|
||||
## For existing applications
|
||||
|
||||
For existing projects, you can opt-in to use the new builder on a per-application basis with two different options.
|
||||
Both automated and manual procedures are available dependening on the requirements of the project.
|
||||
Starting with v18, the update process will ask if you would like to migrate existing applications to use the new build system via the automated migration.
|
||||
|
||||
HELPFUL: Remember to remove any CommonJS assumptions in the application server code if using SSR such as `require`, `__filename`, `__dirname`, or other constructs from the [CommonJS module scope](https://nodejs.org/api/modules.html#the-module-scope). All application code should be ESM compatible. This does not apply to third-party dependencies.
|
||||
|
||||
### Automated migration (Recommended)
|
||||
|
||||
The automated migration will adjust both the application configuration within `angular.json` as well as code and stylesheets to remove previous Webpack-specific feature usage.
|
||||
While many changes can be automated and most applications will not require any further changes, each application is unique and there may be some manual changes required.
|
||||
After the migration, please attempt a build of the application as there could be new errors that will require adjustments within the code.
|
||||
The errors will attempt to provide solutions to the problem when possible and the later sections of this guide describe some of the more common situations that you may encounter.
|
||||
When updating to Angular v18 via `ng update`, you will be asked to execute the migration.
|
||||
This migration is entirely optional for v18 and can also be run manually at anytime after an update via the following command:
|
||||
|
||||
<docs-code language="shell">
|
||||
|
||||
ng update @angular/cli --name use-application-builder
|
||||
|
||||
</docs-code>
|
||||
|
||||
The migration does the following:
|
||||
|
||||
* Converts existing `browser` or `browser-esbuild` target to `application`
|
||||
* Removes any previous SSR builders (because `application` does that now).
|
||||
* Updates configuration accordingly.
|
||||
* Merges `tsconfig.server.json` with `tsconfig.app.json` and adds the TypeScript option `"esModuleInterop": true` to ensure `express` imports are [ESM compliant](#esm-default-imports-vs-namespace-imports).
|
||||
* Updates application server code to use new bootstrapping and output directory structure.
|
||||
* Removes any Webpack-specific builder stylesheet usage such as the tilde or caret in `@import`/`url()` and updates the configuration to provide equivalent behavior
|
||||
* Converts to use the new lower dependency `@angular/build` Node.js package if no other `@angular-devkit/build-angular` usage is found.
|
||||
|
||||
### Manual migration
|
||||
|
||||
Additionally for existing projects, you can manually opt-in to use the new builder on a per-application basis with two different options.
|
||||
Both options are considered stable and fully supported by the Angular team.
|
||||
The choice of which option to use is a factor of how many changes you will need to make to migrate and what new features you would like to use in the project.
|
||||
|
||||
@@ -28,10 +60,10 @@ The choice of which option to use is a factor of how many changes you will need
|
||||
- The `application` builder covers an entire application, such as the client-side bundle, as well as optionally building a server for server-side rendering and performing build-time prerendering of static pages.
|
||||
|
||||
The `application` builder is generally preferred as it improves server-side rendered (SSR) builds, and makes it easier for client-side rendered projects to adopt SSR in the future.
|
||||
However it requires a little more migration effort, particularly for existing SSR applications.
|
||||
However it requires a little more migration effort, particularly for existing SSR applications if performed manually.
|
||||
If the `application` builder is difficult for your project to adopt, `browser-esbuild` can be an easier solution which gives most of the build performance benefits with fewer breaking changes.
|
||||
|
||||
### Using the `browser-esbuild` builder
|
||||
#### Manual migration to the compatibility builder
|
||||
|
||||
A builder named `browser-esbuild` is available within the `@angular-devkit/build-angular` package that is present in an Angular CLI generated application.
|
||||
You can try out the new build system for applications that use the `browser` builder.
|
||||
@@ -61,7 +93,7 @@ Changing the `builder` field is the only change you will need to make.
|
||||
...
|
||||
</docs-code>
|
||||
|
||||
### Using the `application` builder
|
||||
#### Manual migration to the new `application` builder
|
||||
|
||||
A builder named `application` is also available within the `@angular-devkit/build-angular` package that is present in an Angular CLI generated application.
|
||||
This builder is the default for all new applications created via `ng new`.
|
||||
@@ -117,23 +149,6 @@ The `application` builder now provides the integrated functionality for all of t
|
||||
The `ng update` process will automatically remove usages of the `@nguniversal` scope packages where some of these builders were previously located.
|
||||
The new `@angular/ssr` package will also be automatically added and used with configuration and code being adjusted during the update.
|
||||
The `@angular/ssr` package supports the `browser` builder as well as the `application` builder.
|
||||
To convert from the separate SSR builders to the integrated capabilities of the `application` builder, run the experimental `use-application-builder` migration.
|
||||
|
||||
<docs-code language="shell">
|
||||
|
||||
ng update @angular/cli --name use-application-builder
|
||||
|
||||
</docs-code>
|
||||
|
||||
The migration does the following:
|
||||
|
||||
* Converts existing `browser` or `browser-esbuild` target to `application`
|
||||
* Removes any previous SSR builders (because `application` does that now).
|
||||
* Updates configuration accordingly.
|
||||
* Merges `tsconfig.server.json` with `tsconfig.app.json` and adds the TypeScript option `"esModuleInterop": true` to ensure `express` imports are [ESM compliant](#esm-default-imports-vs-namespace-imports).
|
||||
* Updates application server code to use new bootstrapping and output directory structure.
|
||||
|
||||
HELPFUL: Remember to remove any CommonJS assumptions in the application server code such as `require`, `__filename`, `__dirname`, or other constructs from the [CommonJS module scope](https://nodejs.org/api/modules.html#the-module-scope). All application code should be ESM compatible. This does not apply to third-party dependencies.
|
||||
|
||||
## Executing a build
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ When you open the extension, you'll see two additional tabs:
|
||||
|
||||
| Tabs | Details |
|
||||
|:--- |:--- |
|
||||
| [Components](tools/devtools#components) | Lets you explore the components and directives in your application and preview or edit their state. |
|
||||
| [Profiler](tools/devtools#profiler) | Lets you profile your application and understand what the performance bottleneck is during change detection execution. |
|
||||
| [Components](tools/devtools#debug-your-application) | Lets you explore the components and directives in your application and preview or edit their state. |
|
||||
| [Profiler](tools/devtools#profile-your-application) | Lets you profile your application and understand what the performance bottleneck is during change detection execution. |
|
||||
|
||||
<img src="assets/images/guide/devtools/devtools-tabs.png" alt="A screenshot of the top of Angular DevTools illustrating two tabs in the upper-left corner, one labeled 'Components' and another labeled 'Profiler'.">
|
||||
|
||||
@@ -108,7 +108,7 @@ Interact with your application to trigger change detection and generate data Ang
|
||||
To finish recording, click the circle again to **Stop recording**.
|
||||
|
||||
You can also import an existing recording.
|
||||
Read more about this feature in the [Import recording](tools/devtools#import-recording) section.
|
||||
Read more about this feature in the [Import recording](tools/devtools#import-and-export-recordings) section.
|
||||
|
||||
### Understand your application's execution
|
||||
|
||||
@@ -170,3 +170,27 @@ Click the **Save Profile** button at the top-right of a recorded profiling sessi
|
||||
Later, import the file in the initial view of the profiler by clicking the **Choose file** input.
|
||||
|
||||
<img src="assets/images/guide/devtools/save-profile.png" alt="A screenshot of the 'Profiler' tab displaying change detection cycles. On the right side a 'Save Profile' button is visible.">
|
||||
|
||||
## Inspect your injectors
|
||||
|
||||
Note: The Injector Tree is available for Angular Applications built with version 17 or higher.
|
||||
|
||||
### View the injector hierarchy of your application
|
||||
|
||||
The **Injector Tree** tab lets you explore the structure of the Injectors configured in your application. Here you will see two trees representing the [injector hierarchy](guide/di/hierarchical-dependency-injection) of your application. One tree is your environment hierarchy, the other is your element hierarchy.
|
||||
|
||||
<img src="assets/images/guide/devtools/di-injector-tree.png" alt="A screenshot of the 'Profiler' tab displaying the injector tree tab in Angular Devtools visualizing the injector graph for an example application.">
|
||||
|
||||
### Visualize resolution paths
|
||||
|
||||
When a specific injector is selected, the path that Angular's dependency injection algorithm traverses from that injector to the root is highlighted. For element injectors, this includes highlighting the environment injectors that the dependency injection algorithm jumps to when a dependency cannot be resolved in the element hierarchy.
|
||||
|
||||
See [resolution rules](guide/di/hierarchical-dependency-injection#resolution-rules) for more details about how Angular resolves resolution paths.
|
||||
|
||||
<img src="assets/images/guide/devtools/di-injector-tree-selected.png" alt="A screenshot of the 'Profiler' tab displaying how the injector tree visualize highlights resolution paths when an injector is selected.">
|
||||
|
||||
### View injector providers
|
||||
|
||||
Clicking an injector that has configured providers will display those providers in a list on the right of the injector tree view. Here you can view the provided token and it's type.
|
||||
|
||||
<img src="assets/images/guide/devtools/di-injector-tree-providers.png" alt="A screenshot of the 'Profiler' tab displaying how providers are made visible when an injector is selected.">
|
||||
|
||||
@@ -70,11 +70,11 @@ In the **Edit** pane of your IDE:
|
||||
|
||||
1. In `app.component.ts`, in `@Component`, update the `imports` array property and add `HomeComponent`.
|
||||
|
||||
<docs-code header="Replace in src/app/app.component.ts" path="adev/src/content/tutorials/first-app/steps/03-HousingLocation/src/app/app.component.ts" visibleLines="[7,9]"/>
|
||||
<docs-code header="Replace in src/app/app.component.ts" path="adev/src/content/tutorials/first-app/steps/03-HousingLocation/src/app/app.component.ts" visibleLines="[7]"/>
|
||||
|
||||
1. In `app.component.ts`, in `@Component`, update the `template` property to include the following HTML code.
|
||||
|
||||
<docs-code header="Replace in src/app/app.component.ts" path="adev/src/content/tutorials/first-app/steps/03-HousingLocation/src/app/app.component.ts" visibleLines="[10,19]"/>
|
||||
<docs-code header="Replace in src/app/app.component.ts" path="adev/src/content/tutorials/first-app/steps/03-HousingLocation/src/app/app.component.ts" visibleLines="[8,17]"/>
|
||||
|
||||
1. Save your changes to `app.component.ts`.
|
||||
1. If `ng serve` is running, the app should update.
|
||||
@@ -87,6 +87,7 @@ In the **Edit** pane of your IDE:
|
||||
</docs-step>
|
||||
|
||||
<docs-step title="Add features to `HomeComponent`">
|
||||
|
||||
In this step you add features to `HomeComponent`.
|
||||
|
||||
In the previous step, you added the default `HomeComponent` to your app's template so its default HTML appeared in the app.
|
||||
@@ -99,7 +100,7 @@ In the **Edit** pane of your IDE:
|
||||
1. In the `first-app` directory, open `home.component.ts` in the editor.
|
||||
1. In `home.component.ts`, in `@Component`, update the `template` property with this code.
|
||||
|
||||
<docs-code header="Replace in src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/03-HousingLocation/src/app/home/home.component.ts" visibleLines="[10,17]"/>
|
||||
<docs-code header="Replace in src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/03-HousingLocation/src/app/home/home.component.ts" visibleLines="[8,15]"/>
|
||||
|
||||
1. Next, open `home.component.css` in the editor and update the content with these styles.
|
||||
|
||||
|
||||
@@ -51,11 +51,11 @@ In the **Edit** pane of your IDE:
|
||||
|
||||
1. Next update the `imports` property of the `@Component` metadata by adding `HousingLocationComponent` to the array.
|
||||
|
||||
<docs-code header="Add HousingLocationComponent to imports array in src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/04-interfaces/src/app/home/home.component.ts" visibleLines="[7,10]"/>
|
||||
<docs-code header="Add HousingLocationComponent to imports array in src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/04-interfaces/src/app/home/home.component.ts" visibleLines="[7]"/>
|
||||
|
||||
1. Now the component is ready for use in the template for the `HomeComponent`. Update the `template` property of the `@Component` metadata to include a reference to the `<app-housing-location>` tag.
|
||||
|
||||
<docs-code header="Add housing location to the component template in src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/04-interfaces/src/app/home/home.component.ts" visibleLines="[11,21]"/>
|
||||
<docs-code header="Add housing location to the component template in src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/04-interfaces/src/app/home/home.component.ts" visibleLines="[8,18]"/>
|
||||
|
||||
</docs-step>
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ This step adds the properties to the interface that your app needs to represent
|
||||
1. In the **Edit** pane of your IDE, open the `src/app/housinglocation.ts` file.
|
||||
1. In `housinglocation.ts`, replace the default content with the following code to make your new interface to match this example.
|
||||
|
||||
<docs-code header="Update src/app/housinglocation.ts to match this code" path="adev/src/content/tutorials/first-app/steps/05-inputs/src/app/housinglocation.ts"/>
|
||||
<docs-code header="Update src/app/housinglocation.ts to match this code" path="adev/src/content/tutorials/first-app/steps/05-inputs/src/app/housinglocation.ts" visibleLines="[1,10]" />
|
||||
|
||||
1. Save your changes and confirm the app does not display any errors. Correct any errors before you continue to the next step.
|
||||
|
||||
@@ -70,11 +70,11 @@ There are a few more lessons to complete before that happens.
|
||||
|
||||
1. In `src/app/home/home.component.ts`, replace the empty `export class HomeComponent {}` definition with this code to create a single instance of the new interface in the component.
|
||||
|
||||
<docs-code header="Add sample data to src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/05-inputs/src/app/home/home.component.ts" visibleLines="[27,38]"/>
|
||||
<docs-code header="Add sample data to src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/05-inputs/src/app/home/home.component.ts" visibleLines="[23,36]"/>
|
||||
|
||||
1. Confirm that your `home.component.ts` file matches like this example.
|
||||
|
||||
<docs-code header="src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/05-inputs/src/app/home/home.component.ts"/>
|
||||
<docs-code header="src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/05-inputs/src/app/home/home.component.ts" visibleLines="[1,36]" />
|
||||
|
||||
By adding the `housingLocation` property of type `HousingLocation` to the `HomeComponent` class, we're able to confirm that the data matches the description of the interface. If the data didn't satisfy the description of the interface, the IDE has enough information to give us helpful errors.
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ In the code editor:
|
||||
<docs-step title="Add the Input property">
|
||||
1. In the same file, add a property called `housingLocation` of type `HousingLocation` to the `HousingLocationComponent` class. Add an `!` after the property name and prefix it with the `@Input()` decorator:
|
||||
|
||||
<docs-code header="Import HousingLocationComponent and Input in src/app/housing-location/housing-location.component.ts" path="adev/src/content/tutorials/first-app/steps/06-property-binding/src/app/housing-location/housing-location.component.ts" visibleLines="[16,18]"/>
|
||||
<docs-code header="Import HousingLocationComponent and Input in src/app/housing-location/housing-location.component.ts" path="adev/src/content/tutorials/first-app/steps/06-property-binding/src/app/housing-location/housing-location.component.ts" visibleLines="[13,15]"/>
|
||||
|
||||
You have to add the `!` because the input is expecting the value to be passed. In this case, there is no default value. In our example application case we know that the value will be passed in - this is by design. The exclamation point is called the non-null assertion operator and it tells the TypeScript compiler that the value of this property won't be null or undefined.
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ In the code editor:
|
||||
|
||||
1. Navigate to `src/app/home/home.component.ts`
|
||||
1. In the template property of the `@Component` decorator, update the code to match the code below:
|
||||
<docs-code header="Add housingLocation property binding" path="adev/src/content/tutorials/first-app/steps/07-dynamic-template-values/src/app/home/home.component.ts" visibleLines="[21]"/>
|
||||
<docs-code header="Add housingLocation property binding" path="adev/src/content/tutorials/first-app/steps/07-dynamic-template-values/src/app/home/home.component.ts" visibleLines="[17,19]"/>
|
||||
|
||||
When adding a property binding to a component tag, we use the `[attribute] = "value"` syntax to notify Angular that the assigned value should be treated as a property from the component class and not a string value.
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ In the code editor:
|
||||
1. Navigate to `src/app/housing-location/housing-location.component.ts`
|
||||
1. In the template property of the `@Component` decorator, replace the existing HTML markup with the following code:
|
||||
|
||||
<docs-code header="Update HousingLocationComponent template" path="adev/src/content/tutorials/first-app/steps/08-ngFor/src/app/housing-location/housing-location.component.ts" visibleLines="[9,15]"/>
|
||||
<docs-code header="Update HousingLocationComponent template" path="adev/src/content/tutorials/first-app/steps/08-ngFor/src/app/housing-location/housing-location.component.ts" visibleLines="[9,20]"/>
|
||||
|
||||
In this updated template code you have used property binding to bind the `housingLocation.photo` to the `src` attribute. The `alt` attribute uses interpolation to give more context to the alt text of the image.
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ In the `HomeComponent` there is only a single housing location. In this step, yo
|
||||
|
||||
1. In `src/app/home/home.component.ts`, remove the `housingLocation` property from the `HomeComponent` class.
|
||||
1. Update the `HomeComponent` class to have a property called `housingLocationList`. Update your code to match the following code:
|
||||
<docs-code header="Add housingLocationList property" path="adev/src/content/tutorials/first-app/steps/09-services/src/app/home/home.component.ts" visibleLines="31-136"/>
|
||||
<docs-code header="Add housingLocationList property" path="adev/src/content/tutorials/first-app/steps/09-services/src/app/home/home.component.ts" visibleLines="26-131"/>
|
||||
|
||||
IMPORTANT: Do not remove the `@Component` decorator, you will update that code in an upcoming step.
|
||||
|
||||
@@ -35,7 +35,7 @@ In the `HomeComponent` there is only a single housing location. In this step, yo
|
||||
Now the app has a dataset that you can use to display the entries in the browser using the `ngFor` directive.
|
||||
|
||||
1. Update the `<app-housing-location>` tag in the template code to this:
|
||||
<docs-code header="Add ngFor to HomeComponent template" path="adev/src/content/tutorials/first-app/steps/09-services/src/app/home/home.component.ts" visibleLines="[21,24]"/>
|
||||
<docs-code header="Add ngFor to HomeComponent template" path="adev/src/content/tutorials/first-app/steps/09-services/src/app/home/home.component.ts" visibleLines="[17,22]"/>
|
||||
|
||||
Note, in the code `[housingLocation] = "housingLocation"` the `housingLocation` value now refers to the variable used in the `ngFor` directive. Before this change, it referred to the property on the `HomeComponent` class.
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ In the **Edit** pane of your IDE, in `src/app/home/home.component.ts`:
|
||||
|
||||
1. In `HomeComponent`, add the following code to inject the new service and initialize the data for the app. The `constructor` is the first function that runs when this component is created. The code in the `constructor` will assign the `housingLocationList` the value returned from the call to `getAllHousingLocations`.
|
||||
|
||||
<docs-code header="Initialize data from service in src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/10-routing/src/app/home/home.component.ts" visibleLines="[31,36]"/>
|
||||
<docs-code header="Initialize data from service in src/app/home/home.component.ts" path="adev/src/content/tutorials/first-app/steps/10-routing/src/app/home/home.component.ts" visibleLines="[28,32]"/>
|
||||
|
||||
1. Save the changes to `src/app/home/home.component.ts` and confirm your app builds without error.
|
||||
Correct any errors before you continue to the next step.
|
||||
|
||||
@@ -49,11 +49,11 @@ In this lesson, you will enable routing in your application to navigate to the d
|
||||
|
||||
1. Add `RouterModule` to the `@Component` metadata imports
|
||||
|
||||
<docs-code header="Import RouterModule in src/app/app.component.ts" path="adev/src/content/tutorials/first-app/steps/11-details-page/src/app/app.component.ts" visibleLines="[9,12]"/>
|
||||
<docs-code header="Import RouterModule in src/app/app.component.ts" path="adev/src/content/tutorials/first-app/steps/11-details-page/src/app/app.component.ts" visibleLines="[7]"/>
|
||||
|
||||
1. In the `template` property, replace the `<app-home></app-home>` tag with the `<router-outlet>` directive and add a link back to the home page. Your code should match this code:
|
||||
|
||||
<docs-code header="Add router-outlet in src/app/app.component.ts" path="adev/src/content/tutorials/first-app/steps/11-details-page/src/app/app.component.ts" visibleLines="[13,24]"/>
|
||||
<docs-code header="Add router-outlet in src/app/app.component.ts" path="adev/src/content/tutorials/first-app/steps/11-details-page/src/app/app.component.ts" visibleLines="[8,18]"/>
|
||||
|
||||
</docs-step>
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ In this case, `:id` is dynamic and will change based on how the route is request
|
||||
|
||||
1. In `src/app/housing-location/housing-location.component.ts`, add an anchor tag to the `section` element and include the `routerLink` directive:
|
||||
|
||||
<docs-code header="Add anchor with a routerLink directive to housing-location.component.ts" path="adev/src/content/tutorials/first-app/steps/12-forms/src/app/housing-location/housing-location.component.ts" visibleLines="[13,20]"/>
|
||||
<docs-code header="Add anchor with a routerLink directive to housing-location.component.ts" path="adev/src/content/tutorials/first-app/steps/12-forms/src/app/housing-location/housing-location.component.ts" visibleLines="[20]"/>
|
||||
|
||||
The `routerLink` directive enables Angular's router to create dynamic links in the application. The value assigned to the `routerLink` is an array with two entries: the static portion of the path and the dynamic data.
|
||||
|
||||
@@ -53,7 +53,7 @@ In this step, you will get the route parameter in the `DetailsComponent`. Curren
|
||||
template: `<p>details works! {{ housingLocationId }}</p>`,
|
||||
</docs-code>
|
||||
|
||||
1. Update the body of the `DetailsComponent` with the following code:
|
||||
1. Update the body of the `DetailsComponent` class with the following code:
|
||||
|
||||
<docs-code language="javascript">
|
||||
export class DetailsComponent {
|
||||
@@ -79,13 +79,13 @@ To access the data you will add a call to the `HousingService`.
|
||||
|
||||
1. Update the template code to match the following code:
|
||||
|
||||
<docs-code header="Update the DetailsComponent template in src/app/details/details.component.ts" path="adev/src/content/tutorials/first-app/steps/12-forms/src/app/details/details.component.ts" visibleLines="[11,28]"/>
|
||||
<docs-code header="Update the DetailsComponent template in src/app/details/details.component.ts" path="adev/src/content/tutorials/first-app/steps/12-forms/src/app/details/details.component.ts" visibleLines="[11,32]"/>
|
||||
|
||||
Notice that the `housingLocation` properties are being accessed with the optional chaining operator `?`. This ensures that if the `housingLocation` value is null or undefined the application doesn't crash.
|
||||
|
||||
1. Update the body of the `DetailsComponent` class to match the following code:
|
||||
|
||||
<docs-code header="Update the DetailsComponent class in src/app/details/details.component.ts" path="adev/src/content/tutorials/first-app/steps/12-forms/src/app/details/details.component.ts" visibleLines="[31,42]"/>
|
||||
<docs-code header="Update the DetailsComponent class in src/app/details/details.component.ts" path="adev/src/content/tutorials/first-app/steps/12-forms/src/app/details/details.component.ts" visibleLines="[35,44]"/>
|
||||
|
||||
Now the component has the code to display the correct information based on the selected housing location. The `constructor` now includes a call to the `HousingService` to pass the route parameter as an argument to the `getHousingLocationById` service function.
|
||||
|
||||
@@ -106,7 +106,7 @@ In a previous lesson you updated the `AppComponent` template to include a `route
|
||||
|
||||
1. Confirm that your code matches the following:
|
||||
|
||||
<docs-code header="Add routerLink to AppComponent" path="adev/src/content/tutorials/first-app/steps/12-forms/src/app/app.component.ts" visibleLines="[13,24]"/>
|
||||
<docs-code header="Add routerLink to AppComponent" path="adev/src/content/tutorials/first-app/steps/12-forms/src/app/app.component.ts" visibleLines="[8,20]"/>
|
||||
|
||||
Your code may already be up-to-date but confirm to be sure.
|
||||
</docs-step>
|
||||
|
||||
@@ -25,7 +25,7 @@ In the **Edit** pane of your IDE:
|
||||
|
||||
1. In `src/app/housing.service.ts`, inside the `HousingService` class, paste this method at the bottom of the class definition.
|
||||
|
||||
<docs-code header="Submit method in src/app/housing.service.ts" path="adev/src/content/tutorials/first-app/steps/13-search/src/app/housing.service.ts" visibleLines="[120,122]"/>
|
||||
<docs-code header="Submit method in src/app/housing.service.ts" path="adev/src/content/tutorials/first-app/steps/13-search/src/app/housing.service.ts" visibleLines="[120,124]"/>
|
||||
|
||||
1. Confirm that the app builds without error.
|
||||
Correct any errors before you continue to the next step.
|
||||
@@ -42,7 +42,7 @@ In the **Edit** pane of your IDE, in `src/app/details/details.component.ts`:
|
||||
|
||||
1. In the `DetailsComponent` decorator metadata, update the `imports` property with the following code:
|
||||
|
||||
<docs-code header="imports directive in src/app/details/details.component.ts" path="adev/src/content/tutorials/first-app/steps/13-search/src/app/details/details.component.ts" visibleLines="[10,13]"/>
|
||||
<docs-code header="imports directive in src/app/details/details.component.ts" path="adev/src/content/tutorials/first-app/steps/13-search/src/app/details/details.component.ts" visibleLines="[10]"/>
|
||||
|
||||
1. In the `DetailsComponent` class, before the `constructor()` method, add the following code to create the form object.
|
||||
|
||||
@@ -52,7 +52,7 @@ In the **Edit** pane of your IDE, in `src/app/details/details.component.ts`:
|
||||
|
||||
1. In the `DetailsComponent` class, after the `constructor()` method, add the following code to handle the **Apply now** click.
|
||||
|
||||
<docs-code header="template directive in src/app/details/details.component.ts" path="adev/src/content/tutorials/first-app/steps/13-search/src/app/details/details.component.ts" visibleLines="[64,69]"/>
|
||||
<docs-code header="template directive in src/app/details/details.component.ts" path="adev/src/content/tutorials/first-app/steps/13-search/src/app/details/details.component.ts" visibleLines="[63,69]"/>
|
||||
|
||||
This button does not exist yet - you will add it in the next step. In the above code, the `FormControl`s may return `null`. This code uses the nullish coalescing operator to default to empty string if the value is `null`.
|
||||
|
||||
@@ -67,7 +67,7 @@ In the **Edit** pane of your IDE, in `src/app/details/details.component.ts`:
|
||||
|
||||
1. In the `DetailsComponent` decorator metadata, update the `template` HTML to match the following code to add the form's markup.
|
||||
|
||||
<docs-code header="template directive in src/app/details/details.component.ts" path="adev/src/content/tutorials/first-app/steps/13-search/src/app/details/details.component.ts" visibleLines="[15,45]"/>
|
||||
<docs-code header="template directive in src/app/details/details.component.ts" path="adev/src/content/tutorials/first-app/steps/13-search/src/app/details/details.component.ts" visibleLines="[11,46]"/>
|
||||
|
||||
The template now includes an event handler `(submit)="submitApplication()"`. Angular uses parentheses syntax around the event name to define events in the template code. The code on the right hand side of the equals sign is the code that should be executed when this event is triggered. You can bind to browser events and custom events.
|
||||
|
||||
|
||||
@@ -20,13 +20,13 @@ In this step, you'll update the `HomeComponent` class to store data in a new arr
|
||||
|
||||
1. In `src/app/home/home.component.ts`, add new property to the class called `filteredLocationList`.
|
||||
|
||||
<docs-code header="Add the filtered results property" path="adev/src/content/tutorials/first-app/steps/14-http/src/app/home/home.component.ts" visibleLines="[30,33]"/>
|
||||
<docs-code header="Add the filtered results property" path="adev/src/content/tutorials/first-app/steps/14-http/src/app/home/home.component.ts" visibleLines="[30]"/>
|
||||
|
||||
The `filteredLocationList` hold the values that match the search criteria entered by the user.
|
||||
|
||||
1. The `filteredLocationList` should contain the total set of housing locations values by default when the page loads. Update the `constructor` for the `HomeComponent` to set the value.
|
||||
|
||||
<docs-code header="Set the value of filteredLocationList" path="adev/src/content/tutorials/first-app/steps/14-http/src/app/home/home.component.ts" visibleLines="[35,39]"/>
|
||||
<docs-code header="Set the value of filteredLocationList" path="adev/src/content/tutorials/first-app/steps/14-http/src/app/home/home.component.ts" visibleLines="[31,34]"/>
|
||||
|
||||
</docs-step>
|
||||
|
||||
@@ -62,7 +62,7 @@ The template has been updated to bind the `filterResults` function to the `click
|
||||
|
||||
1. Update the `HomeComponent` class to include the implementation of the `filterResults` function.
|
||||
|
||||
<docs-code header="Add the filterResults function implementation" path="adev/src/content/tutorials/first-app/steps/14-http/src/app/home/home.component.ts" visibleLines="[41,45]"/>
|
||||
<docs-code header="Add the filterResults function implementation" path="adev/src/content/tutorials/first-app/steps/14-http/src/app/home/home.component.ts" visibleLines="[35,44]"/>
|
||||
|
||||
This function uses the `String` `filter` function to compare the value of the `text` parameter against the `housingLocation.city` property. You can update this function to match against any property or multiple properties for a fun exercise.
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ The data source has been configured, the next step is to update your web app to
|
||||
|
||||
1. Update the `getAllHousingLocations` function to make a call to the web server you configured.
|
||||
|
||||
<docs-code header="" path="adev/src/content/tutorials/first-app/steps/14-http/src-final/app/housing.service.ts" visibleLines="[12,14]"/>
|
||||
<docs-code header="" path="adev/src/content/tutorials/first-app/steps/14-http/src-final/app/housing.service.ts" visibleLines="[10,13]"/>
|
||||
|
||||
The code now uses asynchronous code to make a **GET** request over HTTP.
|
||||
|
||||
@@ -170,11 +170,11 @@ The data source has been configured, the next step is to update your web app to
|
||||
|
||||
1. Update the `getHousingLocationsById` function to make a call to the web server you configured.
|
||||
|
||||
<docs-code header="" path="adev/src/content/tutorials/first-app/steps/14-http/src-final/app/housing.service.ts" visibleLines="[16,19]"/>
|
||||
<docs-code header="" path="adev/src/content/tutorials/first-app/steps/14-http/src-final/app/housing.service.ts" visibleLines="[15,18]"/>
|
||||
|
||||
1. Once all the updates are complete, your updated service should match the following code.
|
||||
|
||||
<docs-code header="Final version of housing.service.ts" path="adev/src/content/tutorials/first-app/steps/14-http/src-final/app/housing.service.ts"/>
|
||||
<docs-code header="Final version of housing.service.ts" path="adev/src/content/tutorials/first-app/steps/14-http/src-final/app/housing.service.ts" visibleLines="[1,24]" />
|
||||
|
||||
</docs-step>
|
||||
|
||||
@@ -183,7 +183,7 @@ The server is now reading data from the HTTP request but the components that rel
|
||||
|
||||
1. In `src/app/home/home.component.ts`, update the `constructor` to use the new asynchronous version of the `getAllHousingLocations` method.
|
||||
|
||||
<docs-code header="" path="adev/src/content/tutorials/first-app/steps/14-http/src-final/app/home/home.component.ts" visibleLines="[36,41]"/>
|
||||
<docs-code header="" path="adev/src/content/tutorials/first-app/steps/14-http/src-final/app/home/home.component.ts" visibleLines="[32,37]"/>
|
||||
|
||||
1. In `src/app/details/details.component.ts`, update the `constructor` to use the new asynchronous version of the `getHousingLocationById` method.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<!-- We set all theme classes to allow critters to inline the theme styles and prevent flickering -->
|
||||
<html lang="en" class="docs-dark-mode docs-light-mode">
|
||||
<head>
|
||||
@@ -24,7 +24,22 @@
|
||||
} else {
|
||||
documentClassList.add(LIGHT_MODE_CLASS_NAME);
|
||||
}
|
||||
|
||||
if(location.search.includes('uwu')) {
|
||||
documentClassList.add('uwu');
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.uwu-logo {
|
||||
display: none;
|
||||
}
|
||||
html.uwu .angular-logo {
|
||||
display: none;
|
||||
}
|
||||
html.uwu .uwu-logo {
|
||||
display: block !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<title>Angular</title>
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "17.3.7",
|
||||
"@angular/common": "17.3.7",
|
||||
"@angular/compiler": "17.3.7",
|
||||
"@angular/core": "17.3.7",
|
||||
"@angular/forms": "17.3.7",
|
||||
"@angular/platform-browser": "17.3.7",
|
||||
"@angular/platform-browser-dynamic": "17.3.7",
|
||||
"@angular/router": "17.3.7",
|
||||
"@angular/animations": "17.3.8",
|
||||
"@angular/common": "17.3.8",
|
||||
"@angular/compiler": "17.3.8",
|
||||
"@angular/core": "17.3.8",
|
||||
"@angular/forms": "17.3.8",
|
||||
"@angular/platform-browser": "17.3.8",
|
||||
"@angular/platform-browser-dynamic": "17.3.8",
|
||||
"@angular/router": "17.3.8",
|
||||
"angular": "^1.8.3",
|
||||
"angular-in-memory-web-api": "~0.17.0",
|
||||
"angular-route": "1.8.3",
|
||||
@@ -29,9 +29,9 @@
|
||||
"zone.js": "~0.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "17.3.6",
|
||||
"@angular/cli": "17.3.6",
|
||||
"@angular/compiler-cli": "17.3.7",
|
||||
"@angular-devkit/build-angular": "17.3.7",
|
||||
"@angular/cli": "17.3.7",
|
||||
"@angular/compiler-cli": "17.3.8",
|
||||
"@types/angular": "^1.8.4",
|
||||
"@types/angular-route": "^1.7.2",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
|
||||
@@ -13,23 +13,23 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "17.3.7",
|
||||
"@angular/common": "17.3.7",
|
||||
"@angular/compiler": "17.3.7",
|
||||
"@angular/core": "17.3.7",
|
||||
"@angular/forms": "17.3.7",
|
||||
"@angular/platform-browser": "17.3.7",
|
||||
"@angular/platform-browser-dynamic": "17.3.7",
|
||||
"@angular/router": "17.3.7",
|
||||
"@angular/animations": "17.3.8",
|
||||
"@angular/common": "17.3.8",
|
||||
"@angular/compiler": "17.3.8",
|
||||
"@angular/core": "17.3.8",
|
||||
"@angular/forms": "17.3.8",
|
||||
"@angular/platform-browser": "17.3.8",
|
||||
"@angular/platform-browser-dynamic": "17.3.8",
|
||||
"@angular/router": "17.3.8",
|
||||
"angular-in-memory-web-api": "~0.17.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "17.3.6",
|
||||
"@angular/cli": "17.3.6",
|
||||
"@angular/compiler-cli": "17.3.7",
|
||||
"@angular-devkit/build-angular": "17.3.7",
|
||||
"@angular/cli": "17.3.7",
|
||||
"@angular/compiler-cli": "17.3.8",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
"@types/node": "^16.11.35",
|
||||
"copyfiles": "^2.4.1",
|
||||
|
||||
@@ -13,24 +13,24 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "17.3.7",
|
||||
"@angular/common": "17.3.7",
|
||||
"@angular/compiler": "17.3.7",
|
||||
"@angular/core": "17.3.7",
|
||||
"@angular/elements": "17.3.7",
|
||||
"@angular/forms": "17.3.7",
|
||||
"@angular/platform-browser": "17.3.7",
|
||||
"@angular/platform-browser-dynamic": "17.3.7",
|
||||
"@angular/router": "17.3.7",
|
||||
"@angular/animations": "17.3.8",
|
||||
"@angular/common": "17.3.8",
|
||||
"@angular/compiler": "17.3.8",
|
||||
"@angular/core": "17.3.8",
|
||||
"@angular/elements": "17.3.8",
|
||||
"@angular/forms": "17.3.8",
|
||||
"@angular/platform-browser": "17.3.8",
|
||||
"@angular/platform-browser-dynamic": "17.3.8",
|
||||
"@angular/router": "17.3.8",
|
||||
"angular-in-memory-web-api": "~0.17.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "17.3.6",
|
||||
"@angular/cli": "17.3.6",
|
||||
"@angular/compiler-cli": "17.3.7",
|
||||
"@angular-devkit/build-angular": "17.3.7",
|
||||
"@angular/cli": "17.3.7",
|
||||
"@angular/compiler-cli": "17.3.8",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
"@types/node": "^16.11.35",
|
||||
"jasmine-core": "~5.1.0",
|
||||
|
||||
@@ -15,24 +15,24 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "17.3.7",
|
||||
"@angular/common": "17.3.7",
|
||||
"@angular/compiler": "17.3.7",
|
||||
"@angular/core": "17.3.7",
|
||||
"@angular/forms": "17.3.7",
|
||||
"@angular/localize": "17.3.7",
|
||||
"@angular/platform-browser": "17.3.7",
|
||||
"@angular/platform-browser-dynamic": "17.3.7",
|
||||
"@angular/router": "17.3.7",
|
||||
"@angular/animations": "17.3.8",
|
||||
"@angular/common": "17.3.8",
|
||||
"@angular/compiler": "17.3.8",
|
||||
"@angular/core": "17.3.8",
|
||||
"@angular/forms": "17.3.8",
|
||||
"@angular/localize": "17.3.8",
|
||||
"@angular/platform-browser": "17.3.8",
|
||||
"@angular/platform-browser-dynamic": "17.3.8",
|
||||
"@angular/router": "17.3.8",
|
||||
"angular-in-memory-web-api": "~0.17.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "17.3.6",
|
||||
"@angular/cli": "17.3.6",
|
||||
"@angular/compiler-cli": "17.3.7",
|
||||
"@angular-devkit/build-angular": "17.3.7",
|
||||
"@angular/cli": "17.3.7",
|
||||
"@angular/compiler-cli": "17.3.8",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
"@types/node": "^16.11.35",
|
||||
"jasmine-core": "~5.1.0",
|
||||
|
||||
@@ -13,24 +13,24 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "17.3.7",
|
||||
"@angular/common": "17.3.7",
|
||||
"@angular/compiler": "17.3.7",
|
||||
"@angular/core": "17.3.7",
|
||||
"@angular/forms": "17.3.7",
|
||||
"@angular/platform-browser": "17.3.7",
|
||||
"@angular/platform-browser-dynamic": "17.3.7",
|
||||
"@angular/router": "17.3.7",
|
||||
"@angular/service-worker": "17.3.7",
|
||||
"@angular/animations": "17.3.8",
|
||||
"@angular/common": "17.3.8",
|
||||
"@angular/compiler": "17.3.8",
|
||||
"@angular/core": "17.3.8",
|
||||
"@angular/forms": "17.3.8",
|
||||
"@angular/platform-browser": "17.3.8",
|
||||
"@angular/platform-browser-dynamic": "17.3.8",
|
||||
"@angular/router": "17.3.8",
|
||||
"@angular/service-worker": "17.3.8",
|
||||
"angular-in-memory-web-api": "~0.17.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "17.3.6",
|
||||
"@angular/cli": "17.3.6",
|
||||
"@angular/compiler-cli": "17.3.7",
|
||||
"@angular-devkit/build-angular": "17.3.7",
|
||||
"@angular/cli": "17.3.7",
|
||||
"@angular/compiler-cli": "17.3.8",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
"@types/node": "^16.11.35",
|
||||
"jasmine-core": "~5.1.0",
|
||||
|
||||
@@ -25,15 +25,15 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "17.3.7",
|
||||
"@angular/common": "17.3.7",
|
||||
"@angular/compiler": "17.3.7",
|
||||
"@angular/core": "17.3.7",
|
||||
"@angular/forms": "17.3.7",
|
||||
"@angular/platform-browser": "17.3.7",
|
||||
"@angular/platform-browser-dynamic": "17.3.7",
|
||||
"@angular/router": "17.3.7",
|
||||
"@angular/upgrade": "17.3.7",
|
||||
"@angular/animations": "17.3.8",
|
||||
"@angular/common": "17.3.8",
|
||||
"@angular/compiler": "17.3.8",
|
||||
"@angular/core": "17.3.8",
|
||||
"@angular/forms": "17.3.8",
|
||||
"@angular/platform-browser": "17.3.8",
|
||||
"@angular/platform-browser-dynamic": "17.3.8",
|
||||
"@angular/router": "17.3.8",
|
||||
"@angular/upgrade": "17.3.8",
|
||||
"core-js": "^3.0.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"systemjs": "~0.19.39",
|
||||
@@ -42,7 +42,7 @@
|
||||
"zone.js": "~0.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/compiler-cli": "17.3.7",
|
||||
"@angular/compiler-cli": "17.3.8",
|
||||
"@rollup/plugin-commonjs": "^25.0.0",
|
||||
"@rollup/plugin-node-resolve": "^13.2.0",
|
||||
"@types/angular": "^1.8.4",
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "17.3.7",
|
||||
"@angular/common": "17.3.7",
|
||||
"@angular/compiler": "17.3.7",
|
||||
"@angular/core": "17.3.7",
|
||||
"@angular/forms": "17.3.7",
|
||||
"@angular/platform-browser": "17.3.7",
|
||||
"@angular/platform-browser-dynamic": "17.3.7",
|
||||
"@angular/platform-server": "17.3.7",
|
||||
"@angular/router": "17.3.7",
|
||||
"@angular/ssr": "17.3.6",
|
||||
"@angular/animations": "17.3.8",
|
||||
"@angular/common": "17.3.8",
|
||||
"@angular/compiler": "17.3.8",
|
||||
"@angular/core": "17.3.8",
|
||||
"@angular/forms": "17.3.8",
|
||||
"@angular/platform-browser": "17.3.8",
|
||||
"@angular/platform-browser-dynamic": "17.3.8",
|
||||
"@angular/platform-server": "17.3.8",
|
||||
"@angular/router": "17.3.8",
|
||||
"@angular/ssr": "17.3.7",
|
||||
"angular-in-memory-web-api": "~0.17.0",
|
||||
"express": "^4.18.1",
|
||||
"rxjs": "~7.8.0",
|
||||
@@ -30,9 +30,9 @@
|
||||
"zone.js": "~0.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "17.3.6",
|
||||
"@angular/cli": "17.3.6",
|
||||
"@angular/compiler-cli": "17.3.7",
|
||||
"@angular-devkit/build-angular": "17.3.7",
|
||||
"@angular/cli": "17.3.7",
|
||||
"@angular/compiler-cli": "17.3.8",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
"@types/node": "^16.11.35",
|
||||
|
||||
@@ -19,20 +19,20 @@
|
||||
"license": "MIT",
|
||||
"repository": {},
|
||||
"dependencies": {
|
||||
"@angular/animations": "17.3.7",
|
||||
"@angular/common": "17.3.7",
|
||||
"@angular/compiler": "17.3.7",
|
||||
"@angular/core": "17.3.7",
|
||||
"@angular/elements": "17.3.7",
|
||||
"@angular/forms": "17.3.7",
|
||||
"@angular/localize": "17.3.7",
|
||||
"@angular/platform-browser": "17.3.7",
|
||||
"@angular/platform-browser-dynamic": "17.3.7",
|
||||
"@angular/platform-server": "17.3.7",
|
||||
"@angular/router": "17.3.7",
|
||||
"@angular/service-worker": "17.3.7",
|
||||
"@angular/ssr": "17.3.6",
|
||||
"@angular/upgrade": "17.3.7",
|
||||
"@angular/animations": "17.3.8",
|
||||
"@angular/common": "17.3.8",
|
||||
"@angular/compiler": "17.3.8",
|
||||
"@angular/core": "17.3.8",
|
||||
"@angular/elements": "17.3.8",
|
||||
"@angular/forms": "17.3.8",
|
||||
"@angular/localize": "17.3.8",
|
||||
"@angular/platform-browser": "17.3.8",
|
||||
"@angular/platform-browser-dynamic": "17.3.8",
|
||||
"@angular/platform-server": "17.3.8",
|
||||
"@angular/router": "17.3.8",
|
||||
"@angular/service-worker": "17.3.8",
|
||||
"@angular/ssr": "17.3.7",
|
||||
"@angular/upgrade": "17.3.8",
|
||||
"angular": "^1.8.3",
|
||||
"angular-in-memory-web-api": "~0.17.0",
|
||||
"angular-route": "1.8.3",
|
||||
@@ -45,9 +45,9 @@
|
||||
"zone.js": "~0.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "17.3.6",
|
||||
"@angular/cli": "17.3.6",
|
||||
"@angular/compiler-cli": "17.3.7",
|
||||
"@angular-devkit/build-angular": "17.3.7",
|
||||
"@angular/cli": "17.3.7",
|
||||
"@angular/compiler-cli": "17.3.8",
|
||||
"@rollup/plugin-commonjs": "^25.0.0",
|
||||
"@rollup/plugin-node-resolve": "^13.2.0",
|
||||
"@types/angular": "^1.8.4",
|
||||
@@ -57,7 +57,7 @@
|
||||
"@types/angular-route": "^1.7.2",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/jasmine": "~5.1.0",
|
||||
"@types/jquery": "3.5.29",
|
||||
"@types/jquery": "3.5.30",
|
||||
"@types/node": "^16.11.35",
|
||||
"canonical-path": "1.0.0",
|
||||
"concurrently": "^8.0.0",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"short_name": "Angular DevTools",
|
||||
"name": "Angular DevTools",
|
||||
"description": "Angular DevTools extends Chrome DevTools adding Angular specific debugging and profiling capabilities.",
|
||||
"version": "1.0.15",
|
||||
"version_name": "1.0.15",
|
||||
"version": "1.0.16",
|
||||
"version_name": "1.0.16",
|
||||
"minimum_chrome_version": "102",
|
||||
"content_security_policy": {
|
||||
"extension_pages": "script-src 'self'; object-src 'self'"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"short_name": "Angular DevTools",
|
||||
"name": "Angular DevTools",
|
||||
"description": "Angular DevTools extends Firefox DevTools adding Angular specific debugging and profiling capabilities.",
|
||||
"version": "1.0.15",
|
||||
"version": "1.0.16",
|
||||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||
"icons": {
|
||||
"16": "assets/icon16.png",
|
||||
|
||||
@@ -117,6 +117,8 @@ export const enum RuntimeErrorCode {
|
||||
// (undocumented)
|
||||
PLATFORM_NOT_FOUND = 401,
|
||||
// (undocumented)
|
||||
PROVIDED_BOTH_ZONE_AND_ZONELESS = 408,
|
||||
// (undocumented)
|
||||
PROVIDER_IN_WRONG_CONTEXT = 207,
|
||||
// (undocumented)
|
||||
PROVIDER_NOT_FOUND = -201,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
```ts
|
||||
|
||||
import { EnvironmentProviders as EnvironmentProviders_2 } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { SIGNAL } from '@angular/core/primitives/signals';
|
||||
import { SignalNode } from '@angular/core/primitives/signals';
|
||||
@@ -226,6 +227,7 @@ export interface Component extends Directive {
|
||||
changeDetection?: ChangeDetectionStrategy;
|
||||
encapsulation?: ViewEncapsulation;
|
||||
imports?: (Type<any> | ReadonlyArray<any>)[];
|
||||
// @deprecated
|
||||
interpolation?: [string, string];
|
||||
// @deprecated
|
||||
moduleId?: string;
|
||||
@@ -1365,6 +1367,13 @@ export class PlatformRef {
|
||||
// @public
|
||||
export type Predicate<T> = (value: T) => boolean;
|
||||
|
||||
// @public
|
||||
export function provideExperimentalCheckNoChangesForDebug(options: {
|
||||
interval?: number;
|
||||
useNgZoneOnStable?: boolean;
|
||||
exhaustive?: boolean;
|
||||
}): EnvironmentProviders_2;
|
||||
|
||||
// @public
|
||||
export function provideExperimentalZonelessChangeDetection(): EnvironmentProviders;
|
||||
|
||||
|
||||
@@ -5,41 +5,33 @@
|
||||
```ts
|
||||
|
||||
// @public
|
||||
export function bootstrapEarlyEventContract(field: string, container: HTMLElement, appId: string, eventTypes: string[], captureEventTypes: string[], earlyJsactionTracker?: EventContractTracker<EarlyJsactionDataContainer>): void;
|
||||
|
||||
// @public
|
||||
export function bootstrapEventContract(field: string, container: Element, appId: string, events: string[], earlyJsactionTracker?: EventContractTracker<EventContract>): void;
|
||||
export function bootstrapEarlyEventContract(field: string, container: HTMLElement, appId: string, eventTypes?: string[], captureEventTypes?: string[], earlyJsactionTracker?: EventContractTracker<EarlyJsactionDataContainer>): void;
|
||||
|
||||
// @public
|
||||
export class Dispatcher {
|
||||
constructor(getHandler?: ((eventInfoWrapper: EventInfoWrapper) => EventInfoWrapperHandler | void) | undefined, { stopPropagation, eventReplayer, }?: {
|
||||
stopPropagation?: boolean;
|
||||
constructor(dispatchDelegate: (eventInfoWrapper: EventInfoWrapper) => void, { actionResolver, eventReplayer, }?: {
|
||||
actionResolver?: ActionResolver;
|
||||
eventReplayer?: Replayer;
|
||||
});
|
||||
canDispatch(eventInfoWrapper: EventInfoWrapper): boolean;
|
||||
dispatch(eventInfo: EventInfo, isGlobalDispatch?: boolean): void;
|
||||
hasAction(name: string): boolean;
|
||||
registerEventInfoHandlers<T>(namespace: string, instance: T | null, methods: {
|
||||
[key: string]: EventInfoWrapperHandler;
|
||||
}): void;
|
||||
registerGlobalHandler(eventType: string, handler: GlobalHandler): void;
|
||||
setEventReplayer(eventReplayer: Replayer): void;
|
||||
unregisterGlobalHandler(eventType: string, handler: GlobalHandler): void;
|
||||
unregisterHandler(namespace: string, name: string): void;
|
||||
dispatch(eventInfo: EventInfo): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface EarlyJsactionDataContainer {
|
||||
// (undocumented)
|
||||
_ejsa?: EarlyJsactionData;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class EventContract implements UnrenamedEventContract {
|
||||
constructor(containerManager: EventContractContainerManager);
|
||||
constructor(containerManager: EventContractContainerManager, useActionResolver?: boolean);
|
||||
// (undocumented)
|
||||
static A11Y_CLICK_SUPPORT: boolean;
|
||||
addA11yClickSupport(): void;
|
||||
addEvent(eventType: string, prefixedEventType?: string): void;
|
||||
cleanUp(): void;
|
||||
// (undocumented)
|
||||
static CUSTOM_EVENT_SUPPORT: boolean;
|
||||
// (undocumented)
|
||||
ecaacs?: (updateEventInfoForA11yClick: typeof a11yClickLib.updateEventInfoForA11yClick, preventDefaultForA11yClick: typeof a11yClickLib.preventDefaultForA11yClick, populateClickOnlyAction: typeof a11yClickLib.populateClickOnlyAction) => void;
|
||||
ecaacs?: (updateEventInfoForA11yClick: typeof a11yClick.updateEventInfoForA11yClick, preventDefaultForA11yClick: typeof a11yClick.preventDefaultForA11yClick, populateClickOnlyAction: typeof a11yClick.populateClickOnlyAction) => void;
|
||||
ecrd(dispatcher: Dispatcher_2, restriction: Restriction): void;
|
||||
exportAddA11yClickSupport(): void;
|
||||
handler(eventType: string): EventHandler | undefined;
|
||||
|
||||
@@ -565,6 +565,13 @@ export interface FormRecord<TControl> {
|
||||
}): void;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class FormResetEvent extends ControlEvent {
|
||||
constructor(source: AbstractControl);
|
||||
// (undocumented)
|
||||
readonly source: AbstractControl;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class FormsModule {
|
||||
static withConfig(opts: {
|
||||
@@ -578,6 +585,13 @@ export class FormsModule {
|
||||
static ɵmod: i0.ɵɵNgModuleDeclaration<FormsModule, [typeof i1_2.NgModel, typeof i2_2.NgModelGroup, typeof i3_2.NgForm], never, [typeof i4_2.ɵInternalFormsSharedModule, typeof i1_2.NgModel, typeof i2_2.NgModelGroup, typeof i3_2.NgForm]>;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class FormSubmittedEvent extends ControlEvent {
|
||||
constructor(source: AbstractControl);
|
||||
// (undocumented)
|
||||
readonly source: AbstractControl;
|
||||
}
|
||||
|
||||
// @public
|
||||
export const isFormArray: (control: unknown) => control is FormArray<any>;
|
||||
|
||||
@@ -786,7 +800,7 @@ export class PatternValidator extends AbstractValidatorDirective {
|
||||
}
|
||||
|
||||
// @public
|
||||
export class PristineEvent extends ControlEvent {
|
||||
export class PristineChangeEvent extends ControlEvent {
|
||||
constructor(pristine: boolean, source: AbstractControl);
|
||||
// (undocumented)
|
||||
readonly pristine: boolean;
|
||||
@@ -880,7 +894,7 @@ export class SelectMultipleControlValueAccessor extends BuiltInControlValueAcces
|
||||
export type SetDisabledStateOption = 'whenDisabledForLegacyCode' | 'always';
|
||||
|
||||
// @public
|
||||
export class StatusEvent extends ControlEvent {
|
||||
export class StatusChangeEvent extends ControlEvent {
|
||||
constructor(status: FormControlStatus, source: AbstractControl);
|
||||
// (undocumented)
|
||||
readonly source: AbstractControl;
|
||||
@@ -889,7 +903,7 @@ export class StatusEvent extends ControlEvent {
|
||||
}
|
||||
|
||||
// @public
|
||||
export class TouchedEvent extends ControlEvent {
|
||||
export class TouchedChangeEvent extends ControlEvent {
|
||||
constructor(touched: boolean, source: AbstractControl);
|
||||
// (undocumented)
|
||||
readonly source: AbstractControl;
|
||||
|
||||
@@ -51,5 +51,12 @@
|
||||
"polyfills": 33807,
|
||||
"defer.component": 371
|
||||
}
|
||||
},
|
||||
"platform-server-hydration/browser": {
|
||||
"uncompressed": {
|
||||
"main": 207890,
|
||||
"polyfills": 33807,
|
||||
"event-dispatch-contract.min": 648
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,4 @@
|
||||
"protractor": "protractor e2e/protractor.config.js"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# Compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
/bazel-out
|
||||
|
||||
# Node
|
||||
/node_modules
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# IDEs and editors
|
||||
.idea/
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
|
||||
*.sublime-workspace
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
# Miscellaneous
|
||||
/.angular/cache
|
||||
.sass-cache/
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# event contract
|
||||
public/event-dispatch-contract.min.js
|
||||
@@ -0,0 +1,10 @@
|
||||
load("//integration:index.bzl", "ng_integration_test")
|
||||
|
||||
ng_integration_test(
|
||||
name = "test",
|
||||
setup_chromium = True,
|
||||
track_payload_paths = [
|
||||
"/browser",
|
||||
],
|
||||
track_payload_size = "platform-server-hydration",
|
||||
)
|
||||
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"cli": {
|
||||
"analytics": false,
|
||||
"cache": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"projects": {
|
||||
"hydration": {
|
||||
"projectType": "application",
|
||||
"schematics": {},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:application",
|
||||
"options": {
|
||||
"progress": false,
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"browser": "src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"assets": [
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
}
|
||||
],
|
||||
"styles": ["src/styles.css"],
|
||||
"scripts": [],
|
||||
"server": "src/main.server.ts",
|
||||
"prerender": false,
|
||||
"ssr": true
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"optimization": false,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"port": 0
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "hydration:build:production"
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "hydration:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"port": 0,
|
||||
"protractorConfig": "e2e/protractor.conf.js",
|
||||
"webdriverUpdate": false
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "hydration:serve:production"
|
||||
},
|
||||
"development": {
|
||||
"devServerTarget": "hydration:serve:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* This script copies '@angular/core/event-dispatch-contract.min.js' to the 'public' directory, ensuring it's available as an asset.
|
||||
* This is necessary to perform size checks on the distributed script.
|
||||
*/
|
||||
|
||||
import {copyFileSync} from 'node:fs';
|
||||
|
||||
copyFileSync(
|
||||
'./node_modules/@angular/core/event-dispatch-contract.min.js',
|
||||
'public/event-dispatch-contract.min.js',
|
||||
);
|
||||
@@ -0,0 +1,42 @@
|
||||
// @ts-check
|
||||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
const {SpecReporter} = require('jasmine-spec-reporter');
|
||||
|
||||
/**
|
||||
* @type { import("protractor").Config }
|
||||
*/
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: ['./src/**/*.e2e-spec.ts'],
|
||||
chromeDriver: process.env.CHROMEDRIVER_BIN,
|
||||
capabilities: {
|
||||
browserName: 'chrome',
|
||||
chromeOptions: {
|
||||
binary: process.env.CHROME_BIN,
|
||||
// See /integration/README.md#browser-tests for more info on these args
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--headless',
|
||||
'--disable-gpu',
|
||||
'--disable-dev-shm-usage',
|
||||
'--hide-scrollbars',
|
||||
'--mute-audio',
|
||||
],
|
||||
},
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:4200/',
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
print: function () {},
|
||||
},
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: require('path').join(__dirname, './tsconfig.json'),
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({spec: {displayStacktrace: true}}));
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
import {browser, by, element} from 'protractor';
|
||||
import {bootstrapClientApp, navigateTo, verifyNoBrowserErrors} from './util';
|
||||
|
||||
describe('App E2E Tests', () => {
|
||||
beforeEach(async () => {
|
||||
// Don't wait for Angular since it is not bootstrapped automatically.
|
||||
await browser.waitForAngularEnabled(false);
|
||||
|
||||
// Load the page without waiting for Angular since it is not bootstrapped automatically.
|
||||
await navigateTo('');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
// Make sure there were no client side errors.
|
||||
await verifyNoBrowserErrors();
|
||||
});
|
||||
|
||||
it('should reply click event', async () => {
|
||||
const divElement = element(by.css('#divElement'));
|
||||
expect(await divElement.getText()).toContain('click not triggered');
|
||||
|
||||
// Trigger click
|
||||
await divElement.click();
|
||||
|
||||
// Bootstrap client application
|
||||
await bootstrapClientApp();
|
||||
|
||||
expect(await divElement.getText()).toContain('click triggered');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import * as webdriver from 'selenium-webdriver';
|
||||
import {browser} from 'protractor';
|
||||
|
||||
export async function verifyNoBrowserErrors(): Promise<void> {
|
||||
const browserLog = await browser.manage().logs().get('browser');
|
||||
const errors: string[] = [];
|
||||
|
||||
for (const {message, level} of browserLog) {
|
||||
console.log('>> ' + message);
|
||||
if (level.value >= webdriver.logging.Level.INFO.value) {
|
||||
errors.push(message);
|
||||
}
|
||||
}
|
||||
|
||||
expect(errors).toEqual([]);
|
||||
}
|
||||
|
||||
export async function navigateTo(url: string): Promise<void> {
|
||||
await browser.driver.get(browser.baseUrl + url);
|
||||
}
|
||||
|
||||
export async function bootstrapClientApp(): Promise<void> {
|
||||
await browser.executeScript('doBootstrap()');
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"module": "commonjs",
|
||||
"target": "es2019",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "hydration",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build --configuration production",
|
||||
"postinstall": "node ./copy-event-dispatch-contract.mjs",
|
||||
"pretest": "ng version",
|
||||
"test": "yarn e2e",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e --configuration=production"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "file:../../dist/packages-dist/animations",
|
||||
"@angular/common": "file:../../dist/packages-dist/common",
|
||||
"@angular/compiler": "file:../../dist/packages-dist/compiler",
|
||||
"@angular/core": "file:../../dist/packages-dist/core",
|
||||
"@angular/platform-browser": "file:../../dist/packages-dist/platform-browser",
|
||||
"@angular/platform-browser-dynamic": "file:../../dist/packages-dist/platform-browser-dynamic",
|
||||
"@angular/platform-server": "file:../../dist/packages-dist/platform-server",
|
||||
"@angular/router": "file:../../dist/packages-dist/router",
|
||||
"rxjs": "file:../../node_modules/rxjs",
|
||||
"tslib": "file:../../node_modules/tslib",
|
||||
"zone.js": "file:../../dist/zone.js-dist/archive/zone.js.tgz"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "file:../../node_modules/@angular-devkit/build-angular",
|
||||
"@angular/cli": "file:../../node_modules/@angular/cli",
|
||||
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
|
||||
"@types/jasmine": "file:../../node_modules/@types/jasmine",
|
||||
"@types/node": "file:../../node_modules/@types/node",
|
||||
"jasmine-core": "3.5.0",
|
||||
"jasmine-spec-reporter": "4.2.1",
|
||||
"protractor": "file:../../node_modules/protractor",
|
||||
"ts-node": "8.3.0",
|
||||
"typescript": "file:../../node_modules/typescript"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,3 @@
|
||||
<div (click)="onClick()" id="divElement">click not triggered.</div>
|
||||
|
||||
<router-outlet />
|
||||
@@ -0,0 +1,29 @@
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {AppComponent} from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [AppComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should have the 'hydration' title`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('hydration');
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, hydration');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {RouterOutlet} from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
standalone: true,
|
||||
imports: [RouterOutlet],
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.css',
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'hydration';
|
||||
onClick = () => {
|
||||
document.querySelector('#divElement')!.textContent = 'click triggered.';
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import {mergeApplicationConfig, ApplicationConfig} from '@angular/core';
|
||||
import {provideServerRendering} from '@angular/platform-server';
|
||||
import {appConfig} from './app.config';
|
||||
|
||||
const serverConfig: ApplicationConfig = {
|
||||
providers: [provideServerRendering()],
|
||||
};
|
||||
|
||||
export const config = mergeApplicationConfig(appConfig, serverConfig);
|
||||
@@ -0,0 +1,18 @@
|
||||
import {ApplicationConfig, provideZoneChangeDetection} from '@angular/core';
|
||||
import {provideRouter} from '@angular/router';
|
||||
import {
|
||||
provideClientHydration,
|
||||
provideProtractorTestingSupport,
|
||||
withEventReplay,
|
||||
} from '@angular/platform-browser';
|
||||
|
||||
import {routes} from './app.routes';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideZoneChangeDetection({eventCoalescing: true}),
|
||||
provideRouter(routes),
|
||||
provideClientHydration(withEventReplay()),
|
||||
provideProtractorTestingSupport(),
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
import {Routes} from '@angular/router';
|
||||
|
||||
export const routes: Routes = [];
|
||||
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Hydration</title>
|
||||
<base href="/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
import {bootstrapApplication} from '@angular/platform-browser';
|
||||
import {AppComponent} from './app/app.component';
|
||||
import {config} from './app/app.config.server';
|
||||
|
||||
const bootstrap = () => bootstrapApplication(AppComponent, config);
|
||||
|
||||
export default bootstrap;
|
||||
@@ -0,0 +1,7 @@
|
||||
import {bootstrapApplication} from '@angular/platform-browser';
|
||||
import {appConfig} from './app/app.config';
|
||||
import {AppComponent} from './app/app.component';
|
||||
|
||||
(globalThis as any)['doBootstrap'] = () => {
|
||||
bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||