Merge remote-tracking branch 'en/master' into aio

# Conflicts:
#	aio/content/guide/releases.md
#	aio/content/guide/route-animations.md
#	aio/content/guide/template-syntax.md
#	aio/content/guide/testing.md
#	aio/content/guide/updating.md
#	aio/yarn.lock
This commit is contained in:
Zhicheng WANG 2020-02-07 08:15:52 +08:00
commit afb6119ae2
53 changed files with 1366 additions and 155989 deletions

View File

@ -120,25 +120,11 @@ commands:
- attach_workspace:
at: *workspace_location
# Overwrite the yarn installed in the docker container with our own version.
overwrite_yarn:
description: Overwrite yarn with our own version
steps:
- run:
name: Overwrite yarn
command: |
localYarnPath=`node ./.circleci/get-vendored-yarn-path.js`
sudo chmod a+x $localYarnPath
sudo ln -fs $localYarnPath /usr/local/bin/yarn
- run: node --version
- run: yarn --version
# Initializes the CI environment by setting up common environment variables.
init_environment:
description: Initializing environment (setting up variables, overwriting Yarn)
description: Initializing environment (setting up variables)
steps:
- run: ./.circleci/env.sh
- overwrite_yarn
- run:
# Configure git as the CircleCI `checkout` command does.
# This is needed because we only checkout on the setup job.
@ -150,6 +136,27 @@ commands:
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
git config --global gc.auto 0 || true
init_saucelabs_environment:
description: Sets up a domain that resolves to the local host.
steps:
- run:
name: Preparing environment for running tests on Saucelabs.
command: |
# For SauceLabs jobs, we set up a domain which resolves to the machine which launched
# the tunnel. We do this because devices are sometimes not able to properly resolve
# `localhost` or `127.0.0.1` through the SauceLabs tunnel. Using a domain that does not
# resolve to anything on SauceLabs VMs ensures that such requests are always resolved
# through the tunnel, and resolve to the actual tunnel host machine (i.e. the CircleCI VM).
# More context can be found in: https://github.com/angular/angular/pull/35171.
setPublicVar SAUCE_LOCALHOST_ALIAS_DOMAIN "angular-ci.local"
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
- run:
# Sets up a local domain in the machine's host file that resolves to the local
# host. This domain is helpful in Saucelabs tests where devices are not able to
# properly resolve `localhost` or `127.0.0.1` through the sauce-connect tunnel.
name: Setting up alias domain for local host.
command: echo "127.0.0.1 $SAUCE_LOCALHOST_ALIAS_DOMAIN" | sudo tee -a /etc/hosts
# Normally this would be an individual job instead of a command.
# But startup and setup time for each invidual windows job are high enough to discourage
# many small jobs, so instead we use a command for setup unless the gain becomes significant.
@ -160,10 +167,6 @@ commands:
- custom_attach_workspace
# Install Bazel pre-requisites that aren't in the preconfigured CircleCI Windows VM.
- run: ./.circleci/windows-env.ps1
- run:
# Overwrite the yarn installed in the docker container with our own version.
name: Overwrite yarn with our own version
command: ./.circleci/windows-yarn-setup.ps1
- run: node --version
- run: yarn --version
- restore_cache:
@ -313,9 +316,7 @@ jobs:
steps:
- custom_attach_workspace
- init_environment
- run:
name: Preparing environment for running tests on Saucelabs.
command: setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
- init_saucelabs_environment
- run:
name: Run Bazel tests on Saucelabs
# See /tools/saucelabs/README.md for more info
@ -337,9 +338,7 @@ jobs:
steps:
- custom_attach_workspace
- init_environment
- run:
name: Preparing environment for running tests on Saucelabs.
command: setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
- init_saucelabs_environment
- run:
name: Run Bazel tests on Saucelabs
# See /tools/saucelabs/README.md for more info
@ -621,10 +620,8 @@ jobs:
command: |
git fetch origin $CI_STABLE_BRANCH
git checkout --force origin/$CI_STABLE_BRANCH -- aio/ .yarn/ .yarnrc
# Overwrite yarn again to use the version from the checked out branch.
- overwrite_yarn
# Ignore yarn's engines check, because we checked out `aio/package.json` from the stable
# branch and there could be a node version skew, which is acceptable in this monitoring job.
# Ignore yarn's engines check, because we checked out `aio/package.json` from the stable
# branch and there could be a node version skew, which is acceptable in this monitoring job.
- run: yarn config set ignore-engines true
- run:
name: Run tests against https://angular.io/
@ -659,11 +656,7 @@ jobs:
steps:
- custom_attach_workspace
- init_environment
- run:
name: Preparing environment for running tests on Saucelabs.
command: |
setPublicVar KARMA_JS_BROWSERS $(node -e 'console.log(require("./browser-providers.conf").sauceAliases.CI_REQUIRED.join(","))')
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
- init_saucelabs_environment
- run:
name: Starting Saucelabs tunnel service
command: ./tools/saucelabs/sauce-service.sh run
@ -675,7 +668,11 @@ jobs:
# Waiting on ready ensures that we don't run tests too early without Saucelabs not being ready.
name: Waiting for Saucelabs tunnel to connect
command: ./tools/saucelabs/sauce-service.sh ready-wait
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=${KARMA_JS_BROWSERS}
- run:
name: Running tests on Saucelabs.
command: |
browsers=$(node -e 'console.log(require("./browser-providers.conf").sauceAliases.CI_REQUIRED.join(","))')
yarn karma start ./karma-js.conf.js --single-run --browsers=${browsers}
- run:
name: Stop Saucelabs tunnel service
command: ./tools/saucelabs/sauce-service.sh stop

View File

@ -65,6 +65,7 @@ setPublicVar SAUCE_TUNNEL_IDENTIFIER "angular-framework-${CIRCLE_BUILD_NUM}-${CI
# acquire CircleCI instances for too long if sauceconnect failed, we need a connect timeout.
setPublicVar SAUCE_READY_FILE_TIMEOUT 120
####################################################################################################
# Define environment variables for the `angular/components` repo unit tests job.
####################################################################################################

View File

@ -1,36 +0,0 @@
#!/usr/bin/env node
'use strict';
/**
* **Usage:**
* ```
* node get-vendored-yarn-path
* ```
*
* Returns the path to the vendored `yarn.js` script, so that it can be used for setting up yarn
* aliases/symlinks and use the local, vendored yarn script instead of a globally installed one.
*
* **Context:**
* We keep a version of yarn in the repo, at `third_party/github.com/yarnpkg/`. All CI jobs should
* use that version for consistency (and easier updates). The path to the actual `yarn.js` script,
* however, changes depending on the version (e.g. `third_party/github.com/yarnpkg/v1.21.1/...`).
*
* This script infers the correct path, so that we don't have to update the path in several places,
* when we update the version of yarn in `third_party/github.com/yarnpkg/`.
*/
const {readdirSync} = require('fs');
const {normalize} = require('path');
const yarnDownloadDir = `${__dirname}/../third_party/github.com/yarnpkg/yarn/releases/download`;
const yarnVersionSubdirs = readdirSync(yarnDownloadDir);
// Based on our current process, there should be exactly one sub-directory inside
// `vendoredYarnDownloadDir` at all times. Throw, if that is not the case.
if (yarnVersionSubdirs.length !== 1) {
throw new Error(
`Expected exactly 1 yarn version in '${yarnDownloadDir}', but found ` +
`${yarnVersionSubdirs.length}: ${yarnVersionSubdirs.join(', ')}`);
}
console.log(normalize(`${yarnDownloadDir}/${yarnVersionSubdirs[0]}/bin/yarn.js`));

View File

@ -1,14 +0,0 @@
# Use our local, vendored yarn in the global `yarn` command.
$globalYarnDir = "$HOME\AppData\Roaming\yarn"
$localYarnPath = & ${Env:ProgramFiles}\nodejs\node.exe ".\.circleci\get-vendored-yarn-path.js"
# Create a directory to put the yarn PowerShell script.
New-Item -Path "$globalYarnDir" -ItemType "directory" >$null
# Create the yarn PowerShell script (using the inferred path to the local yarn script).
Get-Content -Path ".\.circleci\windows-yarn.ps1.template" |
%{$_ -replace "{{ LOCAL_YARN_PATH_PLACEHOLDER }}", "$localYarnPath"} |
Add-Content -Path "$globalYarnDir\yarn.ps1"
# Add the directory containing the yarn PowerShell script to `PATH`.
Add-Content -Path $profile -Value ('$Env:path = "{0};" + $Env:path' -f $globalYarnDir)

View File

@ -1,15 +0,0 @@
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "{{ LOCAL_YARN_PATH_PLACEHOLDER }}" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "{{ LOCAL_YARN_PATH_PLACEHOLDER }}" $args
$ret=$LASTEXITCODE
}
exit $ret

View File

@ -978,26 +978,6 @@ groups:
- ~framework-global-approvers
# =========================================================
# Material CI
# =========================================================
material-ci:
conditions:
- >
contains_any_globs(files, [
'tools/components-repo-ci/**'
])
reviewers:
users:
- alxhub
- AndrewKushnir
- kara
- mhevery
- pkozlowski-opensource
teams:
- ~framework-global-approvers
# =========================================================
# Public API
# =========================================================

File diff suppressed because it is too large Load Diff

View File

@ -40,9 +40,6 @@ node_repositories(
},
node_version = "12.14.1",
package_json = ["//:package.json"],
# Label needs to explicitly specify the current workspace name because otherwise Bazel does
# not provide all needed data (like "workspace_root") to the repository context.
vendored_yarn = "@angular//:third_party/github.com/yarnpkg/yarn/releases/download/v1.21.1",
)
yarn_install(

View File

@ -25,23 +25,12 @@ describe('Attribute binding example', function () {
});
it('should display a blue div with a red border', function () {
expect(element.all(by.css('div')).get(4).getCssValue('border')).toEqual('2px solid rgb(212, 30, 46)');
expect(element.all(by.css('div')).get(1).getCssValue('border')).toEqual('2px solid rgb(212, 30, 46)');
});
it('should display a div with replaced classes', function () {
expect(element.all(by.css('div')).get(5).getAttribute('class')).toEqual('new-class');
});
it('should display four buttons', function() {
let redButton = element.all(by.css('button')).get(1);
let saveButton = element.all(by.css('button')).get(2);
let bigButton = element.all(by.css('button')).get(3);
let smallButton = element.all(by.css('button')).get(4);
expect(redButton.getCssValue('color')).toEqual('rgba(255, 0, 0, 1)');
expect(saveButton.getCssValue('background-color')).toEqual('rgba(0, 255, 255, 1)');
expect(bigButton.getText()).toBe('Big');
expect(smallButton.getText()).toBe('Small');
it('should display a div with many classes', function () {
expect(element.all(by.css('div')).get(1).getAttribute('class')).toContain('special');
expect(element.all(by.css('div')).get(1).getAttribute('class')).toContain('clearance');
});
});

View File

@ -27,39 +27,41 @@
<hr />
<h2>Class binding</h2>
<h2>Styling precedence</h2>
<!-- #docregion is-special -->
<h3>toggle the "special" class on/off with a property:</h3>
<div [class.special]="isSpecial">The class binding is special.</div>
<!-- #docregion basic-specificity -->
<h3>Basic specificity</h3>
<h3>binding to class.special overrides the class attribute:</h3>
<div class="special" [class.special]="!isSpecial">This one is not so special.</div>
<!-- The `class.special` binding will override any value for the `special` class in `classExpr`. -->
<div [class.special]="isSpecial" [class]="classExpr">Some text.</div>
<h3>Using the bind- syntax:</h3>
<div bind-class.special="isSpecial">This class binding is special too.</div>
<!-- #enddocregion is-special -->
<!-- The `style.color` binding will override any value for the `color` property in `styleExpr`. -->
<div [style.color]="color" [style]="styleExpr">Some text.</div>
<!-- #enddocregion basic-specificity -->
<!-- #docregion add-class -->
<h3>Add a class:</h3>
<div class="item clearance special" [class.item-clearance]="itemClearance">Add another class</div>
<!-- #enddocregion add-class -->
<!-- #docregion source-specificity -->
<h3>Source specificity</h3>
<!-- #docregion class-override -->
<h3>Overwrite all existing classes with a new class:</h3>
<div class="item clearance special" [attr.class]="resetClasses">Reset all classes at once</div>
<!-- #enddocregion class-override -->
<!-- The `class.special` template binding will override any host binding to the `special` class set by `dirWithClassBinding` or `comp-with-host-binding`.-->
<comp-with-host-binding [class.special]="isSpecial" dirWithClassBinding>Some text.</comp-with-host-binding>
<hr />
<!-- The `style.color` template binding will override any host binding to the `color` property set by `dirWithStyleBinding` or `comp-with-host-binding`. -->
<comp-with-host-binding [style.color]="color" dirWithStyleBinding>Some text.</comp-with-host-binding>
<!-- #enddocregion source-specificity -->
<h2>Style binding</h2>
<!-- #docregion dynamic-priority -->
<h3>Dynamic vs static</h3>
<!-- If `classExpr` has a value for the `special` class, this value will override the `class="special"` below -->
<div class="special" [class]="classExpr">Some text.</div>
<!-- If `styleExpr` has a value for the `color` property, this value will override the `style="color: blue"` below -->
<div style="color: blue" [style]="styleExpr">Some text.</div>
<!-- #enddocregion dynamic-priority -->
<!-- #docregion style-delegation -->
<comp-with-host-binding dirWithHostBinding></comp-with-host-binding>
<!-- #enddocregion style-delegation -->
<!-- #docregion style-binding-->
<button [style.color]="isSpecial ? 'red': 'green'">Red</button>
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>
<!-- #enddocregion style-binding -->
<!-- #docregion style-binding-condition-->
<button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button>
<button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>
<!-- #enddocregion style-binding-condition-->

View File

@ -8,8 +8,8 @@ import { Component } from '@angular/core';
export class AppComponent {
actionName = 'Go for it';
isSpecial = true;
itemClearance = true;
resetClasses = 'new-class';
canSave = true;
classExpr = 'special clearance';
styleExpr = 'color: red';
color = 'blue';
}

View File

@ -3,11 +3,13 @@ import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { CompWithHostBindingComponent } from './comp-with-host-binding.component';
@NgModule({
declarations: [
AppComponent
AppComponent,
CompWithHostBindingComponent
],
imports: [
BrowserModule

View File

@ -0,0 +1,16 @@
import { Component } from '@angular/core';
@Component({
selector: 'comp-with-host-binding',
template: 'I am a component!',
host: {
'[class.special]': 'isSpecial',
'[style.color]': 'color',
'[style.width]': 'width'
}
})
export class CompWithHostBindingComponent {
isSpecial = false;
color = 'green';
width = '200px';
}

View File

@ -17,6 +17,23 @@ If you're still seeing the errors, they are not specific to Ivy. In this case, y
If the errors are gone, switch back to Ivy by removing the changes to the `tsconfig.json` and review the list of expected changes below.
{@a payload-size-debugging}
### Payload size debugging
If you notice that the size of your application's main bundle has increased with Ivy, you may want to check the following:
1. Verify that the components and `NgModules` that you want to be lazy loaded are only imported in lazy modules.
Anything that you import outside lazy modules can end up in the main bundle.
See more details in the original issue [here](https://github.com/angular/angular-cli/issues/16146#issuecomment-557559287).
1. Check that imported libraries have been marked side-effect-free.
If your app imports from shared libraries that are meant to be free from side effects, add "sideEffects": false to their `package.json`.
This will ensure that the libraries will be properly tree-shaken if they are imported but not directly referenced.
See more details in the original issue [here](https://github.com/angular/angular-cli/issues/16799#issuecomment-580912090).
1. Projects not using Angular CLI will see a significant size regression unless they update their minifier settings and set compile-time constants `ngDevMode`, `ngI18nClosureMode` and `ngJitMode` to `false` (for Terser, please set these to `false` via [`global_defs` config option](https://terser.org/docs/api-reference.html#conditional-compilation)).
Please note that these constants are not meant to be used by 3rd party library or application code as they are not part of our public api surface and might change in the future.
{@a common-changes}
### Changes you may see
@ -27,6 +44,8 @@ If the errors are gone, switch back to Ivy by removing the changes to the `tscon
* Unbound inputs for directives (e.g. name in `<my-comp name="">`) are now set upon creation of the view, before change detection runs (previously, all inputs were set during change detection).
* Static attributes set directly in the HTML of a template will override any conflicting host attributes set by directives or components (previously, static host attributes set by directives / components would override static template attributes if conflicting).
{@a less-common-changes}
### Less common changes
@ -62,4 +81,4 @@ If the errors are gone, switch back to Ivy by removing the changes to the `tscon
* `DebugElement.classes` returns `undefined` for classes that were added and then subsequently removed (previously, classes added and later removed would have a value of `false`).
* If selecting the native `<option>` element in a `<select>` where the `<option>`s are created via `*ngFor`, use the `[selected]` property of an `<option>` instead of binding to the `[value]` property of the `<select>` element (previously, you could bind to either.) [details](guide/ivy-compatibility-examples#select-value-binding)
* If selecting the native `<option>` element in a `<select>` where the `<option>`s are created via `*ngFor`, use the `[selected]` property of an `<option>` instead of binding to the `[value]` property of the `<select>` element (previously, you could bind to either.) [details](guide/ivy-compatibility-examples#select-value-binding)

View File

@ -115,6 +115,14 @@ We work toward a regular schedule of releases, so that you can plan and coordina
我们会定期发布新版本,以便随着 Angular 的不断演进,你可以提前计划并协调这些升级工作。
<div class="alert is-helpful">
Disclaimer: Dates are offered as general guidance and will be adjusted by us when necessary to ensure delivery of a high-quality platform.
免责条款:这些日期仅供参考,如有必要,我们会对其进行调整,以确保提供高质量的平台。
</div>
In general, you can expect the following release cycle:
通常,你可以期待下列发布周期:
@ -135,35 +143,6 @@ This cadence of releases gives you access to new features as soon as they are re
这种发布节奏能让你尽快用上已就绪的新特性,同时,为生产环境下的用户维护本平台的稳定性和可靠性。
{@a schedule}
## Release schedule
## 发布计划
<div class="alert is-helpful">
Disclaimer: The dates are offered as general guidance and may be adjusted by us when necessary to ensure delivery of a high-quality platform.
免责声明:这些日期只是作为一般性的指导,在必要时我们会进行调整,以确保始终提供高质量的平台。
</div>
The following table contains our current target release dates for the next two major versions of Angular:
下表中包含 Angular 接下来两个主版本的目标发布日期:
Date | Stable Release | Compatibility
---------------------- | -------------- | -------------
日期 | 稳定版 | 兼容性
2019 年 10/11 月 | 9.0.0 | ^8.0.0
2020 年 5 月 | 10.0.0 | ^9.0.0
Compatibility note: The primary goal of the backward compatibility promise is to ensure that changes in the core framework and tooling don't break the existing ecosystem of components and applications and don't put undue upgrade/migration burden on Angular application and component authors.
兼容性说明:向后兼容性承诺的主要目标是确保在核心框架和核心工具中的变化不会破坏现有组件和应用的生态系统,并且不要给 Angular 应用和组件的开发者带来额外的升级/迁移负担。
{@a lts}
{@a support}
## Support policy and schedule
@ -229,9 +208,9 @@ To help ensure that you have sufficient time and a clear path to update, this is
** 宣布弃用:** 我们会在[变更记录](https://github.com/angular/angular/blob/master/CHANGELOG.md "Angular change log")中宣布要弃用的那些 API 和特性。启用的 API 在[文档](api?status=deprecated)中会显示成带~~删除线~~的样式。当我们宣布一项弃用时,我们还会宣布一个建议的升级路径。为便于查找,我们在[弃用列表](guide/deprecations)中包含一个关于弃用 API 和特性的汇总表。
* **Deprecation period:** When an API or a feature is deprecated, it will still be present in the [next two major releases](#schedule). After that, deprecated APIs and features will be candidates for removal. A deprecation can be announced in any release, but the removal of a deprecated API or feature will happen only in major release. Until a deprecated API or feature is removed, it will be maintained according to the LTS support policy, meaning that only critical and security issues will be fixed.
* **Deprecation period:** When an API or a feature is deprecated, it will still be present in the next two major releases. After that, deprecated APIs and features will be candidates for removal. A deprecation can be announced in any release, but the removal of a deprecated API or feature will happen only in major release. Until a deprecated API or feature is removed, it will be maintained according to the LTS support policy, meaning that only critical and security issues will be fixed.
**弃用阶段:** 当 API 或特性已弃用时,它在[接下来的两个主版本](#schedule)中仍然会存在。再往后,弃用的 API 和特性将会进入候选弃用状态。可能会在任何一次发布中宣布弃用,但是只会在主版本中移除已弃用的 API 或特性。除非已弃用的 API 或特性已被移除,否则我们仍然会根据 LTS 支持策略来维护它,也就是说,只会修复严重问题和安全问题。
**弃用阶段:** 当 API 或特性已弃用时,它在接下来的两个主版本中仍然会存在。再往后,弃用的 API 和特性将会进入候选弃用状态。可能会在任何一次发布中宣布弃用,但是只会在主版本中移除已弃用的 API 或特性。除非已弃用的 API 或特性已被移除,否则我们仍然会根据 LTS 支持策略来维护它,也就是说,只会修复严重问题和安全问题。
* **npm dependencies:** We only make npm dependency updates that require changes to your apps in a major release.
In minor releases, we update peer dependencies by expanding the supported versions, but we do not require projects to update these dependencies until a future major version. This means that during minor Angular releases, npm dependency updates within Angular applications and libraries are optional.

View File

@ -194,7 +194,7 @@ Let's assume that we are routing from the *Home => About*.
我们假设正在从 *Home* 转场到 *About*`Home => About`
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="query" language="typescript"></code-example>
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts (Continuation from above)" region="query" language="typescript"></code-example>
The animation code does the following after styling the views:

View File

@ -208,7 +208,7 @@ Other notable differences from JavaScript syntax include:
* New [template expression operators](guide/template-syntax#expression-operators), such as `|`, `?.` and `!`
新的[模板表达式运算符](guide/template-syntax#expression-operators),例如`|``?.``!`
新的[模板表达式运算符](guide/template-syntax#expression-operators),例如 `|``?.``!`
### Expression context
@ -348,7 +348,7 @@ In Angular terms, an idempotent expression always returns
*exactly the same thing* until one of its dependent values changes.
[幂等](https://en.wikipedia.org/wiki/Idempotence)的表达式是最理想的,因为它没有副作用,并且可以提高 Angular 的变更检测性能。
用Angular术语来说幂等表达式总会返回*完全相同的东西*,除非其依赖值之一发生了变化。
Angular 术语来说,幂等表达式总会返回*完全相同的东西*,除非其依赖值之一发生了变化。
Dependent values should not change during a single turn of the event loop.
If an idempotent expression returns a string or a number, it returns the same string or number when called twice in a row. If the expression returns an object, including an `array`, it returns the same object *reference* when called twice in a row.
@ -754,7 +754,7 @@ For more information, see the [MDN Interfaces documentation](https://developer.m
Comparing the [`<td>` attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) attributes to the [`<td>` properties](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) provides a helpful example for differentiation.
In particular, you can navigate from the attributes page to the properties via "DOM interface" link, and navigate the inheritance hierarchy up to `HTMLTableCellElement`.
欲知详情,参见 [MDN接口文档](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces),其中包含所有标准 DOM 元素及其 Property 的 API 文档。
欲知详情,参见 [MDN 接口文档](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces),其中包含所有标准 DOM 元素及其 Property 的 API 文档。
[`<td>` Attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) 与 [`<td>` Property](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) 之间的比较是一个很有用的例子。
特别是,您可以通过 “DOM 接口” 链接从 Attribute 页面导航到 Property 页面,并在继承层次中导航到 `HTMLTableCellElement`
@ -1117,7 +1117,7 @@ binding the `src` property of an image element to a component's `itemImageUrl` p
Here's an example of binding to the `colSpan` property. Notice that it's not `colspan`,
which is the attribute, spelled with a lowercase `s`.
这是绑定到 `colSpan` Property 的示例。请注意,它不是 `colspan`,后者是 Attribute用小写的s拼写。
这是绑定到 `colSpan` Property 的示例。请注意,它不是 `colspan`,后者是 Attribute用小写的 s 拼写。
<code-example path="property-binding/src/app/app.component.html" region="colSpan" header="src/app/app.component.html"></code-example>
@ -1549,58 +1549,123 @@ Instead, you'd use property binding and write it like this:
### 类绑定
Here's how to set the `class` attribute without a binding in plain HTML:
Add and remove CSS class names from an element's `class` attribute with
a **class binding**.
使用**类绑定**可以从元素的 `class` 属性中添加和删除 CSS 类名称。
Here's how to set the attribute without binding in plain HTML:
下面是在普通 HTML 中不用绑定来设置 Attribute 的方法:
下面是在普通 HTML 中不用绑定来设置 `class` Attribute 的方法:
```html
<!-- standard class attribute setting -->
<div class="item clearance special">Item clearance special</div>
<div class="foo bar">Some text</div>
```
Class binding syntax resembles property binding, but instead of an element property between brackets, start with the prefix `class`,
optionally followed by a dot (`.`) and the name of a CSS class: `[class.class-name]`.
You can also add and remove CSS class names from an element's `class` attribute with a **class binding**.
类绑定语法类似于 Property 绑定,但其括号之间不是元素的 Property而是由前缀 `class`、点(`.`)和 CSS 类名(点和 CSS 类名可选)组成 `[class.class-name]` `[class.class-name]`
你还可以使用**类绑定**来为一个元素添加和移除 CSS 类。
To create a single class binding, start with the prefix `class` followed by a dot (`.`) and the name of the CSS class (for example, `[class.foo]="hasFoo"`).
Angular adds the class when the bound expression is truthy, and it removes the class when the expression is falsy (with the exception of `undefined`, see [styling delegation](#styling-delegation)).
要创建单个类的绑定,请使用 `class` 前缀,紧跟一个点(`.`),再跟上 CSS 类名,比如 `[class.foo]="hasFoo"`
当绑定表达式为真值的时候Angular 就会加上这个类,为假值则会移除,但 `undefined` 是假值中的例外,参见[样式委派](#styling-delegation) 部分。
To create a binding to multiple classes, use a generic `[class]` binding without the dot (for example, `[class]="classExpr"`).
The expression can be a space-delimited string of class names, or you can format it as an object with class names as the keys and truthy/falsy expressions as the values.
With object format, Angular will add a class only if its associated value is truthy.
要想创建多个类的绑定,请使用通用的 `[class]` 形式来绑定类,而不要带点,比如 `[class]="classExpr"`
该表达式可以是空格分隔的类名字符串,或者用一个以类名为键、真假值表达式为值的对象。
当使用对象格式时Angular 只会加上那些相关的值为真的类名。
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
Updating the property without changing object identity will have no effect.
一定要注意,在对象型表达式中(如 `object``Array``Map``Set` 等),当这个类列表改变时,对象的引用也必须修改。仅仅修改其属性而不修改对象引用是无法生效的。
If there are multiple bindings to the same class name, conflicts are resolved using [styling precedence](#styling-precedence).
如果有多处绑定到了同一个类名,出现的冲突将根据[样式的优先级规则](#styling-precedence)进行解决。
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="15%">
</col>
<col width="20%">
</col>
<col width="35%">
</col>
<col width="30%">
</col>
<tr>
<th>
Binding Type
</th>
<th>
Syntax
</th>
<th>
Input Type
</th>
<th>
Example Input Values
</th>
</tr>
<tr>
<th>
绑定类型
</th>
<th>
语法
</th>
<th>
输入类型
</th>
<th>
输入值范例
</th>
</tr>
<tr>
<td>Single class binding</td>
<td><code>[class.foo]="hasFoo"</code></td>
<td><code>boolean | undefined | null</code></td>
<td><code>true</code>, <code>false</code></td>
</tr>
<tr>
<td>单个类绑定</td>
<td><code>[class.foo]="hasFoo"</code></td>
<td><code>boolean | undefined | null</code></td>
<td><code>true</code>, <code>false</code></td>
</tr>
<tr>
<td rowspan=3>Multi-class binding</td>
<td rowspan=3><code>[class]="classExpr"</code></td>
<td><code>string</code></td>
<td><code>"my-class-1 my-class-2 my-class-3"</code></td>
</tr>
<tr>
<td rowspan=3>多个类绑定</td>
<td rowspan=3><code>[class]="classExpr"</code></td>
<td><code>string</code></td>
<td><code>"my-class-1 my-class-2 my-class-3"</code></td>
</tr>
<tr>
<td><code>{[key: string]: boolean | undefined | null}</code></td>
<td><code>{foo: true, bar: false}</code></td>
</tr>
<tr>
<td><code>Array</code><<code>string</code>></td>
<td><code>['foo', 'bar']</code></td>
</tr>
</table>
You can replace that with a binding to a string of the desired class names; this is an all-or-nothing, replacement binding.
可以把它改写为绑定到所需 CSS 类名的绑定;这是一个或者全有或者全无的替换型绑定。
(译注:即当 resetClasses 有值时 class 这个 attribute 设置的内容会被完全覆盖)
<code-example path="attribute-binding/src/app/app.component.html" region="class-override" header="src/app/app.component.html"></code-example>
You can also add a class to an element without overwriting the classes already on the element:
您还可以将一个类添加到元素上,而不会覆盖该元素上已经存在的类:
<code-example path="attribute-binding/src/app/app.component.html" region="add-class" header="src/app/app.component.html"></code-example>
Finally, you can bind to a specific class name.
Angular adds the class when the template expression evaluates to truthy.
It removes the class when the expression is falsy.
最后,可以绑定到特定的类名。
当模板表达式的求值结果是真值时Angular 会添加这个类,反之则移除它。
<code-example path="attribute-binding/src/app/app.component.html" region="is-special" header="src/app/app.component.html"></code-example>
While this technique is suitable for toggling a single class name,
consider the [`NgClass`](guide/template-syntax#ngClass) directive when
managing multiple class names at the same time.
The [NgClass](#ngclass) directive can be used as an alternative to direct `[class]` bindings.
However, using the above class binding syntax without `NgClass` is preferred because due to improvements in class binding in Angular, `NgClass` no longer provides significant value, and might eventually be removed in the future.
尽管此技术适用于切换单个类名,但在需要同时管理多个类名时请考虑使用 [`NgClass`](guide/template-syntax#ngClass) 指令。
@ -1611,32 +1676,26 @@ managing multiple class names at the same time.
### 样式绑定
You can set inline styles with a **style binding**.
Here's how to set the `style` attribute without a binding in plain HTML:
通过**样式绑定**,可以设置内联样式。
下面演示了如何不通过绑定在普通 HTML 中设置 `style` 属性:
Style binding syntax resembles property binding.
Instead of an element property between brackets, start with the prefix `style`,
followed by a dot (`.`) and the name of a CSS style property: `[style.style-property]`.
```html
<!-- standard style attribute setting -->
<div style="color: blue">Some text</div>
```
样式绑定的语法与属性绑定类似。
但方括号中的部分不是元素的属性名,而由**`style`**前缀,一个点 (`.`)和 CSS 样式的属性名组成。
形如:`[style.style-property]`
You can also set styles dynamically with a **style binding**.
<code-example path="attribute-binding/src/app/app.component.html" region="style-binding" header="src/app/app.component.html"></code-example>
你还可以通过**样式绑定**来动态设置样式。
Some style binding styles have a unit extension.
The following example conditionally sets the font size in “em” and “%” units.
有些样式绑定中的样式带有单位。在这里,以根据条件用 “em” 和 “%” 来设置字体大小的单位。
<code-example path="attribute-binding/src/app/app.component.html" region="style-binding-condition" header="src/app/app.component.html"></code-example>
This technique is suitable for setting a single style, but consider
the [`NgStyle`](guide/template-syntax#ngStyle) directive when setting several inline styles at the same time.
此技术适用于设置单个样式,当需要同时设置多个内联样式时请考虑使用 [`NgStyle`](guide/template-syntax#ngStyle) 指令。
To create a single style binding, start with the prefix `style` followed by a dot (`.`) and the name of the CSS style property (for example, `[style.width]="width"`).
The property will be set to the value of the bound expression, which is normally a string.
Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
要想创建单个样式的绑定,请以 `style` 前缀开头,紧跟一个点(`.`),再跟着 CSS 样式的属性名,比如 `[style.width]="width"`
该属性将会被设置为绑定表达式的值,该值通常为字符串。
不过你还可以添加一个单位表达式,比如 `em``%`,这时候该值就要是一个 `number` 类型。
<div class="alert is-helpful">
@ -1649,8 +1708,270 @@ Note that a _style property_ name can be written in either
</div>
If there are multiple styles you'd like to toggle, you can bind to the `[style]` property directly without the dot (for example, `[style]="styleExpr"`).
The expression attached to the `[style]` binding is most often a string list of styles like `"width: 100px; height: 100px;"`.
如果要切换多个样式,你可以直接绑定到 `[style]` 属性而不用点(比如, `[style]="styleExpr"`)。赋给 `[style]` 的绑定表达式通常是一系列样式组成的字符串,比如 `"width: 100px; height: 100px;"`
You can also format the expression as an object with style names as the keys and style values as the values, like `{width: '100px', height: '100px'}`.
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
Updating the property without changing object identity will have no effect.
你也可以把该表达式格式化成一个以样式名为键、以样式值为值的对象,比如 `{width: '100px', height: '100px'}` 。一定要注意,对于任何对象型的表达式( 如 `object` `Array` `Map` `Set` 等),当这个样式列表改变时,对象的引用也必须修改。仅仅修改其属性而不修改对象引用是无法生效的。。
If there are multiple bindings to the same style property, conflicts are resolved using [styling precedence rules](#styling-precedence).
如果有多处绑定了同一个样式属性,则会使用[样式的优先级规则](#styling-precedence)来解决冲突。
<style>
td, th {vertical-align: top}
</style>
<table width="100%">
<col width="15%">
</col>
<col width="20%">
</col>
<col width="35%">
</col>
<col width="30%">
</col>
<tr>
<th>
Binding Type
</th>
<th>
Syntax
</th>
<th>
Input Type
</th>
<th>
Example Input Values
</th>
</tr>
<tr>
<th>
绑定类型
</th>
<th>
语法
</th>
<th>
输入类型
</th>
<th>
输入值范例
</th>
</tr>
<tr>
<td>Single style binding</td>
<td><code>[style.width]="width"</code></td>
<td><code>string | undefined | null</code></td>
<td><code>"100px"</code></td>
</tr>
<tr>
<td>单一样式绑定</td>
<td><code>[style.width]="width"</code></td>
<td><code>string | undefined | null</code></td>
<td><code>"100px"</code></td>
</tr>
<tr>
<tr>
<td>Single style binding with units</td>
<td><code>[style.width.px]="width"</code></td>
<td><code>number | undefined | null</code></td>
<td><code>100</code></td>
</tr>
<tr>
<td>带单位的单一样式绑定</td>
<td><code>[style.width.px]="width"</code></td>
<td><code>number | undefined | null</code></td>
<td><code>100</code></td>
</tr>
<tr>
<td rowspan=3>Multi-style binding</td>
<td rowspan=3><code>[style]="styleExpr"</code></td>
<td><code>string</code></td>
<td><code>"width: 100px; height: 100px"</code></td>
</tr>
<tr>
<td rowspan=3>多个样式绑定</td>
<td rowspan=3><code>[style]="styleExpr"</code></td>
<td><code>string</code></td>
<td><code>"width: 100px; height: 100px"</code></td>
</tr>
<tr>
<td><code>{[key: string]: string | undefined | null}</code></td>
<td><code>{width: '100px', height: '100px'}</code></td>
</tr>
<tr>
<td><code>Array</code><<code>string</code>></td>
<td><code>['width', '100px']</code></td>
</tr>
</table>
The [NgStyle](#ngstyle) directive can be used as an alternative to direct `[style]` bindings.
However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future.
[NgStyle](#ngstyle) 指令可以作为 `[style]` 绑定的替代指令。但是,应该把上面这种 `[style]` 样式绑定语法作为首选,因为随着 Angular 中样式绑定的改进,`NgStyle` 将不再提供重要的价值,并最终在未来的某个版本中删除。
<hr/>
{@a styling-precedence}
### Styling Precedence
### 样式的优先级规则
A single HTML element can have its CSS class list and style values bound to a multiple sources (for example, host bindings from multiple directives).
一个 HTML 元素可以把它的 CSS 类列表和样式值绑定到多个来源(例如,来自多个指令的宿主 `host` 绑定)。
When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element.
当对同一个类名或样式属性存在多个绑定时Angular 会使用一组优先级规则来解决冲突,并确定最终哪些类或样式会应用到该元素中。
<div class="alert is-helpful">
<h4>Styling precedence (highest to lowest)</h4>
<h4>样式的优先级规则(从高到低)</h4>
1. Template bindings
模板绑定
1. Property binding (for example, `<div [class.foo]="hasFoo">` or `<div [style.color]="color">`)
属性绑定(例如 `<div [class.foo]="hasFoo">``<div [style.color]="color">`
1. Map binding (for example, `<div [class]="classExpr">` or `<div [style]="styleExpr">`)
Map 绑定(例如,`<div [class]="classExpr">``<div [style]="styleExpr">`
1. Static value (for example, `<div class="foo">` or `<div style="color: blue">`)
静态值(例如 `<div class="foo">``<div style="color: blue">`
1. Directive host bindings
指令宿主绑定
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
属性绑定(例如,`host: {'[class.foo]': 'hasFoo'}``host: {'[style.color]': 'color'}`
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
Map 绑定(例如, `host: {'[class]': 'classExpr'}` 或者 `host: {'[style]': 'styleExpr'}`
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
静态值(例如, `host: {'class': 'foo'}``host: {'style': 'color: blue'}`
1. Component host bindings
组件宿主绑定
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
属性绑定(例如, `host: {'[class.foo]': 'hasFoo'}``host: {'[style.color]': 'color'}`
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
Map 绑定(例如, `host: {'[class]': 'classExpr'}` 或者 `host: {'[style]': 'styleExpr'}`
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
静态值(例如, `host: {'class': 'foo'}``host: {'style': 'color: blue'}`
</div>
The more specific a class or style binding is, the higher its precedence.
某个类或样式绑定越具体,它的优先级就越高。
A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take precedence over a generic `[style]` binding.
对具体类(例如 `[class.foo]` )的绑定优先于一般化的 `[class]` 绑定,对具体样式(例如 `[style.bar]` )的绑定优先于一般化的 `[style]` 绑定。
<code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example>
Specificity rules also apply when it comes to bindings that originate from different sources.
It's possible for an element to have bindings in the template where it's declared, from host bindings on matched directives, and from host bindings on matched components.
当处理不同来源的绑定时,也适用这种基于具体度的规则。
某个元素可能在声明它的模板中有一些绑定、在所匹配的指令中有一些宿主绑定、在所匹配的组件中有一些宿主绑定。
Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.
模板中的绑定是最具体的,因为它们直接并且唯一地应用于该元素,所以它们具有最高的优先级。
Directive host bindings are considered less specific because directives can be used in multiple locations, so they have a lower precedence than template bindings.
指令的宿主绑定被认为不太具体,因为指令可以在多个位置使用,所以它们的优先级低于模板绑定。
Directives often augment component behavior, so host bindings from components have the lowest precedence.
指令经常会增强组件的行为,所以组件的宿主绑定优先级最低。
<code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example>
In addition, bindings take precedence over static attributes.
另外,绑定总是优先于静态属性。
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic.
在下面的例子中, `class``[class]` 具有相似的具体度,但 `[class]` 绑定优先,因为它是动态的。
<code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example>
{@a styling-delegation}
### Delegating to styles with lower precedence
### 委托优先级较低的样式
It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values.
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style.
更高优先级的样式可以使用 `undefined` 值“委托”给低级的优先级样式。虽然把 style 属性设置为 `null` 可以确保该样式被移除,但把它设置为 `undefined` 会导致 Angular 回退到该样式的次高优先级。
For example, consider the following template:
例如,考虑以下模板:
<code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example>
Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding.
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding.
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.
想象一下, `dirWithHostBinding` 指令和 `comp-with-host-binding` 组件都有 `[style.width]` 宿主绑定。在这种情况下,如果 `dirWithHostBinding` 把它的绑定设置为 `undefined` ,则 `width` 属性将回退到 `comp-with-host-binding` 主机绑定的值。但是,如果 `dirWithHostBinding` 把它的绑定设置为 `null` ,那么 `width` 属性就会被完全删除。
{@a event-binding}
## Event binding `(event)`

View File

@ -947,12 +947,16 @@ It also generates an initial test file for the component, `banner-external.compo
<div class="alert is-helpful">
Because `compileComponents` is asynchronous, it uses
the [`async`](api/core/testing/async) utility
Because `compileComponents` is asynchronous, it uses
the [`async`](api/core/testing/async) utility
function imported from `@angular/core/testing`.
由于 `compileComponents` 是异步的,所以它要使用从 `@angular/core/testing` 中导入的工具函数 [`async`](api/core/testing/async)。
Please refer to the [async](#async) section for more details.
欲知详情,请参见 [async](#async) 部分。
</div>
#### Reduce the setup
@ -1904,17 +1908,17 @@ XHR calls within a test are rare, but if you need to call XHR, see [`async()`](#
#### `tick()` 函数
You do have to call `tick()` to advance the (virtual) clock.
You do have to call [tick()](api/core/testing/tick) to advance the (virtual) clock.
你必须调用 `tick()` 函数来向前推动(虚拟)时钟。
Calling `tick()` simulates the passage of time until all pending asynchronous activities finish.
Calling [tick()](api/core/testing/tick) simulates the passage of time until all pending asynchronous activities finish.
In this case, it waits for the error handler's `setTimeout()`.
调用 `tick()` 会模拟时光的流逝,直到所有未决的异步活动都结束为止。
在这个例子中,它会等待错误处理器中的 `setTimeout()`
The `tick()` function accepts milliseconds as a parameter (defaults to 0 if not provided). The parameter represents how much the virtual clock advances. For example, if you have a `setTimeout(fn, 100)` in a `fakeAsync()` test, you need to use tick(100) to trigger the fn callback.
The [tick()](api/core/testing/tick) function accepts milliseconds as a parameter (defaults to 0 if not provided). The parameter represents how much the virtual clock advances. For example, if you have a `setTimeout(fn, 100)` in a `fakeAsync()` test, you need to use tick(100) to trigger the fn callback.
`tick()` 函数接受一个毫秒值作为参数(如果没有提供则默认为 0。该参数表示虚拟时钟要前进多少。
比如,如果你的 `fakeAsync()` 测试中有一个 `setTimeout(fn, 100)` 函数,你就需要用 `tick(100)` 来触发它的 fn 回调。
@ -1924,7 +1928,7 @@ The `tick()` function accepts milliseconds as a parameter (defaults to 0 if not
region="fake-async-test-tick">
</code-example>
The `tick()` function is one of the Angular testing utilities that you import with `TestBed`.
The [tick()](api/core/testing/tick) function is one of the Angular testing utilities that you import with `TestBed`.
It's a companion to `fakeAsync()` and you can only call it within a `fakeAsync()` body.
`tick()` 函数是你从 `TestBed` 中导入的 Angular 测试实用工具之一。
@ -2137,7 +2141,7 @@ The first quote hasn't arrived yet.
注意,这个 `<quote>` 元素应该在 `ngOnInit()` 之后显示占位值(`'...'`
但第一个引文却没有出现。
To flush the first quote from the observable, you call `tick()`.
To flush the first quote from the observable, you call [tick()](api/core/testing/tick).
Then call `detectChanges()` to tell Angular to update the screen.
要刷出可观察对象中的第一个引文,你就要先调用 `tick()`,然后调用 `detectChanges()` 来要求 Angular 刷新屏幕。
@ -2209,7 +2213,7 @@ When using an `intervalTimer()` such as `setInterval()` in `async()`, remember t
#### _whenStable_
The test must wait for the `getQuote()` observable to emit the next quote.
Instead of calling `tick()`, it calls `fixture.whenStable()`.
Instead of calling [tick()](api/core/testing/tick), it calls `fixture.whenStable()`.
该测试必须等待 `getQuote()` 的可观察对象发出下一条引言。
它不再调用 `tick()`,而是调用 `fixture.whenStable()`
@ -2378,7 +2382,7 @@ you tell the `TestScheduler` to _flush_ its queue of prepared tasks like this.
path="testing/src/app/twain/twain.component.marbles.spec.ts"
region="test-scheduler-flush"></code-example>
This step serves a purpose analogous to `tick()` and `whenStable()` in the
This step serves a purpose analogous to [tick()](api/core/testing/tick) and `whenStable()` in the
earlier `fakeAsync()` and `async()` examples.
The balance of the test is the same as those examples.
@ -2397,7 +2401,7 @@ Here's the marble testing version of the `getQuote()` error test.
path="testing/src/app/twain/twain.component.marbles.spec.ts"
region="error-test"></code-example>
It's still an async test, calling `fakeAsync()` and `tick()`, because the component itself
It's still an async test, calling `fakeAsync()` and [tick()](api/core/testing/tick), because the component itself
calls `setTimeout()` when processing errors.
它仍然是异步测试,要调用 `fakeAsync()``tick()`,这是因为组件自身在处理错误的时候调用 `setTimeout()`

View File

@ -122,7 +122,3 @@ For simple updates, the CLI command [`ng update`](cli/update) is all you need. W
* Versioning, release, support, and deprecation practices: [Angular versioning and releases](guide/releases "Angular versioning and releases")
版本、发布、支持与废弃的实践:[Angular 的版本与发布](guide/releases "Angular versioning and releases")
* Release schedule: [Angular versioning and releases](guide/releases#schedule "Angular versioning and releases")
发布计划:[Angular 的版本与发布](guide/releases#schedule "Angular versioning and releases")

View File

@ -906,6 +906,10 @@
}
],
"docVersions": [
{
"title": "v8",
"url": "https://v8.angular.io/"
},
{
"title": "v7",
"url": "https://v7.angular.io/"

View File

@ -24,7 +24,7 @@
"build-local-with-viewengine": "yarn ~~build",
"prebuild-local-with-viewengine-ci": "node scripts/switch-to-viewengine && yarn setup-local-ci",
"build-local-with-viewengine-ci": "yarn ~~build --progress=false",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 94d07909c",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js d452f0873",
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
"test": "yarn check-env && ng test",
"pree2e": "yarn check-env && yarn update-webdriver",
@ -107,8 +107,8 @@
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "0.900.0-rc.11",
"@angular/cli": "9.0.0-rc.11",
"@angular-devkit/build-angular": "0.900.0-rc.14",
"@angular/cli": "9.0.0-rc.14",
"@angular/compiler-cli": "9.0.0-rc.11",
"@angular/language-service": "9.0.0-rc.11",
"@types/html-minifier": "^3.5.3",

View File

@ -2,27 +2,27 @@
# yarn lockfile v1
"@angular-devkit/architect@0.900.0-rc.11":
version "0.900.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.0-rc.11.tgz#e9f3e5e372d467a220027cf53231b88e8e857fbc"
integrity sha512-rRbq4ipppnY4FvVo89Cv+yC7rlt1/VFE/jaB77Ra2tI6zVlFWCTjnMzuc9TYz/3jK1ssThzgEA2sebPDmjH47w==
"@angular-devkit/architect@0.900.0-rc.14":
version "0.900.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.0-rc.14.tgz#cfdbee7899b9addfd9d43c638b0dbc21188f0a79"
integrity sha512-dgEc/zYE0uzv+m8JTdv3FDc7bViJKbxs8FY3zdkArc6MXIXpoMzgvveEEHvhrpO0iu6njW/xRSZYtYnTIY4xlw==
dependencies:
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.14"
rxjs "6.5.3"
"@angular-devkit/build-angular@0.900.0-rc.11":
version "0.900.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.900.0-rc.11.tgz#0bdec73d3ba631b3550527c54a35cf4145b0ed6d"
integrity sha512-lp0f5lRsiTYSPjIgiWtX2N0NgV7dUZ/ifXYqqAEURKZ5O0jFF2gt2x9R29TmyFzTQ3ZP8O5AojO7POh1OfJ6iA==
"@angular-devkit/build-angular@0.900.0-rc.14":
version "0.900.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.900.0-rc.14.tgz#2146316c0aca5311bfe139f7f7597ac025d792b2"
integrity sha512-KnSni3kCvJbiBj43wRoY2OYsOKVDfqWGhBZsX4IPrv6OVMfCsWH9b62pcvJ0n63Qw/AwEaE6HUvCQB3IBR3lVg==
dependencies:
"@angular-devkit/architect" "0.900.0-rc.11"
"@angular-devkit/build-optimizer" "0.900.0-rc.11"
"@angular-devkit/build-webpack" "0.900.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/architect" "0.900.0-rc.14"
"@angular-devkit/build-optimizer" "0.900.0-rc.14"
"@angular-devkit/build-webpack" "0.900.0-rc.14"
"@angular-devkit/core" "9.0.0-rc.14"
"@babel/core" "7.7.7"
"@babel/generator" "7.7.7"
"@babel/preset-env" "7.7.7"
"@ngtools/webpack" "9.0.0-rc.11"
"@ngtools/webpack" "9.0.0-rc.14"
ajv "6.10.2"
autoprefixer "9.7.1"
babel-loader "8.0.6"
@ -77,10 +77,10 @@
webpack-subresource-integrity "1.3.4"
worker-plugin "3.2.0"
"@angular-devkit/build-optimizer@0.900.0-rc.11":
version "0.900.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.0-rc.11.tgz#96c2446fa9cd2e90700ab8a68312b28b3907f6d9"
integrity sha512-GJC+7H7ER6bxDC2UdAGwW357EYHpv8ISKKmS19wdJV5gZPMPANcpbg9FIpl27SDhUyZX9C2DOrcATvYYFoYgDQ==
"@angular-devkit/build-optimizer@0.900.0-rc.14":
version "0.900.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.0-rc.14.tgz#e90e955e1daf5689ad198a5253134187c99b7b5a"
integrity sha512-MA2g8N9/cvzMvudEEjeaNV6STwSr8NI/znpv+nU6sQa4PdegIotBbqxGUmHMKtLH5cOwDy9hI47ANN+XADbIbQ==
dependencies:
loader-utils "1.2.3"
source-map "0.7.3"
@ -88,19 +88,19 @@
typescript "3.6.4"
webpack-sources "1.4.3"
"@angular-devkit/build-webpack@0.900.0-rc.11":
version "0.900.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.0-rc.11.tgz#d9a91c2b67a629f6adfe87980d26e495f2e30e0a"
integrity sha512-utBAnkO6WLi323Rto1s7TJpaDRqDNR8jkD0C0PG5Zm3y1U9ARbAjTkugkrB/7bc4gEIqWZD+1dLYaaJCidye2Q==
"@angular-devkit/build-webpack@0.900.0-rc.14":
version "0.900.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.0-rc.14.tgz#b932148f14ed0056f1885c98c330411a80d31331"
integrity sha512-HvrDapIKr4k2a7Tf7MdW0miGOUUzHxRkGyDIWJBDXLbfOIt9BnhKfFGxP/SyDlwJnLyat9yYZjcDu1AI0E1Dmw==
dependencies:
"@angular-devkit/architect" "0.900.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/architect" "0.900.0-rc.14"
"@angular-devkit/core" "9.0.0-rc.14"
rxjs "6.5.3"
"@angular-devkit/core@9.0.0-rc.11":
version "9.0.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.0-rc.11.tgz#9e69545eb21284a573ad78e4c33003f2ea25afd5"
integrity sha512-ki7Sln+mQdCctJNBalzy70tiFn2hOCY2Yyte8B0xKWVHnofZySvG+ANzoLgodnKFOBH18AQy35FhgzZM++N9tQ==
"@angular-devkit/core@9.0.0-rc.14":
version "9.0.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.0-rc.14.tgz#5cff058750c0b063a6f5fa1a2e830f1f48ffa56b"
integrity sha512-hFiKoAPtnOqqYv97Y22OgyeTFxjNU/6WDhmuXkfbZDKychvuBLDOdgUhL43heEzavSfCCl23E0JmilwCUcepmw==
dependencies:
ajv "6.10.2"
fast-json-stable-stringify "2.0.0"
@ -108,12 +108,12 @@
rxjs "6.5.3"
source-map "0.7.3"
"@angular-devkit/schematics@9.0.0-rc.11":
version "9.0.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.0-rc.11.tgz#e0d4d271d8d783ebf05eced576262f20e6c3562c"
integrity sha512-aJqOLzsoAkVj3AVTf1ehH2hA9wHHz1+7TTtfqI+Yx+S3jFyvGmnKrNBCKtMuIV5JdEHiXmhhuGbNBHwRFWpOow==
"@angular-devkit/schematics@9.0.0-rc.14":
version "9.0.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.0-rc.14.tgz#4605b1ee9f18b772094697f9b35258fdac76d4b3"
integrity sha512-i/XTxo7hTXTFKus51Qry3rRGHL2uS4SgufGqdvOcy2qZbjyh/wt0UDOGJu/w8dcA9pJm+vFBLAbnro5oFyIsVw==
dependencies:
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.14"
ora "4.0.2"
rxjs "6.5.3"
@ -129,16 +129,16 @@
optionalDependencies:
parse5 "^5.0.0"
"@angular/cli@9.0.0-rc.11":
version "9.0.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-9.0.0-rc.11.tgz#5d830045bb95f4a38a1d0df02212207731061a57"
integrity sha512-Du0y6rpOfGkH7h6ukZf5SKgpTv0uAZ5McNFrPAH2KFs7PgM4fyj9VmJ1lSns9WsVcEHdPlIPh8WGResUzvePdA==
"@angular/cli@9.0.0-rc.14":
version "9.0.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-9.0.0-rc.14.tgz#4f43bb0eb9a18b8f5e9001ec0a9de01a20c31870"
integrity sha512-qdktJY0swHMfAgx2+b7jbguNsONQLRLt2X910kRY8KdiCJDXAc2dPgk8lN4K1jzpPnyzWx/0cNcDhsIzsyLDrw==
dependencies:
"@angular-devkit/architect" "0.900.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/schematics" "9.0.0-rc.11"
"@schematics/angular" "9.0.0-rc.11"
"@schematics/update" "0.900.0-rc.11"
"@angular-devkit/architect" "0.900.0-rc.14"
"@angular-devkit/core" "9.0.0-rc.14"
"@angular-devkit/schematics" "9.0.0-rc.14"
"@schematics/angular" "9.0.0-rc.14"
"@schematics/update" "0.900.0-rc.14"
"@yarnpkg/lockfile" "1.1.0"
ansi-colors "4.1.1"
debug "^4.1.1"
@ -1101,12 +1101,12 @@
call-me-maybe "^1.0.1"
glob-to-regexp "^0.3.0"
"@ngtools/webpack@9.0.0-rc.11":
version "9.0.0-rc.11"
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.0-rc.11.tgz#10b5997bec7cf48d1b144c8b4d46ffd0039c522a"
integrity sha512-qeW81ISiO8GVEndOaCYv0k6fzRIxzZs6jrXGl1pcLH1H6qv2mxhA5DA0vC/9TN6wenrS43RGjDIQpp+RvkiLwA==
"@ngtools/webpack@9.0.0-rc.14":
version "9.0.0-rc.14"
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.0-rc.14.tgz#6a764138347d2ff3846753a141eaacdab3b0658c"
integrity sha512-G98u14exE36kR4LflWB20ClJ6ql9B0qMcyokepjwpVAgaoDfpJRR7mKAZliMPd0KFXktdnct2QEyF6pbLevO7w==
dependencies:
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.14"
enhanced-resolve "4.1.1"
rxjs "6.5.3"
webpack-sources "1.4.3"
@ -1169,21 +1169,21 @@
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
"@schematics/angular@9.0.0-rc.11":
version "9.0.0-rc.11"
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.0-rc.11.tgz#d544c0d4e7b3dd59ed56be5183e038ebe06a165e"
integrity sha512-9InC+F71KiPXE0jl7Ow4iPFJ2AZZDbfTM6yWZoYLk3hzTCohAZZciBl00Tfyu2uerGshx8akbJMLySjXtf+q0g==
"@schematics/angular@9.0.0-rc.14":
version "9.0.0-rc.14"
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.0-rc.14.tgz#4112aeb6c76144893d65cab9f53ca8422adc3bbb"
integrity sha512-NWxDLym2Sst5lTvV7QYkVUjy3N0CfCohhdWC4DGRtjUyTD2eUepAg1PZCQcq8U2iRtd78Lm1n4obDWO1tW3pXQ==
dependencies:
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/schematics" "9.0.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.14"
"@angular-devkit/schematics" "9.0.0-rc.14"
"@schematics/update@0.900.0-rc.11":
version "0.900.0-rc.11"
resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.900.0-rc.11.tgz#d22df30f13a6f38970b759db61ad84d3f9b03a78"
integrity sha512-nV0oCPzzd0vi2Exo1910rWXwz/RnMc4zF9FxSOCZzsIv+AkwIehhL815OKyjUSCzU9+IM0/o1LKkPPrSWK7QEA==
"@schematics/update@0.900.0-rc.14":
version "0.900.0-rc.14"
resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.900.0-rc.14.tgz#1debea3eb90559d25838e7b256b48bac216e19d9"
integrity sha512-ZlsneHwpvrtpt0D10g4S8JftLaSFQtSO+kOD1uP26OxNMg9w54jrlr7xWSwAmT69/ETjNy8BFKXdcU9yvYixPA==
dependencies:
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/schematics" "9.0.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.14"
"@angular-devkit/schematics" "9.0.0-rc.14"
"@yarnpkg/lockfile" "1.1.0"
ini "1.3.5"
npm-package-arg "^7.0.0"

View File

@ -167,6 +167,16 @@ module.exports = function(config) {
conf.browserStack.tunnelIdentifier = tunnelIdentifier;
}
// For SauceLabs jobs, we set up a domain which resolves to the machine which launched
// the tunnel. We do this because devices are sometimes not able to properly resolve
// `localhost` or `127.0.0.1` through the SauceLabs tunnel. Using a domain that does not
// resolve to anything on SauceLabs VMs ensures that such requests are always resolved through
// the tunnel, and resolve to the actual tunnel host machine (commonly the CircleCI VMs).
// More context can be found in: https://github.com/angular/angular/pull/35171.
if (process.env.SAUCE_LOCALHOST_ALIAS_DOMAIN) {
conf.hostname = process.env.SAUCE_LOCALHOST_ALIAS_DOMAIN;
}
if (process.env.KARMA_WEB_TEST_MODE) {
// KARMA_WEB_TEST_MODE is used to setup karma to run in
// SauceLabs or Browserstack

View File

@ -35,10 +35,10 @@
},
"// 1": "dependencies are used locally and by bazel",
"dependencies": {
"@angular-devkit/architect": "0.900.0-rc.10",
"@angular-devkit/build-optimizer": "0.900.0-rc.10",
"@angular-devkit/core": "9.0.0-rc.10",
"@angular-devkit/schematics": "9.0.0-rc.10",
"@angular-devkit/architect": "0.900.0-rc.14",
"@angular-devkit/build-optimizer": "0.900.0-rc.14",
"@angular-devkit/core": "9.0.0-rc.14",
"@angular-devkit/schematics": "9.0.0-rc.14",
"@angular/bazel": "file:./tools/npm/@angular_bazel",
"@babel/core": "7.8.3",
"@babel/generator": "7.8.3",
@ -132,8 +132,8 @@
"// 2": "devDependencies are not used under Bazel. Many can be removed after test.sh is deleted.",
"// 3": "when updating @bazel/bazel version you also need to update the RBE settings in .bazelrc (see https://github.com/angular/angular/pull/27935)",
"devDependencies": {
"@angular-devkit/build-angular": "0.900.0-rc.11",
"@angular/cli": "9.0.0-rc.11",
"@angular-devkit/build-angular": "0.900.0-rc.14",
"@angular/cli": "9.0.0-rc.14",
"@bazel/bazel": "2.0.0",
"@bazel/buildifier": "^0.29.0",
"@bazel/ibazel": "^0.11.1",

View File

@ -102,6 +102,10 @@ pkg_web(
history_server(
name = "prodserver",
data = [":prodapp"],
args = [
"--port",
"4200",
],
templated_args = ["src/prodapp"],
)
@ -116,7 +120,7 @@ filegroup(
ts_devserver(
name = "devserver",
additional_root_paths = ["src/_"],
additional_root_paths = ["project/src/_"],
port = 4200,
entry_module = "project/src/main.dev",
serving_path = "/bundle.min.js",

View File

@ -39,7 +39,7 @@ function addDevDependenciesToPackageJson(options: Schema) {
const devDependencies: [string, string][] = [
['@angular/bazel', angularCore.version],
['@bazel/bazel', '2.0.0'],
['@bazel/ibazel', '0.10.3'],
['@bazel/ibazel', '0.11.1'],
['@bazel/karma', '1.2.2'],
['@bazel/protractor', '1.2.2'],
['@bazel/rollup', '1.2.2'],

View File

@ -2,7 +2,7 @@
This package contains the core functionality of the Angular compiler. It provides APIs for the implementor of a TypeScript compiler to provide Angular compilation as well.
It supports the 'ngc' command-line tool and the Angular CLI (via the `NgtscProgram`).
It supports the 'ngc' command-line tool and the Angular CLI (via the `NgtscProgram`), as well as an experimental integration with `tsc_wrapped` and the `ts_library` Bazel rule via `NgTscPlugin`.
# Angular compilation

View File

@ -97,6 +97,8 @@ export class NgCompiler {
private resourceManager: HostResourceLoader;
private cycleAnalyzer: CycleAnalyzer;
readonly incrementalDriver: IncrementalDriver;
readonly ignoreForDiagnostics: Set<ts.SourceFile>;
readonly ignoreForEmit: Set<ts.SourceFile>;
constructor(
private host: NgCompilerHost, private options: NgCompilerOptions,
@ -142,6 +144,14 @@ export class NgCompiler {
}
}
setIncrementalDriver(tsProgram, this.incrementalDriver);
this.ignoreForDiagnostics = new Set([
this.typeCheckFile,
...host.factoryFiles.map(fileName => getSourceFileOrError(tsProgram, fileName)),
...host.summaryFiles.map(fileName => getSourceFileOrError(tsProgram, fileName)),
]);
this.ignoreForEmit = new Set([this.typeCheckFile]);
}
/**
@ -285,7 +295,6 @@ export class NgCompiler {
*/
prepareEmit(): {
transformers: ts.CustomTransformers,
ignoreFiles: Set<ts.SourceFile>,
} {
const compilation = this.ensureAnalyzed();
@ -321,9 +330,7 @@ export class NgCompiler {
}
before.push(ivySwitchTransform);
const ignoreFiles = new Set<ts.SourceFile>([this.typeCheckFile]);
return {transformers: {before, afterDeclarations} as ts.CustomTransformers, ignoreFiles};
return {transformers: {before, afterDeclarations} as ts.CustomTransformers};
}
/**

View File

@ -97,17 +97,22 @@ export class NgCompilerHost extends DelegatingCompilerHost implements
readonly inputFiles: ReadonlyArray<string>;
readonly rootDirs: ReadonlyArray<AbsoluteFsPath>;
readonly typeCheckFile: AbsoluteFsPath;
readonly factoryFiles: AbsoluteFsPath[];
readonly summaryFiles: AbsoluteFsPath[];
constructor(
delegate: ExtendedTsCompilerHost, inputFiles: ReadonlyArray<string>,
rootDirs: ReadonlyArray<AbsoluteFsPath>, private shims: ShimGenerator[],
entryPoint: AbsoluteFsPath|null, typeCheckFile: AbsoluteFsPath,
factoryFiles: AbsoluteFsPath[], summaryFiles: AbsoluteFsPath[],
factoryTracker: FactoryTracker|null, diagnostics: ts.Diagnostic[]) {
super(delegate);
this.factoryTracker = factoryTracker;
this.entryPoint = entryPoint;
this.typeCheckFile = typeCheckFile;
this.factoryFiles = factoryFiles;
this.summaryFiles = summaryFiles;
this.diagnostics = diagnostics;
this.inputFiles = inputFiles;
this.rootDirs = rootDirs;
@ -136,31 +141,36 @@ export class NgCompilerHost extends DelegatingCompilerHost implements
const generators: ShimGenerator[] = [];
let summaryGenerator: SummaryGenerator|null = null;
let summaryFiles: AbsoluteFsPath[];
if (shouldGenerateSummaryShims) {
// Summary generation.
summaryGenerator = SummaryGenerator.forRootFiles(normalizedInputFiles);
generators.push(summaryGenerator);
summaryFiles = summaryGenerator.getSummaryFileNames();
} else {
summaryFiles = [];
}
let factoryTracker: FactoryTracker|null = null;
let factoryFiles: AbsoluteFsPath[];
if (shouldGenerateFactoryShims) {
// Factory generation.
const factoryGenerator = FactoryGenerator.forRootFiles(normalizedInputFiles);
const factoryFileMap = factoryGenerator.factoryFileMap;
const factoryFileNames = Array.from(factoryFileMap.keys());
rootFiles.push(...factoryFileNames);
factoryFiles = Array.from(factoryFileMap.keys());
rootFiles.push(...factoryFiles);
generators.push(factoryGenerator);
factoryTracker = new FactoryTracker(factoryGenerator);
} else {
factoryFiles = [];
}
// Done separately to preserve the order of factory files before summary files in rootFiles.
// TODO(alxhub): validate that this is necessary.
if (summaryGenerator !== null) {
rootFiles.push(...summaryGenerator.getSummaryFileNames());
}
rootFiles.push(...summaryFiles);
const rootDirs = getRootDirs(delegate, options as ts.CompilerOptions);
@ -203,8 +213,8 @@ export class NgCompilerHost extends DelegatingCompilerHost implements
}
return new NgCompilerHost(
delegate, rootFiles, rootDirs, generators, entryPoint, typeCheckFile, factoryTracker,
diagnostics);
delegate, rootFiles, rootDirs, generators, entryPoint, typeCheckFile, factoryFiles,
summaryFiles, factoryTracker, diagnostics);
}
getSourceFile(

View File

@ -88,13 +88,43 @@ export class NgtscProgram implements api.Program {
getTsSyntacticDiagnostics(
sourceFile?: ts.SourceFile|undefined,
cancellationToken?: ts.CancellationToken|undefined): readonly ts.Diagnostic[] {
return this.tsProgram.getSyntacticDiagnostics(sourceFile, cancellationToken);
const ignoredFiles = this.compiler.ignoreForDiagnostics;
if (sourceFile !== undefined) {
if (ignoredFiles.has(sourceFile)) {
return [];
}
return this.tsProgram.getSyntacticDiagnostics(sourceFile, cancellationToken);
} else {
const diagnostics: ts.Diagnostic[] = [];
for (const sf of this.tsProgram.getSourceFiles()) {
if (!ignoredFiles.has(sf)) {
diagnostics.push(...this.tsProgram.getSyntacticDiagnostics(sf, cancellationToken));
}
}
return diagnostics;
}
}
getTsSemanticDiagnostics(
sourceFile?: ts.SourceFile|undefined,
cancellationToken?: ts.CancellationToken|undefined): readonly ts.Diagnostic[] {
return this.tsProgram.getSemanticDiagnostics(sourceFile, cancellationToken);
const ignoredFiles = this.compiler.ignoreForDiagnostics;
if (sourceFile !== undefined) {
if (ignoredFiles.has(sourceFile)) {
return [];
}
return this.tsProgram.getSemanticDiagnostics(sourceFile, cancellationToken);
} else {
const diagnostics: ts.Diagnostic[] = [];
for (const sf of this.tsProgram.getSourceFiles()) {
if (!ignoredFiles.has(sf)) {
diagnostics.push(...this.tsProgram.getSemanticDiagnostics(sf, cancellationToken));
}
}
return diagnostics;
}
}
getNgOptionDiagnostics(cancellationToken?: ts.CancellationToken|
@ -144,7 +174,8 @@ export class NgtscProgram implements api.Program {
emitCallback?: api.TsEmitCallback | undefined;
mergeEmitResultsCallback?: api.TsMergeEmitResultsCallback | undefined;
}|undefined): ts.EmitResult {
const {transformers, ignoreFiles} = this.compiler.prepareEmit();
const {transformers} = this.compiler.prepareEmit();
const ignoreFiles = this.compiler.ignoreForEmit;
const emitCallback = opts && opts.emitCallback || defaultEmitCallback;
const writeFile: ts.WriteFileCallback =

View File

@ -22,9 +22,11 @@ const STRIP_NG_FACTORY = /(.*)NgFactory$/;
* class of an input ts.SourceFile.
*/
export class FactoryGenerator implements ShimGenerator {
private constructor(private map: Map<string, string>) {}
private constructor(private map: Map<AbsoluteFsPath, AbsoluteFsPath>) {}
get factoryFileMap(): Map<string, string> { return this.map; }
get factoryFileMap(): Map<AbsoluteFsPath, AbsoluteFsPath> { return this.map; }
get factoryFileNames(): AbsoluteFsPath[] { return Array.from(this.map.keys()); }
recognize(fileName: AbsoluteFsPath): boolean { return this.map.has(fileName); }
@ -101,7 +103,7 @@ export class FactoryGenerator implements ShimGenerator {
}
static forRootFiles(files: ReadonlyArray<AbsoluteFsPath>): FactoryGenerator {
const map = new Map<AbsoluteFsPath, string>();
const map = new Map<AbsoluteFsPath, AbsoluteFsPath>();
files.filter(sourceFile => isNonDeclarationTsPath(sourceFile))
.forEach(
sourceFile =>

View File

@ -15,9 +15,9 @@ import {ShimGenerator} from './api';
import {generatedModuleName} from './util';
export class SummaryGenerator implements ShimGenerator {
private constructor(private map: Map<AbsoluteFsPath, string>) {}
private constructor(private map: Map<AbsoluteFsPath, AbsoluteFsPath>) {}
getSummaryFileNames(): string[] { return Array.from(this.map.keys()); }
getSummaryFileNames(): AbsoluteFsPath[] { return Array.from(this.map.keys()); }
recognize(fileName: AbsoluteFsPath): boolean { return this.map.has(fileName); }
@ -78,7 +78,7 @@ export class SummaryGenerator implements ShimGenerator {
}
static forRootFiles(files: ReadonlyArray<AbsoluteFsPath>): SummaryGenerator {
const map = new Map<AbsoluteFsPath, string>();
const map = new Map<AbsoluteFsPath, AbsoluteFsPath>();
files.filter(sourceFile => isNonDeclarationTsPath(sourceFile))
.forEach(
sourceFile =>

View File

@ -1,99 +0,0 @@
/**
* @license
* Copyright Google Inc. 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 {PluginCompilerHost} from '@bazel/typescript/internal/tsc_wrapped/plugin_api';
import * as ts from 'typescript';
/**
* Extension of the TypeScript compiler host that supports files added to the Program which
* were never on disk.
*
* This is used for backwards-compatibility with the ViewEngine compiler, which used ngsummary
* and ngfactory files as inputs to the program. We call these inputs "synthetic".
*
* They need to be program inputs because user code may import from these generated files.
*
* TODO(alxhub): remove this after all ng_module users have migrated to Ivy
*/
export class SyntheticFilesCompilerHost implements PluginCompilerHost {
/**
* SourceFiles which are added to the program but which never existed on disk.
*/
syntheticFiles = new Map<string, ts.SourceFile>();
constructor(
private rootFiles: string[], private delegate: ts.CompilerHost,
generatedFiles: (rootFiles: string[]) => {
[fileName: string]: (host: ts.CompilerHost) => ts.SourceFile | undefined
}) {
// Allow ngtsc to contribute in-memory synthetic files, which will be loaded
// as if they existed on disk as action inputs.
const angularGeneratedFiles = generatedFiles !(rootFiles);
for (const f of Object.keys(angularGeneratedFiles)) {
const generator = angularGeneratedFiles[f];
const generated = generator(delegate);
if (generated) {
this.syntheticFiles.set(generated.fileName, generated);
}
}
if (delegate.getDirectories !== undefined) {
this.getDirectories = (path: string) => delegate.getDirectories !(path);
}
}
fileExists(filePath: string): boolean {
if (this.syntheticFiles.has(filePath)) {
return true;
}
return this.delegate.fileExists(filePath);
}
/** Loads a source file from in-memory map, or delegates. */
getSourceFile(
fileName: string, languageVersion: ts.ScriptTarget,
onError?: (message: string) => void): ts.SourceFile|undefined {
const syntheticFile = this.syntheticFiles.get(fileName);
if (syntheticFile) {
return syntheticFile !;
}
return this.delegate.getSourceFile(fileName, languageVersion, onError);
}
get inputFiles() { return [...this.rootFiles, ...Array.from(this.syntheticFiles.keys())]; }
fileNameToModuleId(fileName: string) {
return fileName; // TODO: Ivy logic. don't forget that the delegate has the google3 logic
}
// Delegate everything else to the original compiler host.
getDefaultLibFileName(options: ts.CompilerOptions): string {
return this.delegate.getDefaultLibFileName(options);
}
writeFile(
fileName: string, content: string, writeByteOrderMark: boolean,
onError: ((message: string) => void)|undefined,
sourceFiles: ReadonlyArray<ts.SourceFile>|undefined): void {
this.delegate.writeFile(fileName, content, writeByteOrderMark, onError, sourceFiles);
}
getCanonicalFileName(path: string) { return this.delegate.getCanonicalFileName(path); }
getCurrentDirectory(): string { return this.delegate.getCurrentDirectory(); }
useCaseSensitiveFileNames(): boolean { return this.delegate.useCaseSensitiveFileNames(); }
getNewLine(): string { return this.delegate.getNewLine(); }
getDirectories?: (path: string) => string[];
readFile(fileName: string): string|undefined { return this.delegate.readFile(fileName); }
trace(s: string): void { console.error(s); }
}

View File

@ -6,77 +6,105 @@
* found in the LICENSE file at https://angular.io/license
*/
import {PluginCompilerHost, TscPlugin} from '@bazel/typescript/internal/tsc_wrapped/plugin_api';
import * as ts from 'typescript';
import {SyntheticFilesCompilerHost} from './synthetic_files_compiler_host';
import {NgCompiler, NgCompilerHost} from './core';
import {NgCompilerOptions, UnifiedModulesHost} from './core/api';
import {NodeJSFileSystem, setFileSystem} from './file_system';
import {NOOP_PERF_RECORDER} from './perf';
// Copied from tsc_wrapped/plugin_api.ts to avoid a runtime dependency on the
// @bazel/typescript package - it would be strange for non-Bazel users of
// Angular to fetch that package.
function createProxy<T>(delegate: T): T {
const proxy = Object.create(null);
for (const k of Object.keys(delegate)) {
proxy[k] = function() { return (delegate as any)[k].apply(delegate, arguments); };
}
return proxy;
// The following is needed to fix a the chicken-and-egg issue where the sync (into g3) script will
// refuse to accept this file unless the following string appears:
// import * as plugin from '@bazel/typescript/internal/tsc_wrapped/plugin_api';
/**
* A `ts.CompilerHost` which also returns a list of input files, out of which the `ts.Program`
* should be created.
*
* Currently mirrored from @bazel/typescript/internal/tsc_wrapped/plugin_api (with the naming of
* `fileNameToModuleName` corrected).
*/
interface PluginCompilerHost extends ts.CompilerHost, Partial<UnifiedModulesHost> {
readonly inputFiles: ReadonlyArray<string>;
}
/**
* Mirrors the plugin interface from tsc_wrapped which is currently under active development. To
* enable progress to be made in parallel, the upstream interface isn't implemented directly.
* Instead, `TscPlugin` here is structurally assignable to what tsc_wrapped expects.
*/
interface TscPlugin {
readonly name: string;
wrapHost(
host: ts.CompilerHost&Partial<UnifiedModulesHost>, inputFiles: ReadonlyArray<string>,
options: ts.CompilerOptions): PluginCompilerHost;
setupCompilation(program: ts.Program, oldProgram?: ts.Program): {
ignoreForDiagnostics: Set<ts.SourceFile>,
ignoreForEmit: Set<ts.SourceFile>,
};
getDiagnostics(file?: ts.SourceFile): ts.Diagnostic[];
getOptionDiagnostics(): ts.Diagnostic[];
getNextProgram(): ts.Program;
prepareEmit(): {
transformers: ts.CustomTransformers,
};
}
/**
* A plugin for `tsc_wrapped` which allows Angular compilation from a plain `ts_library`.
*/
export class NgTscPlugin implements TscPlugin {
constructor(private angularCompilerOptions: unknown) {}
name = 'ngtsc';
wrapHost(inputFiles: string[], compilerHost: ts.CompilerHost) {
return new SyntheticFilesCompilerHost(inputFiles, compilerHost, (rootFiles: string[]) => {
// For demo purposes, assume that the first .ts rootFile is the only
// one that needs ngfactory.js/d.ts back-compat files produced.
const tsInputs = rootFiles.filter(f => f.endsWith('.ts') && !f.endsWith('.d.ts'));
const factoryPath: string = tsInputs[0].replace(/\.ts/, '.ngfactory.ts');
private options: NgCompilerOptions|null = null;
private host: NgCompilerHost|null = null;
private _compiler: NgCompiler|null = null;
return {
factoryPath: (host: ts.CompilerHost) =>
ts.createSourceFile(factoryPath, 'contents', ts.ScriptTarget.ES5),
};
});
get compiler(): NgCompiler {
if (this._compiler === null) {
throw new Error('Lifecycle error: setupCompilation() must be called first.');
}
return this._compiler;
}
wrap(program: ts.Program, config: {}, host: ts.CompilerHost) {
const proxy = createProxy(program);
proxy.getSemanticDiagnostics = (sourceFile: ts.SourceFile) => {
const result: ts.Diagnostic[] = [...program.getSemanticDiagnostics(sourceFile)];
constructor(private ngOptions: {}) { setFileSystem(new NodeJSFileSystem()); }
// For demo purposes, trigger a diagnostic when the sourcefile has a magic string
if (sourceFile.text.indexOf('diag') >= 0) {
const fake: ts.Diagnostic = {
file: sourceFile,
start: 0,
length: 3,
messageText: 'Example Angular Compiler Diagnostic',
category: ts.DiagnosticCategory.Error,
code: 12345,
// source is the name of the plugin.
source: 'ngtsc',
};
result.push(fake);
}
return result;
wrapHost(
host: ts.CompilerHost&UnifiedModulesHost, inputFiles: readonly string[],
options: ts.CompilerOptions): PluginCompilerHost {
this.options = {...this.ngOptions, ...options } as NgCompilerOptions;
this.host = NgCompilerHost.wrap(host, inputFiles, this.options);
return this.host;
}
setupCompilation(program: ts.Program, oldProgram?: ts.Program): {
ignoreForDiagnostics: Set<ts.SourceFile>,
ignoreForEmit: Set<ts.SourceFile>,
} {
if (this.host === null || this.options === null) {
throw new Error('Lifecycle error: setupCompilation() before wrapHost().');
}
this._compiler =
new NgCompiler(this.host, this.options, program, oldProgram, NOOP_PERF_RECORDER);
return {
ignoreForDiagnostics: this._compiler.ignoreForDiagnostics,
ignoreForEmit: this._compiler.ignoreForEmit,
};
return proxy;
}
createTransformers(host: PluginCompilerHost) {
const afterDeclarations: Array<ts.TransformerFactory<ts.SourceFile|ts.Bundle>> =
[(context: ts.TransformationContext) => (sf: ts.SourceFile | ts.Bundle) => {
const visitor = (node: ts.Node): ts.Node => {
if (ts.isClassDeclaration(node)) {
// For demo purposes, transform the class name in the .d.ts output
return ts.updateClassDeclaration(
node, node.decorators, node.modifiers, ts.createIdentifier('NEWNAME'),
node.typeParameters, node.heritageClauses, node.members);
}
return ts.visitEachChild(node, visitor, context);
};
return visitor(sf) as ts.SourceFile;
}];
return {afterDeclarations};
getDiagnostics(file?: ts.SourceFile): ts.Diagnostic[] {
return this.compiler.getDiagnostics(file);
}
getOptionDiagnostics(): ts.Diagnostic[] { return this.compiler.getOptionDiagnostics(); }
getNextProgram(): ts.Program { return this.compiler.getNextProgram(); }
prepareEmit(): {transformers: ts.CustomTransformers;} { return this.compiler.prepareEmit(); }
}

View File

@ -1,8 +1,7 @@
#!/usr/bin/env bash
set -u -e -o pipefail
# Script that runs all unit tests of the `angular/components` repository. The script also
# sets up the test blocklist from `tools/components-repo-ci`.
# Script that runs all unit tests of the `angular/components` repository.
# Path to the Angular project.
angular_dir=$(pwd)
@ -11,10 +10,6 @@ angular_dir=$(pwd)
# repository has been cloned into.
cd ${COMPONENTS_REPO_TMP_DIR}
# Copy the test blocklist into the `angular/components` repository. The unit tests will
# automatically pick up the blocklist and disable the specified tests.
cp ${angular_dir}/tools/components-repo-ci/test-blocklist.ts ${COMPONENTS_REPO_TMP_DIR}/test/
# Create a symlink for the Bazel binary installed through NPM, as running through Yarn introduces OOM errors.
./scripts/circleci/setup_bazel_binary.sh

View File

@ -7,7 +7,7 @@
mkdir tmp
cd tmp
npm init -y
npm install typescript@~2.7.0 rxjs@^6.0.0 zone.js@~0.8.26 @angular/{animations,core,common,forms,router,platform-browser,platform-browser-dynamic,platform-webworker,platform-webworker-dynamic,platform-server,service-worker,compiler,compiler-cli,upgrade,language-service,elements} --save
npm install typescript@~3.7.4 rxjs@^6.5.3 zone.js@~0.10.2 @bazel/typescript@^1.0.0 rollup@^1.20.0 rollup-plugin-commonjs@^9.0.0 rollup-plugin-node-resolve@^4.2.0 rollup-plugin-sourcemaps@0.4.0 @angular/{animations,bazel,common,compiler,compiler-cli,core,elements,forms,language-service,localize,platform-browser,platform-browser-dynamic,platform-server,platform-webworker,platform-webworker-dynamic,router,service-worker,upgrade} --save
cd ..
rm -rf tmp

View File

@ -7,7 +7,7 @@
mkdir tmp
cd tmp
npm init -y
npm install typescript@~3.1.1 rxjs@^6.0.0-beta.4 zone.js@~0.8.20 @angular/{animations,core,common,forms,http,router,platform-browser,platform-browser-dynamic,platform-webworker,platform-webworker-dynamic,platform-server,compiler,compiler-cli,language-service,service-worker,upgrade}@next --save
npm install typescript@~3.7.4 rxjs@^6.5.3 zone.js@~0.10.2 @bazel/typescript@^1.0.0 rollup@^1.20.0 rollup-plugin-commonjs@^9.0.0 rollup-plugin-node-resolve@^4.2.0 rollup-plugin-sourcemaps@0.4.0 @angular/{animations,bazel,common,compiler,compiler-cli,core,elements,forms,language-service,localize,platform-browser,platform-browser-dynamic,platform-server,platform-webworker,platform-webworker-dynamic,router,service-worker,upgrade}@next --save
cd ..
rm -rf tmp

View File

@ -1,2 +0,0 @@
# Fetched from https://github.com/yarnpkg/yarn/releases/download/v1.21.1/yarn-v1.21.1.tar.gz
licenses(["notice"])

View File

@ -1,26 +0,0 @@
BSD 2-Clause License
For Yarn software
Copyright (c) 2016-present, Yarn Contributors. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,60 +0,0 @@
<p align="center">
<a href="https://yarnpkg.com/">
<img alt="Yarn" src="https://github.com/yarnpkg/assets/blob/master/yarn-kitten-full.png?raw=true" width="546">
</a>
</p>
<p align="center">
Fast, reliable, and secure dependency management.
</p>
<p align="center">
<a href="https://circleci.com/gh/yarnpkg/yarn"><img alt="Circle Status" src="https://circleci.com/gh/yarnpkg/yarn.svg?style=shield&circle-token=5f0a78473b0f440afb218bf2b82323cc6b3cb43f"></a>
<a href="https://ci.appveyor.com/project/kittens/yarn/branch/master"><img alt="Appveyor Status" src="https://ci.appveyor.com/api/projects/status/0xdv8chwe2kmk463?svg=true"></a>
<a href="https://dev.azure.com/yarnpkg/yarn/_build"><img alt="Azure Pipelines status" src="https://dev.azure.com/yarnpkg/yarn/_apis/build/status/Yarn%20Acceptance%20Tests"></a>
<a href="https://discord.gg/yarnpkg"><img alt="Discord Chat" src="https://img.shields.io/discord/226791405589233664.svg"></a>
<a href="http://commitizen.github.io/cz-cli/"><img alt="Commitizen friendly" src="https://img.shields.io/badge/commitizen-friendly-brightgreen.svg"></a>
</p>
---
**Fast:** Yarn caches every package it has downloaded, so it never needs to download the same package again. It also does almost everything concurrently to maximize resource utilization. This means even faster installs.
**Reliable:** Using a detailed but concise lockfile format and a deterministic algorithm for install operations, Yarn is able to guarantee that any installation that works on one system will work exactly the same on another system.
**Secure:** Yarn uses checksums to verify the integrity of every installed package before its code is executed.
## Features
* **Offline Mode.** If you've installed a package before, then you can install it again without an internet connection.
* **Deterministic.** The same dependencies will be installed in the same exact way on any machine, regardless of installation order.
* **Network Performance.** Yarn efficiently queues requests and avoids request waterfalls in order to maximize network utilization.
* **Network Resilience.** A single request that fails will not cause the entire installation to fail. Requests are automatically retried upon failure.
* **Flat Mode.** Yarn resolves mismatched versions of dependencies to a single version to avoid creating duplicates.
* **More emojis.** 🐈
## Installing Yarn
Read the [Installation Guide](https://yarnpkg.com/en/docs/install) on our website for detailed instructions on how to install Yarn.
## Using Yarn
Read the [Usage Guide](https://yarnpkg.com/en/docs/usage) on our website for detailed instructions on how to use Yarn.
## Contributing to Yarn
Contributions are always welcome, no matter how large or small. Substantial feature requests should be proposed as an [RFC](https://github.com/yarnpkg/rfcs). Before contributing, please read the [code of conduct](CODE_OF_CONDUCT.md).
See [Contributing](https://yarnpkg.com/org/contributing/).
## Prior art
Yarn wouldn't exist if it wasn't for excellent prior art. Yarn has been inspired by the following projects:
- [Bundler](https://github.com/bundler/bundler)
- [Cargo](https://github.com/rust-lang/cargo)
- [npm](https://github.com/npm/cli)
## Credits
Thanks to [Sam Holmes](https://github.com/samholmes) for donating the npm package name!

View File

@ -1,35 +0,0 @@
#!/bin/sh
argv0=$(echo "$0" | sed -e 's,\\,/,g')
basedir=$(dirname "$(readlink "$0" || echo "$argv0")")
case "$(uname -s)" in
Darwin) basedir="$( cd "$( dirname "$argv0" )" && pwd )";;
Linux) basedir=$(dirname "$(readlink -f "$0" || echo "$argv0")");;
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
command_exists() {
command -v "$1" >/dev/null 2>&1;
}
if command_exists node; then
if [ "$YARN_FORCE_WINPTY" = 1 ] || command_exists winpty && test -t 1; then
winpty node "$basedir/yarn.js" "$@"
else
exec node "$basedir/yarn.js" "$@"
fi
ret=$?
# Debian and Ubuntu use "nodejs" as the name of the binary, not "node", so we
# search for that too. See:
# https://lists.debian.org/debian-devel-announce/2012/07/msg00002.html
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=614907
elif command_exists nodejs; then
exec nodejs "$basedir/yarn.js" "$@"
ret=$?
else
>&2 echo 'Yarn requires Node.js 4.0 or higher to be installed.'
ret=1
fi
exit $ret

View File

@ -1,2 +0,0 @@
@echo off
node "%~dp0\yarn.js" %*

View File

@ -1,31 +0,0 @@
#!/usr/bin/env node
/* eslint-disable no-var */
/* eslint-disable flowtype/require-valid-file-annotation */
'use strict';
var ver = process.versions.node;
var majorVer = parseInt(ver.split('.')[0], 10);
if (majorVer < 4) {
console.error('Node version ' + ver + ' is not supported, please use Node.js 4.0 or higher.');
process.exit(1); // eslint-disable-line no-process-exit
} else {
try {
require(__dirname + '/../lib/v8-compile-cache.js');
} catch (err) {
// We don't have/need this on legacy builds and dev builds
}
// Just requiring this package will trigger a yarn run since the
// `require.main === module` check inside `cli/index.js` will always
// be truthy when built with webpack :(
// `lib/cli` may be `lib/cli/index.js` or `lib/cli.js` depending on the build.
var cli = require(__dirname + '/../lib/cli');
if (!cli.autoRun) {
cli.default().catch(function(error) {
console.error(error.stack || error.message || error);
process.exitCode = 1;
});
}
}

View File

@ -1,2 +0,0 @@
#!/usr/bin/env node
require('./yarn.js');

View File

@ -1,2 +0,0 @@
@echo off
"%~dp0\yarn.cmd" %*

File diff suppressed because one or more lines are too long

View File

@ -1,351 +0,0 @@
'use strict';
const Module = require('module');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const vm = require('vm');
const os = require('os');
const hasOwnProperty = Object.prototype.hasOwnProperty;
//------------------------------------------------------------------------------
// FileSystemBlobStore
//------------------------------------------------------------------------------
class FileSystemBlobStore {
constructor(directory, prefix) {
const name = prefix ? slashEscape(prefix + '.') : '';
this._blobFilename = path.join(directory, name + 'BLOB');
this._mapFilename = path.join(directory, name + 'MAP');
this._lockFilename = path.join(directory, name + 'LOCK');
this._directory = directory;
this._load();
}
has(key, invalidationKey) {
if (hasOwnProperty.call(this._memoryBlobs, key)) {
return this._invalidationKeys[key] === invalidationKey;
} else if (hasOwnProperty.call(this._storedMap, key)) {
return this._storedMap[key][0] === invalidationKey;
}
return false;
}
get(key, invalidationKey) {
if (hasOwnProperty.call(this._memoryBlobs, key)) {
if (this._invalidationKeys[key] === invalidationKey) {
return this._memoryBlobs[key];
}
} else if (hasOwnProperty.call(this._storedMap, key)) {
const mapping = this._storedMap[key];
if (mapping[0] === invalidationKey) {
return this._storedBlob.slice(mapping[1], mapping[2]);
}
}
}
set(key, invalidationKey, buffer) {
this._invalidationKeys[key] = invalidationKey;
this._memoryBlobs[key] = buffer;
this._dirty = true;
}
delete(key) {
if (hasOwnProperty.call(this._memoryBlobs, key)) {
this._dirty = true;
delete this._memoryBlobs[key];
}
if (hasOwnProperty.call(this._invalidationKeys, key)) {
this._dirty = true;
delete this._invalidationKeys[key];
}
if (hasOwnProperty.call(this._storedMap, key)) {
this._dirty = true;
delete this._storedMap[key];
}
}
isDirty() {
return this._dirty;
}
save() {
const dump = this._getDump();
const blobToStore = Buffer.concat(dump[0]);
const mapToStore = JSON.stringify(dump[1]);
try {
mkdirpSync(this._directory);
fs.writeFileSync(this._lockFilename, 'LOCK', {flag: 'wx'});
} catch (error) {
// Swallow the exception if we fail to acquire the lock.
return false;
}
try {
fs.writeFileSync(this._blobFilename, blobToStore);
fs.writeFileSync(this._mapFilename, mapToStore);
} catch (error) {
throw error;
} finally {
fs.unlinkSync(this._lockFilename);
}
return true;
}
_load() {
try {
this._storedBlob = fs.readFileSync(this._blobFilename);
this._storedMap = JSON.parse(fs.readFileSync(this._mapFilename));
} catch (e) {
this._storedBlob = Buffer.alloc(0);
this._storedMap = {};
}
this._dirty = false;
this._memoryBlobs = {};
this._invalidationKeys = {};
}
_getDump() {
const buffers = [];
const newMap = {};
let offset = 0;
function push(key, invalidationKey, buffer) {
buffers.push(buffer);
newMap[key] = [invalidationKey, offset, offset + buffer.length];
offset += buffer.length;
}
for (const key of Object.keys(this._memoryBlobs)) {
const buffer = this._memoryBlobs[key];
const invalidationKey = this._invalidationKeys[key];
push(key, invalidationKey, buffer);
}
for (const key of Object.keys(this._storedMap)) {
if (hasOwnProperty.call(newMap, key)) continue;
const mapping = this._storedMap[key];
const buffer = this._storedBlob.slice(mapping[1], mapping[2]);
push(key, mapping[0], buffer);
}
return [buffers, newMap];
}
}
//------------------------------------------------------------------------------
// NativeCompileCache
//------------------------------------------------------------------------------
class NativeCompileCache {
constructor() {
this._cacheStore = null;
this._previousModuleCompile = null;
}
setCacheStore(cacheStore) {
this._cacheStore = cacheStore;
}
install() {
const self = this;
this._previousModuleCompile = Module.prototype._compile;
Module.prototype._compile = function(content, filename) {
const mod = this;
function require(id) {
return mod.require(id);
}
require.resolve = function(request) {
return Module._resolveFilename(request, mod);
};
require.main = process.mainModule;
// Enable support to add extra extension types
require.extensions = Module._extensions;
require.cache = Module._cache;
const dirname = path.dirname(filename);
const compiledWrapper = self._moduleCompile(filename, content);
// We skip the debugger setup because by the time we run, node has already
// done that itself.
const args = [mod.exports, require, mod, filename, dirname, process, global];
return compiledWrapper.apply(mod.exports, args);
};
}
uninstall() {
Module.prototype._compile = this._previousModuleCompile;
}
_moduleCompile(filename, content) {
// https://github.com/nodejs/node/blob/v7.5.0/lib/module.js#L511
// Remove shebang
var contLen = content.length;
if (contLen >= 2) {
if (content.charCodeAt(0) === 35/*#*/ &&
content.charCodeAt(1) === 33/*!*/) {
if (contLen === 2) {
// Exact match
content = '';
} else {
// Find end of shebang line and slice it off
var i = 2;
for (; i < contLen; ++i) {
var code = content.charCodeAt(i);
if (code === 10/*\n*/ || code === 13/*\r*/) break;
}
if (i === contLen) {
content = '';
} else {
// Note that this actually includes the newline character(s) in the
// new output. This duplicates the behavior of the regular
// expression that was previously used to replace the shebang line
content = content.slice(i);
}
}
}
}
// create wrapper function
var wrapper = Module.wrap(content);
var invalidationKey = crypto
.createHash('sha1')
.update(content, 'utf8')
.digest('hex');
var buffer = this._cacheStore.get(filename, invalidationKey);
var script = new vm.Script(wrapper, {
filename: filename,
lineOffset: 0,
displayErrors: true,
cachedData: buffer,
produceCachedData: true,
});
if (script.cachedDataProduced) {
this._cacheStore.set(filename, invalidationKey, script.cachedData);
} else if (script.cachedDataRejected) {
this._cacheStore.delete(filename);
}
var compiledWrapper = script.runInThisContext({
filename: filename,
lineOffset: 0,
columnOffset: 0,
displayErrors: true,
});
return compiledWrapper;
}
}
//------------------------------------------------------------------------------
// utilities
//
// https://github.com/substack/node-mkdirp/blob/f2003bb/index.js#L55-L98
// https://github.com/zertosh/slash-escape/blob/e7ebb99/slash-escape.js
//------------------------------------------------------------------------------
function mkdirpSync(p_) {
_mkdirpSync(path.resolve(p_), parseInt('0777', 8) & ~process.umask());
}
function _mkdirpSync(p, mode) {
try {
fs.mkdirSync(p, mode);
} catch (err0) {
if (err0.code === 'ENOENT') {
_mkdirpSync(path.dirname(p));
_mkdirpSync(p);
} else {
try {
const stat = fs.statSync(p);
if (!stat.isDirectory()) { throw err0; }
} catch (err1) {
throw err0;
}
}
}
}
function slashEscape(str) {
const ESCAPE_LOOKUP = {
'\\': 'zB',
':': 'zC',
'/': 'zS',
'\x00': 'z0',
'z': 'zZ',
};
return str.replace(/[\\:\/\x00z]/g, match => (ESCAPE_LOOKUP[match]));
}
function supportsCachedData() {
const script = new vm.Script('""', {produceCachedData: true});
// chakracore, as of v1.7.1.0, returns `false`.
return script.cachedDataProduced === true;
}
function getCacheDir() {
// Avoid cache ownership issues on POSIX systems.
const dirname = typeof process.getuid === 'function'
? 'v8-compile-cache-' + process.getuid()
: 'v8-compile-cache';
const version = typeof process.versions.v8 === 'string'
? process.versions.v8
: typeof process.versions.chakracore === 'string'
? 'chakracore-' + process.versions.chakracore
: 'node-' + process.version;
const cacheDir = path.join(os.tmpdir(), dirname, version);
return cacheDir;
}
function getParentName() {
// `module.parent.filename` is undefined or null when:
// * node -e 'require("v8-compile-cache")'
// * node -r 'v8-compile-cache'
// * Or, requiring from the REPL.
const parentName = module.parent && typeof module.parent.filename === 'string'
? module.parent.filename
: process.cwd();
return parentName;
}
//------------------------------------------------------------------------------
// main
//------------------------------------------------------------------------------
if (!process.env.DISABLE_V8_COMPILE_CACHE && supportsCachedData()) {
const cacheDir = getCacheDir();
const prefix = getParentName();
const blobStore = new FileSystemBlobStore(cacheDir, prefix);
const nativeCompileCache = new NativeCompileCache();
nativeCompileCache.setCacheStore(blobStore);
nativeCompileCache.install();
process.once('exit', code => {
if (blobStore.isDirty()) {
blobStore.save();
}
nativeCompileCache.uninstall();
});
}
module.exports.__TEST__ = {
FileSystemBlobStore,
NativeCompileCache,
mkdirpSync,
slashEscape,
supportsCachedData,
getCacheDir,
getParentName,
};

View File

@ -1,24 +0,0 @@
{
"name": "yarn",
"installationMethod": "tar",
"version": "1.21.1",
"license": "BSD-2-Clause",
"preferGlobal": true,
"description": "📦🐈 Fast, reliable, and secure dependency management.",
"resolutions": {
"sshpk": "^1.14.2"
},
"engines": {
"node": ">=4.0.0"
},
"repository": "yarnpkg/yarn",
"bin": {
"yarn": "./bin/yarn.js",
"yarnpkg": "./bin/yarn.js"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}

View File

@ -1,32 +0,0 @@
### Unit tests for `angular/components`
Currently, all changes to Ivy are validated against the test suite of the
`angular/components` repository. Known failing tests are skipped based on
the blocklist in `tools/components-repo-ci/test-blocklist.ts`.
Whenever the root cause of a known failure is identified, the `notes` field
for the corresponding tests should be updated. Whenever a failure is resolved,
the corresponding tests should be removed from the blocklist.
### Debugging
Information on debugging can be found [here](../../docs/DEBUG_COMPONENTS_REPO_IVY.md).
### Excluding new tests
In case there are any tests in the components test suite that fail due to
recent changes in the framework and you want to exclude the tests temporarily,
a new entry can be added to the `test-blocklist.ts` file.
Each property in the blocklist object corresponds to a test in the components
repository. The name of the property **must** match the exact test name. Additionally
it's **recommended** that every entry has a field with a note on why the test is disabled.
```ts
export const testBlocklist: any = {
'MatSlider should be able to drag thumb': {
error: 'Cannot register event "dragstart".',
notes: 'Breaking change where HammerJS module needs to be imported.'
}
}
```

View File

@ -1,29 +0,0 @@
/**
* @license
* Copyright Google Inc. 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
*/
// clang-format off
// tslint:disable
interface BlocklistEntry {
/** Description on why the given test is disabled. */
notes: string;
/** Optional error that has been thrown in the test. */
error?: string;
}
/**
* List of tests that should not run in the Angular component test suites. This should
* be empty in the components repository, but the file will be overwritten if the framework
* repository runs the Angular component test suites against the latest snapshots. This is
* helpful because sometimes breaking changes that break individual tests land in the framework
* repository. It should be possible to disable these tests until the component repository
* migrated the broken tests.
*/
export const testBlocklist: {[testName: string]: BlocklistEntry} = {};
// clang-format on

View File

@ -21,22 +21,18 @@ try {
// KARMA_WEB_TEST_MODE is set which informs /karma-js.conf.js that it should
// run the test with the karma saucelabs launcher
process.env['KARMA_WEB_TEST_MODE'] = 'SL_REQUIRED';
// Saucelabs parameters read from a temporary file that is created by the `sauce-service`. This
// will be `null` if the test runs locally without the `sauce-service` being started.
const saucelabsParams = readLocalSauceConnectParams();
// Setup required SAUCE_* env if they are not already set
if (!process.env['SAUCE_USERNAME'] || !process.env['SAUCE_ACCESS_KEY'] ||
!process.env['SAUCE_TUNNEL_IDENTIFIER']) {
try {
// The following path comes from /tools/saucelabs/sauce-service.sh.
// We setup the required saucelabs environment variables here for the karma test
// from a json file under /tmp/angular/sauce-service so that we don't break the
// test cache with a changing SAUCE_TUNNEL_IDENTIFIER provided through --test_env
const scParams = require('/tmp/angular/sauce-service/sauce-connect-params.json');
process.env['SAUCE_USERNAME'] = scParams.SAUCE_USERNAME;
process.env['SAUCE_ACCESS_KEY'] = scParams.SAUCE_ACCESS_KEY;
process.env['SAUCE_TUNNEL_IDENTIFIER'] = scParams.SAUCE_TUNNEL_IDENTIFIER;
} catch (e) {
console.error(e.stack || e);
console.error(
`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// We print a helpful error message below if the required Saucelabs parameters have not
// been specified in test environment, and the `sauce-service` params file has not been
// created either.
if (saucelabsParams === null) {
console.error(`
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! Make sure that you have run "yarn bazel run //tools/saucelabs:sauce_service_setup"
!!! (or "./tools/saucelabs/sauce-service.sh setup") before the test target. Alternately
!!! you can provide the required SAUCE_* environment variables (SAUCE_USERNAME, SAUCE_ACCESS_KEY &
@ -45,6 +41,16 @@ try {
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`);
process.exit(1);
}
process.env['SAUCE_USERNAME'] = saucelabsParams.SAUCE_USERNAME;
process.env['SAUCE_ACCESS_KEY'] = saucelabsParams.SAUCE_ACCESS_KEY;
process.env['SAUCE_TUNNEL_IDENTIFIER'] = saucelabsParams.SAUCE_TUNNEL_IDENTIFIER;
process.env['SAUCE_LOCALHOST_ALIAS_DOMAIN'] = saucelabsParams.SAUCE_LOCALHOST_ALIAS_DOMAIN;
}
// Pass through the optional `SAUCE_LOCALHOST_ALIAS_DOMAIN` environment variable. The
// variable is usually specified on CI, but is not required for testing with Saucelabs.
if (!process.env['SAUCE_LOCALHOST_ALIAS_DOMAIN'] && saucelabsParams !== null) {
process.env['SAUCE_LOCALHOST_ALIAS_DOMAIN'] = saucelabsParams.SAUCE_LOCALHOST_ALIAS_DOMAIN;
}
const scStart = `${sauceService} start-ready-wait`;
@ -60,3 +66,15 @@ try {
console.error(e.stack || e);
process.exit(1);
}
function readLocalSauceConnectParams() {
try {
// The following path comes from /tools/saucelabs/sauce-service.sh.
// We setup the required saucelabs environment variables here for the karma test
// from a json file under /tmp/angular/sauce-service so that we don't break the
// test cache with a changing SAUCE_TUNNEL_IDENTIFIER provided through --test_env
return require('/tmp/angular/sauce-service/sauce-connect-params.json');
} catch {
return null;
}
}

View File

@ -130,7 +130,7 @@ service-setup-command() {
@fail "sc binary not found at ${SAUCE_CONNECT}"
fi
echo "{ \"SAUCE_USERNAME\": \"${SAUCE_USERNAME}\", \"SAUCE_ACCESS_KEY\": \"${SAUCE_ACCESS_KEY}\", \"SAUCE_TUNNEL_IDENTIFIER\": \"${SAUCE_TUNNEL_IDENTIFIER}\" }" > ${SAUCE_PARAMS_JSON_FILE}
echo "{ \"SAUCE_USERNAME\": \"${SAUCE_USERNAME}\", \"SAUCE_ACCESS_KEY\": \"${SAUCE_ACCESS_KEY}\", \"SAUCE_TUNNEL_IDENTIFIER\": \"${SAUCE_TUNNEL_IDENTIFIER}\", \"SAUCE_LOCALHOST_ALIAS_DOMAIN\": \"${SAUCE_LOCALHOST_ALIAS_DOMAIN}\" }" > ${SAUCE_PARAMS_JSON_FILE}
# Command arguments that will be passed to sauce-connect.
# By default we disable SSL bumping for all requests. This is because SSL bumping is
@ -147,6 +147,16 @@ service-setup-command() {
"--user ${SAUCE_USERNAME}"
# Don't add the --api-key here so we don't echo it out in service-pre-start
)
if [[ -n "${SAUCE_LOCALHOST_ALIAS_DOMAIN}" ]]; then
# Ensures that requests to the localhost alias domain are always resolved through the tunnel.
# This environment variable is usually configured on CI, and refers to a domain that has been
# locally configured in the current machine's hosts file (e.g. `/etc/hosts`). The domain should
# resolve to the current machine in Saucelabs VMs, so we need to ensure that it is resolved
# through the tunnel we going to create.
sauce_args+=("--tunnel-domains ${SAUCE_LOCALHOST_ALIAS_DOMAIN}")
fi
@echo "Sauce connect will be started with:"
echo " ${SAUCE_CONNECT} ${sauce_args[@]}"
SERVICE_COMMAND="${SAUCE_CONNECT} ${sauce_args[@]} --api-key ${SAUCE_ACCESS_KEY}"
@ -296,7 +306,7 @@ service-post-stop() {
fi
@wait_for "Waiting for start file" "${SERVICE_START_FILE}"
${SERVICE_COMMAND}
) >>"${SERVICE_LOG_FILE}" 2>&1
) >>"${SERVICE_LOG_FILE}" 2>&1
) &
echo $! >"${SERVICE_PID_FILE}"

157
yarn.lock
View File

@ -2,35 +2,27 @@
# yarn lockfile v1
"@angular-devkit/architect@0.900.0-rc.10":
version "0.900.0-rc.10"
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.0-rc.10.tgz#5fee2dd12de787d02c4c78d6d5dd53364bcaae25"
integrity sha512-85bHmwBOJ9nkQ4Ict4rPNF6ON/zHkxGWNST9gy3BgwBcNUO3Y/udywxO0j2/UE/dQ8wtIvqKZfUD7GgVEnLXdQ==
"@angular-devkit/architect@0.900.0-rc.14":
version "0.900.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.0-rc.14.tgz#cfdbee7899b9addfd9d43c638b0dbc21188f0a79"
integrity sha512-dgEc/zYE0uzv+m8JTdv3FDc7bViJKbxs8FY3zdkArc6MXIXpoMzgvveEEHvhrpO0iu6njW/xRSZYtYnTIY4xlw==
dependencies:
"@angular-devkit/core" "9.0.0-rc.10"
"@angular-devkit/core" "9.0.0-rc.14"
rxjs "6.5.3"
"@angular-devkit/architect@0.900.0-rc.11":
version "0.900.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.0-rc.11.tgz#e9f3e5e372d467a220027cf53231b88e8e857fbc"
integrity sha512-rRbq4ipppnY4FvVo89Cv+yC7rlt1/VFE/jaB77Ra2tI6zVlFWCTjnMzuc9TYz/3jK1ssThzgEA2sebPDmjH47w==
"@angular-devkit/build-angular@0.900.0-rc.14":
version "0.900.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.900.0-rc.14.tgz#2146316c0aca5311bfe139f7f7597ac025d792b2"
integrity sha512-KnSni3kCvJbiBj43wRoY2OYsOKVDfqWGhBZsX4IPrv6OVMfCsWH9b62pcvJ0n63Qw/AwEaE6HUvCQB3IBR3lVg==
dependencies:
"@angular-devkit/core" "9.0.0-rc.11"
rxjs "6.5.3"
"@angular-devkit/build-angular@0.900.0-rc.11":
version "0.900.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.900.0-rc.11.tgz#0bdec73d3ba631b3550527c54a35cf4145b0ed6d"
integrity sha512-lp0f5lRsiTYSPjIgiWtX2N0NgV7dUZ/ifXYqqAEURKZ5O0jFF2gt2x9R29TmyFzTQ3ZP8O5AojO7POh1OfJ6iA==
dependencies:
"@angular-devkit/architect" "0.900.0-rc.11"
"@angular-devkit/build-optimizer" "0.900.0-rc.11"
"@angular-devkit/build-webpack" "0.900.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/architect" "0.900.0-rc.14"
"@angular-devkit/build-optimizer" "0.900.0-rc.14"
"@angular-devkit/build-webpack" "0.900.0-rc.14"
"@angular-devkit/core" "9.0.0-rc.14"
"@babel/core" "7.7.7"
"@babel/generator" "7.7.7"
"@babel/preset-env" "7.7.7"
"@ngtools/webpack" "9.0.0-rc.11"
"@ngtools/webpack" "9.0.0-rc.14"
ajv "6.10.2"
autoprefixer "9.7.1"
babel-loader "8.0.6"
@ -95,10 +87,10 @@
typescript "3.2.4"
webpack-sources "1.3.0"
"@angular-devkit/build-optimizer@0.900.0-rc.10":
version "0.900.0-rc.10"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.0-rc.10.tgz#e2351297689185ed71b07d0537fc1d3c73e9b2b7"
integrity sha512-cQkOLwzIdhZgAzkpea2Pi1oS8C8BDo+aB06JchMpdRudi1+ArbTbsaH/2FYhHMD4jkK2XCfKT8yFx20J8t2lVg==
"@angular-devkit/build-optimizer@0.900.0-rc.14":
version "0.900.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.0-rc.14.tgz#e90e955e1daf5689ad198a5253134187c99b7b5a"
integrity sha512-MA2g8N9/cvzMvudEEjeaNV6STwSr8NI/znpv+nU6sQa4PdegIotBbqxGUmHMKtLH5cOwDy9hI47ANN+XADbIbQ==
dependencies:
loader-utils "1.2.3"
source-map "0.7.3"
@ -106,41 +98,19 @@
typescript "3.6.4"
webpack-sources "1.4.3"
"@angular-devkit/build-optimizer@0.900.0-rc.11":
version "0.900.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.0-rc.11.tgz#96c2446fa9cd2e90700ab8a68312b28b3907f6d9"
integrity sha512-GJC+7H7ER6bxDC2UdAGwW357EYHpv8ISKKmS19wdJV5gZPMPANcpbg9FIpl27SDhUyZX9C2DOrcATvYYFoYgDQ==
"@angular-devkit/build-webpack@0.900.0-rc.14":
version "0.900.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.0-rc.14.tgz#b932148f14ed0056f1885c98c330411a80d31331"
integrity sha512-HvrDapIKr4k2a7Tf7MdW0miGOUUzHxRkGyDIWJBDXLbfOIt9BnhKfFGxP/SyDlwJnLyat9yYZjcDu1AI0E1Dmw==
dependencies:
loader-utils "1.2.3"
source-map "0.7.3"
tslib "1.10.0"
typescript "3.6.4"
webpack-sources "1.4.3"
"@angular-devkit/build-webpack@0.900.0-rc.11":
version "0.900.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.0-rc.11.tgz#d9a91c2b67a629f6adfe87980d26e495f2e30e0a"
integrity sha512-utBAnkO6WLi323Rto1s7TJpaDRqDNR8jkD0C0PG5Zm3y1U9ARbAjTkugkrB/7bc4gEIqWZD+1dLYaaJCidye2Q==
dependencies:
"@angular-devkit/architect" "0.900.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/architect" "0.900.0-rc.14"
"@angular-devkit/core" "9.0.0-rc.14"
rxjs "6.5.3"
"@angular-devkit/core@9.0.0-rc.10":
version "9.0.0-rc.10"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.0-rc.10.tgz#e751cedf6483026bbb3f9a5a6ab9c6e9833e1c3a"
integrity sha512-aEdHb9M1rwAsyJSkmQ8J4BRiRLK4zWQL/CXxK15c056H04ncwU8OntBChpnSIf5iGsBM9UQRtiFbRubLfrpxgQ==
dependencies:
ajv "6.10.2"
fast-json-stable-stringify "2.0.0"
magic-string "0.25.4"
rxjs "6.5.3"
source-map "0.7.3"
"@angular-devkit/core@9.0.0-rc.11":
version "9.0.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.0-rc.11.tgz#9e69545eb21284a573ad78e4c33003f2ea25afd5"
integrity sha512-ki7Sln+mQdCctJNBalzy70tiFn2hOCY2Yyte8B0xKWVHnofZySvG+ANzoLgodnKFOBH18AQy35FhgzZM++N9tQ==
"@angular-devkit/core@9.0.0-rc.14":
version "9.0.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.0-rc.14.tgz#5cff058750c0b063a6f5fa1a2e830f1f48ffa56b"
integrity sha512-hFiKoAPtnOqqYv97Y22OgyeTFxjNU/6WDhmuXkfbZDKychvuBLDOdgUhL43heEzavSfCCl23E0JmilwCUcepmw==
dependencies:
ajv "6.10.2"
fast-json-stable-stringify "2.0.0"
@ -159,21 +129,12 @@
rxjs "6.5.3"
source-map "0.7.3"
"@angular-devkit/schematics@9.0.0-rc.10":
version "9.0.0-rc.10"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.0-rc.10.tgz#65d5e3fbf6a0c7c0689f3ac27cc1b629ca6c8570"
integrity sha512-cuy+gDOhzf04vhJHsR21HnkEcOZqyfFabNs90Q5H77iGWl7GUO/RhwV7tXADdKZ4ee14rfFQi3TA0SrcOMXQlA==
"@angular-devkit/schematics@9.0.0-rc.14":
version "9.0.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.0-rc.14.tgz#4605b1ee9f18b772094697f9b35258fdac76d4b3"
integrity sha512-i/XTxo7hTXTFKus51Qry3rRGHL2uS4SgufGqdvOcy2qZbjyh/wt0UDOGJu/w8dcA9pJm+vFBLAbnro5oFyIsVw==
dependencies:
"@angular-devkit/core" "9.0.0-rc.10"
ora "4.0.2"
rxjs "6.5.3"
"@angular-devkit/schematics@9.0.0-rc.11":
version "9.0.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.0-rc.11.tgz#e0d4d271d8d783ebf05eced576262f20e6c3562c"
integrity sha512-aJqOLzsoAkVj3AVTf1ehH2hA9wHHz1+7TTtfqI+Yx+S3jFyvGmnKrNBCKtMuIV5JdEHiXmhhuGbNBHwRFWpOow==
dependencies:
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.14"
ora "4.0.2"
rxjs "6.5.3"
@ -189,16 +150,16 @@
"@angular/bazel@file:./tools/npm/@angular_bazel":
version "0.0.0"
"@angular/cli@9.0.0-rc.11":
version "9.0.0-rc.11"
resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-9.0.0-rc.11.tgz#5d830045bb95f4a38a1d0df02212207731061a57"
integrity sha512-Du0y6rpOfGkH7h6ukZf5SKgpTv0uAZ5McNFrPAH2KFs7PgM4fyj9VmJ1lSns9WsVcEHdPlIPh8WGResUzvePdA==
"@angular/cli@9.0.0-rc.14":
version "9.0.0-rc.14"
resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-9.0.0-rc.14.tgz#4f43bb0eb9a18b8f5e9001ec0a9de01a20c31870"
integrity sha512-qdktJY0swHMfAgx2+b7jbguNsONQLRLt2X910kRY8KdiCJDXAc2dPgk8lN4K1jzpPnyzWx/0cNcDhsIzsyLDrw==
dependencies:
"@angular-devkit/architect" "0.900.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/schematics" "9.0.0-rc.11"
"@schematics/angular" "9.0.0-rc.11"
"@schematics/update" "0.900.0-rc.11"
"@angular-devkit/architect" "0.900.0-rc.14"
"@angular-devkit/core" "9.0.0-rc.14"
"@angular-devkit/schematics" "9.0.0-rc.14"
"@schematics/angular" "9.0.0-rc.14"
"@schematics/update" "0.900.0-rc.14"
"@yarnpkg/lockfile" "1.1.0"
ansi-colors "4.1.1"
debug "^4.1.1"
@ -1269,12 +1230,12 @@
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.12.12.tgz#6692f1cbca664f68abbc62f9a26459fba8b9ff28"
integrity sha512-5EzH1gHIonvvgA/xWRmVAJmRkTQj/yayUXyr66hFwNZiFE4j7lP8is9YQeXhwxGZEjO1PVMblAmFF0CyjNtPGw==
"@ngtools/webpack@9.0.0-rc.11":
version "9.0.0-rc.11"
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.0-rc.11.tgz#10b5997bec7cf48d1b144c8b4d46ffd0039c522a"
integrity sha512-qeW81ISiO8GVEndOaCYv0k6fzRIxzZs6jrXGl1pcLH1H6qv2mxhA5DA0vC/9TN6wenrS43RGjDIQpp+RvkiLwA==
"@ngtools/webpack@9.0.0-rc.14":
version "9.0.0-rc.14"
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.0-rc.14.tgz#6a764138347d2ff3846753a141eaacdab3b0658c"
integrity sha512-G98u14exE36kR4LflWB20ClJ6ql9B0qMcyokepjwpVAgaoDfpJRR7mKAZliMPd0KFXktdnct2QEyF6pbLevO7w==
dependencies:
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.14"
enhanced-resolve "4.1.1"
rxjs "6.5.3"
webpack-sources "1.4.3"
@ -1332,13 +1293,13 @@
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
"@schematics/angular@9.0.0-rc.11":
version "9.0.0-rc.11"
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.0-rc.11.tgz#d544c0d4e7b3dd59ed56be5183e038ebe06a165e"
integrity sha512-9InC+F71KiPXE0jl7Ow4iPFJ2AZZDbfTM6yWZoYLk3hzTCohAZZciBl00Tfyu2uerGshx8akbJMLySjXtf+q0g==
"@schematics/angular@9.0.0-rc.14":
version "9.0.0-rc.14"
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.0-rc.14.tgz#4112aeb6c76144893d65cab9f53ca8422adc3bbb"
integrity sha512-NWxDLym2Sst5lTvV7QYkVUjy3N0CfCohhdWC4DGRtjUyTD2eUepAg1PZCQcq8U2iRtd78Lm1n4obDWO1tW3pXQ==
dependencies:
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/schematics" "9.0.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.14"
"@angular-devkit/schematics" "9.0.0-rc.14"
"@schematics/angular@9.0.0-rc.8":
version "9.0.0-rc.8"
@ -1348,13 +1309,13 @@
"@angular-devkit/core" "9.0.0-rc.8"
"@angular-devkit/schematics" "9.0.0-rc.8"
"@schematics/update@0.900.0-rc.11":
version "0.900.0-rc.11"
resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.900.0-rc.11.tgz#d22df30f13a6f38970b759db61ad84d3f9b03a78"
integrity sha512-nV0oCPzzd0vi2Exo1910rWXwz/RnMc4zF9FxSOCZzsIv+AkwIehhL815OKyjUSCzU9+IM0/o1LKkPPrSWK7QEA==
"@schematics/update@0.900.0-rc.14":
version "0.900.0-rc.14"
resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.900.0-rc.14.tgz#1debea3eb90559d25838e7b256b48bac216e19d9"
integrity sha512-ZlsneHwpvrtpt0D10g4S8JftLaSFQtSO+kOD1uP26OxNMg9w54jrlr7xWSwAmT69/ETjNy8BFKXdcU9yvYixPA==
dependencies:
"@angular-devkit/core" "9.0.0-rc.11"
"@angular-devkit/schematics" "9.0.0-rc.11"
"@angular-devkit/core" "9.0.0-rc.14"
"@angular-devkit/schematics" "9.0.0-rc.14"
"@yarnpkg/lockfile" "1.1.0"
ini "1.3.5"
npm-package-arg "^7.0.0"