Compare commits

..

57 Commits
7.0.1 ... 7.0.2

Author SHA1 Message Date
77f531b6f7 release: cut the v7.0.2 release 2018-10-31 16:05:54 -07:00
3041240cbc build: remove problematic yarn prefix for running bazel 2018-10-31 16:03:29 -07:00
257ac83095 fix(core): Remove static dependency from @angular/core to @angular/compiler (#26734) (#26879) 2018-10-31 13:14:01 -07:00
bc93d47129 build(bazel): remove undeclared dep (#26875)
PR Close #26875
2018-10-31 12:50:28 -04:00
3f61071638 build(bazel): fix bad merge in BUILD file (#26875)
PR Close #26875
2018-10-31 12:50:28 -04:00
ea571aa9d1 build(bazel): generalize fix for AMD name for flat module out file (#26837)
PR Close #26837
2018-10-30 18:37:12 -04:00
40cd0371d2 docs: fixup deployment guide (#26486)
- remove sections that were not relevant (all the development stuff)
- fix incorrect info

PR Close #26486
2018-10-30 16:29:04 -04:00
8356577670 docs: Removing duplicate lines (#26754)
Duplicate lines are removed to avoid confusion.
PR Close #26754
2018-10-30 16:24:51 -04:00
45d3c8093b docs: fix typo (#26776)
PR Close #26776
2018-10-30 16:24:13 -04:00
e7eec2e44b docs: fix typo (#26773)
PR Close #26773
2018-10-30 16:23:49 -04:00
c44b93253c build: use bazel version from node modules (#26691)
* No longer depends on a custom CircleCI docker image that comes with Bazel pre-installed. Since Bazel is now available through NPM, we should be able to use the version from `@bazel/bazel` in order to enforce a consistent environment on CI and locally.
* This also reduces the amount of packages that need to be published (ngcontainer is removed)

PR Close #26691
2018-10-30 16:19:13 -04:00
cd444bc2ba build: Move non-bazel deps to devDependencies (#26691)
This makes yarn_install of ngdeps under Bazel faster, since we don't need many of the large dependencies.
It's important because downstream angular/bazel users will observe the same install time.

PR Close #26691
2018-10-30 16:19:13 -04:00
e9ae26a272 docs: replace unused variable by _ (#26768)
replace unused variable by _  to keep the code consistent between examples

PR Close #26768
2018-10-30 13:49:52 -04:00
f9856974e3 docs: describe your change... (#26784)
PR Close #26784
2018-10-30 13:49:12 -04:00
b3c6409763 fix(core): support computed base class in metadata inheritance (#24014)
PR Close #24014
2018-10-30 13:48:22 -04:00
4c3e9a32d2 docs(changelog): remove reverted fix from 6.1.10 changelog (#26401)
PR Close #26401
2018-10-30 13:47:47 -04:00
2700952040 build: fix ts-api-guardian does not work on windows w/ bazel (#26761)
* Fixes that the `ts-api-guardian` package does not work on Windows with Bazel. This is because `ts-api-guardian` does not resolve the runfiles through theNodeJS `require` function that properly handles runfiles within Bazel.

PR Close #26761
2018-10-30 13:45:58 -04:00
6d92c99c49 build: add option to disable ts-api-guardian default angular tag rules (#26761)
Since the API guardian can be also used by other projects, we should not set up the default Angular project tag rules unless specified explicitly through a given command option (`useAngularTagRules`)

PR Close #26761
2018-10-30 13:45:58 -04:00
7cefb3efd4 docs: configuration file reference (#26484)
PR Close #26484
2018-10-30 13:44:53 -04:00
1c0ab3468d docs: update example dependencies to Angular/CLI/Universal V7 releases (#26820)
PR Close #26820
2018-10-30 13:44:24 -04:00
b5ede01c09 build(docs-infra): move CLI API desciption higher up (#26568)
Closes #26556

PR Close #26568
2018-10-29 13:01:09 -04:00
98b1a9dcfe ci(docs-infra): notify caretaker about aio_monitoring failures (#26649)
PR Close #26649
2018-10-29 13:00:21 -04:00
c277c198d2 test(docs-infra): make redirection tests more robust (#26649)
PR Close #26649
2018-10-29 13:00:21 -04:00
b7d7609872 test(docs-infra): make smoke tests more robust (#26649)
PR Close #26649
2018-10-29 13:00:21 -04:00
415e3e06ed test(docs-infra): fix smoke tests (#26649)
PR Close #26649
2018-10-29 13:00:21 -04:00
0f7a850699 test(docs-infra): run basic smoke tests against PR previews (#26649)
This makes the tests run agaisnt the deployed production versions (as
part of the `aio_monitoring` job) more reliable.

PR Close #26649
2018-10-29 13:00:21 -04:00
1e2525b8a7 test: mark public_api_guard test with fixme-ivy-aot and no-ivy-jit (#26602)
These tests are currently broken because of the following reasons:
- ivy no longer emits a generated index, so the filename of the main d.ts file is different
- ivy currently exports some symbols that don't match the golden file, this needs investigation

PR Close #26602
2018-10-29 12:59:47 -04:00
bc9f534bf4 build: fix the accept binary path in ts-api-guardian error message (#26602)
Fixes #26589

PR Close #26602
2018-10-29 12:59:47 -04:00
ea2a3ca705 build: remove unused @angular/compiler ts-api-guardian golden files (#26602)
these files are not used because the api surface of this package is not considered
to be stable/public api.

the presence of these files only confuses the reader.

PR Close #26602
2018-10-29 12:59:47 -04:00
802e996e64 build: don't depend on npm packages from public api tests (#26602)
We need only the inputs from ng_module.

PR Close #26602
2018-10-29 12:59:47 -04:00
aa7dd1267b docs: add ant design mobile of angular in resources (#26562)
PR Close #26562
2018-10-26 18:10:46 -04:00
91916e7113 docs: fix indentation (#26623)
PR Close #26623
2018-10-26 18:10:15 -04:00
0e92f1eee5 docs: add links to angular subdomains (#26653)
Add link to protactor.angular.io
Replace link from github.com/angular/universal to universal.angular.io
Replace link from github.com/angular/material2 to material.angular.io

fix #18257

PR Close #26653
2018-10-26 18:09:45 -04:00
4ac3b2e2bd build(docs-infra): ensure that CLI code blocks are not auto-linked (#26675)
Some of the text in CLI API docs were being auto-linked to API
pages. This was not correct, and in fact these blocks should not
have any auto links to Angular API at all.

Closes #26570

PR Close #26675
2018-10-26 18:09:21 -04:00
20ce134961 build(docs-infra): mark code blocks to disable auto-linking (#26675)
You can now mark `<code>` blocks with a `no-auto-link` css class
to tell the code auto-linker to ignore this code block.

PR Close #26675
2018-10-26 18:09:21 -04:00
c01f3409f3 fix(compiler): generate relative paths only in summary file errors (#26759)
Previously errors in the summary file would include absolute file names.
This is undesirable as the output of a build should not depend on the
current working directory. Doing so causes nondeterminism issues in
builds.

PR Close #26759
2018-10-26 18:07:55 -04:00
71580c8e37 ci: configure chrome options for protractor (#26735) (#26788)
so that they are more suitable for CI usage.

PR Close #26735

PR Close #26788
2018-10-26 15:46:35 -04:00
e58f8b7be0 ci: mark //modules/benchmarks/src/largetable/render3:perf with fixme-ivy-* tags (#26735) (#26788)
This target fails with odd error that we need to investigate:

[01:19:32] I/direct - Using ChromeDriver directly...
[01:19:32] E/direct - Error code: 135
[01:19:32] E/direct - Error message: Could not find chromedriver at /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/external/ngdeps/node_modules/webdriver-manager/selenium/chromedriver_2.41. Run 'webdriver-manager update' to download binaries.
[01:19:32] E/direct - Error: Could not find chromedriver at /home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/external/ngdeps/node_modules/webdriver-manager/selenium/chromedriver_2.41. Run 'webdriver-manager update' to download binaries.

PR Close #26735

PR Close #26788
2018-10-26 15:46:35 -04:00
046c96a3f1 ci: use yarn test-ivy-... (#26735) (#26788)
This means that we use the same command to run test on CI as when developing locally.

PR Close #26735

PR Close #26788
2018-10-26 15:46:35 -04:00
00e6569e0f build: fix symbol-extractor by passing through "compile" as environmental variable (#26735) (#26788)
PR Close #26735

PR Close #26788
2018-10-26 15:46:35 -04:00
5dbf9f721b test(ivy): fix or disable failing ivy tests (#26735) (#26788)
These tests were previously not running on CI so they have always been broken,
or got broken just recently :-(.

test(ivy): mark failing test targets with fixme-ivy-jit and fixme-ivy-local tags

PR Close #26735

PR Close #26788
2018-10-26 15:46:35 -04:00
c63bc02846 build: remove ivy build/test tag hackery now that we can (#26735) (#26788)
With https://github.com/bazelbuild/rules_nodejs/pull/388 fixed we can stop messing around
with tags and just rely on the explicitly defined tags.

PR Close #26735

PR Close #26788
2018-10-26 15:46:35 -04:00
2f3308e4f0 docs: rename ivy compile mode 'local' to 'aot' in BAZEL.md (#26735) (#26788)
PR Close #26735

PR Close #26788
2018-10-26 15:46:35 -04:00
cc5e4fb93f ci: move CircleCI env variables definition to shell script (#26786)
PR Close #26786
2018-10-26 13:26:57 -04:00
3ab9947c7f ci: add more info on how CircleCI env vars are defined (#26786)
PR Close #26786
2018-10-26 13:26:57 -04:00
b1f92db22b ci: run Xvfb in the background on CircleCI (#26786)
PR Close #26786
2018-10-26 13:26:57 -04:00
bda1e52b50 build(docs-infra): include inherited members in search index (#26676)
Closes #23800

PR Close #26676
2018-10-26 13:16:33 -04:00
1084ebc091 build(docs-infra): refactor generateKeywords processor (#26676)
PR Close #26676
2018-10-26 13:16:33 -04:00
5a3af00398 ci(docs-infra): split test_and_deploy_aio to two separate jobs (#26746)
By splitting the jobs, if something goes wrong with deploying (e.g. a
network issue), we can re-run just that part instead of having to wait
for all the tests to complete again.

In terms of total duration, the difference should be minimal, because
the two operations (testing and deploying) do not depend on shared
tasks. For example, we need to build again (for the specific target
environment; e.g. stable, next, etc.) before deploying anyway.

PR Close #26746
2018-10-25 21:17:53 -04:00
7a088af3ff build: clean up *.gz files created by payload-size.sh (#26746)
These files are not needed once the size has been calculated and there
is no point in keeping them around.

Deleting them prevents, for example, uploading unnecessary files from
`aio/dist/` to Firebase (because `deploy-to-firebase.sh` runs the
payload size checks right before deploying).

PR Close #26746
2018-10-25 21:17:53 -04:00
3e8d8ec2f5 ci(docs-infra): reduce verbosity of yarn build on CI (#26746)
PR Close #26746
2018-10-25 21:17:53 -04:00
d4ea7f1f7e ci(docs-infra): fix deployment to Firebase (#26746)
Previously, `firebase-tools@3.x` was used and the deployment from
CircleCI failed with `Unexpected error` (HTTP code: 410).

This commit ensures that we use a recent version of `firebase-tools` for
deploying to Firebase. It also ensures that we use the locally installed
`firebase-tools` (not sure where it came from before 😁).

PR Close #26746
2018-10-25 21:17:53 -04:00
23096501e2 build(docs-infra): upgrade cli command docs sources to 4faa81e25 (#26741)
PR Close #26741
2018-10-25 21:10:21 -04:00
023874426e test(upgrade): make e2e tests for upgrade docs examples less flaky (#26726)
PR Close #26726
2018-10-24 19:49:14 -04:00
aeffcdd417 test(elements): make e2e tests for elements docs examples even less flaky (#26726)
PR Close #26726
2018-10-24 19:49:14 -04:00
6d7d7c77e3 ci: only publish builds if relevant aio jobs pass (#26722)
Some of the `aio`-/`docs`-related jobs rely on the locally built Angular
packages. When these jobs fail, it could mean that there is an issue
with the Angular packages (e.g. an unintentional breaking change).

This commit ensures that the `publish_artifacts` job is not run, unless
those `aio`-/`docs`-related jobs pass.

(The `test_aio_tools` job also uses the locally built Angular packages,
but it does not exercise them in a meaningful way to be worth making it
a prerequisite for `publish_artifacts`.)

PR Close #26722
2018-10-24 19:48:41 -04:00
8da6c369e5 build(docs-infra): fix parameter type rendering (#26688)
Closes #24355

PR Close #26688
2018-10-24 19:48:10 -04:00
139 changed files with 4477 additions and 5286 deletions

View File

@ -13,7 +13,7 @@ a GitHub token that enables publishing snapshots.
To create the github_token file, we take this approach:
- Find the angular-builds:token in http://valentine
- Go inside the ngcontainer docker image so you use the same version of openssl as we will at runtime: `docker run --rm -it angular/ngcontainer`
- Go inside the CircleCI default docker image so you use the same version of openssl as we will at runtime: `docker run --rm -it circleci/node:10.12`
- echo "https://[token]:@github.com" > credentials
- openssl aes-256-cbc -e -in credentials -out .circleci/github_token -k $KEY
- If needed, base64-encode the result so you can copy-paste it out of docker: `base64 github_token`

View File

@ -7,40 +7,20 @@
# To validate changes, use an online parser, eg.
# http://yaml-online-parser.appspot.com/
# Variables
## IMPORTANT
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
var_1: &docker_image angular/ngcontainer:0.7.0
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.7.0
# Note that the browser docker image comes with Chrome and Firefox preinstalled. This is just
# needed for jobs that run tests without Bazel. Bazel runs tests with browsers that will be
# fetched by the Webtesting rules. Therefore for jobs that run tests with Bazel, we don't need a
# docker image with browsers pre-installed.
# **NOTE**: If you change the version of the docker images, also change the `cache_key` suffix.
var_1: &default_docker_image circleci/node:10.12
var_2: &browsers_docker_image circleci/node:10.12-browsers
var_3: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-node-10.12
# Define common ENV vars
var_3: &define_env_vars
var_4: &define_env_vars
run:
name: Define environment variables
command: |
echo "export PROJECT_ROOT=$(pwd)" | tee -a $BASH_ENV
echo "export CI_AIO_MIN_PWA_SCORE=95" | tee -a $BASH_ENV
# This is the branch being built; e.g. `pull/12345` for PR builds.
echo "export CI_BRANCH=$CIRCLE_BRANCH" | tee -a $BASH_ENV
echo "export CI_COMMIT=$CIRCLE_SHA1" | tee -a $BASH_ENV
# `CI_COMMIT_RANGE` will only be available when `CIRCLE_COMPARE_URL` is also available,
# i.e. on push builds (a.k.a. non-PR builds). That is fine, since we only need it in push builds.
echo "export CI_COMMIT_RANGE=$(sed -r 's|^.*/([0-9a-f]+\.\.\.[0-9a-f]+)$|\1|i' <<< ${CIRCLE_COMPARE_URL:-})" | tee -a $BASH_ENV
echo "export CI_PULL_REQUEST=${CIRCLE_PR_NUMBER:-false}" | tee -a $BASH_ENV
echo "export CI_REPO_NAME=$CIRCLE_PROJECT_REPONAME" | tee -a $BASH_ENV
echo "export CI_REPO_OWNER=$CIRCLE_PROJECT_USERNAME" | tee -a $BASH_ENV
# WARNING: Secrets (do not print).
echo "export CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN=$AIO_DEPLOY_TOKEN" >> $BASH_ENV
echo "export CI_SECRET_PAYLOAD_FIREBASE_TOKEN=$ANGULAR_PAYLOAD_TOKEN" >> $BASH_ENV
# See remote cache documentation in /docs/BAZEL.md
var_4: &setup-bazel-remote-cache
run:
name: Start up bazel remote cache proxy
command: ~/bazel-remote-proxy -backend circleci://
background: true
command: ./.circleci/env.sh
var_5: &setup_bazel_remote_execution
run:
@ -48,59 +28,73 @@ var_5: &setup_bazel_remote_execution
command: openssl aes-256-cbc -d -in .circleci/gcp_token -k "$CI_REPO_NAME" -out /home/circleci/.gcp_credentials && echo "export GOOGLE_APPLICATION_CREDENTIALS=/home/circleci/.gcp_credentials" >> $BASH_ENV && sudo bash -c "cat .circleci/rbe-bazel.rc >> /etc/bazel.bazelrc"
# Settings common to each job
anchor_1: &job_defaults
var_6: &job_defaults
working_directory: ~/ng
docker:
- image: *docker_image
- image: *default_docker_image
var_7: &start-xvfb
run:
name: Running X virtual framebuffer
command: Xvfb :99 -screen 0 1280x1024x24
background: true
# After checkout, rebase on top of master.
# Similar to travis behavior, but not quite the same.
# See https://discuss.circleci.com/t/1662
anchor_2: &post_checkout
var_8: &post_checkout
post: git pull --ff-only origin "refs/pull/${CI_PULL_REQUEST//*pull\//}/merge"
var_9: &yarn_install
run:
name: Running Yarn install
command: yarn install --frozen-lockfile --non-interactive
var_10: &setup_circleci_bazel_config
run:
name: Setting up CircleCI bazel configuration
command: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
version: 2
jobs:
lint:
<<: *job_defaults
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
# Check BUILD.bazel formatting before we have a node_modules directory
# Then we don't need any exclude pattern to avoid checking those files
- run: 'yarn buildifier -mode=check ||
(echo "BUILD files not formatted. Please run ''yarn buildifier''" ; exit 1)'
# Run the skylark linter to check our Bazel rules
- run: 'yarn skylint ||
(echo -e "\n.bzl files have lint errors. Please run ''yarn skylint''"; exit 1)'
- restore_cache:
key: *cache_key
- run: yarn install --frozen-lockfile --non-interactive
- run: ./node_modules/.bin/gulp lint
test:
<<: *job_defaults
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- run: bazel info release
- run: bazel run @nodejs//:yarn
# Setup remote execution and run RBE-compatible tests.
- *setup_bazel_remote_execution
- run: bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only,-local
- run: yarn bazel test //... --build_tag_filters=-ivy-only --test_tag_filters=-ivy-only,-local
# Now run RBE incompatible tests locally.
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: bazel test //... --build_tag_filters=-ivy-only,local --test_tag_filters=-ivy-only,local
- run: yarn bazel test //... --build_tag_filters=-ivy-only,local --test_tag_filters=-ivy-only,local
# CircleCI will allow us to go back and view/download these artifacts from past builds.
# Also we can use a service like https://buildsize.org/ to automatically track binary size of these artifacts.
@ -134,14 +128,16 @@ jobs:
steps:
# don't run this job on the patch branch (to preserve resources)
- run: circleci step halt
- *define_env_vars
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: bazel run @yarn//:yarn
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
- run: bazel test //... --define=compile=jit --build_tag_filters=ivy-jit --test_tag_filters=ivy-jit
- run: yarn test-ivy-jit //...
test_ivy_aot:
<<: *job_defaults
@ -149,77 +145,96 @@ jobs:
steps:
# don't run this job on the patch branch (to preserve resources)
- run: circleci step halt
- *define_env_vars
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: bazel run @yarn//:yarn
- *setup_bazel_remote_execution
- run: bazel test //... --define=compile=aot --build_tag_filters=ivy-aot --test_tag_filters=ivy-aot
test_and_deploy_aio:
<<: *job_defaults
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
- run: yarn test-ivy-aot //...
test_aio:
<<: *job_defaults
docker:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *start-xvfb
# Build aio
- run: yarn --cwd aio build --progress=false
# Lint the code
- run: yarn --cwd aio lint
# Run PWA-score tests
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
- run:
name: Run PWA-score tests
command: xvfb-run --auto-servernum yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Check the bundle sizes.
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
- run: yarn --cwd aio payload-size
# Run unit tests
- run: xvfb-run --auto-servernum yarn --cwd aio test --watch=false
- run: yarn --cwd aio test --watch=false
# Run e2e tests
- run: xvfb-run --auto-servernum yarn --cwd aio e2e
- run: yarn --cwd aio e2e
# Run unit tests for Firebase redirects
- run: yarn --cwd aio redirects-test
deploy_aio:
<<: *job_defaults
docker:
# Needed because before deploying the deploy-production script runs the PWA score tests.
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *start-xvfb
# Deploy angular.io to production (if necessary)
- run: echo "export CI_STABLE_BRANCH=$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')" | tee -a $BASH_ENV
- run: xvfb-run --auto-servernum yarn --cwd aio deploy-production
- run: setPublicVar CI_STABLE_BRANCH "$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')"
- run: yarn --cwd aio deploy-production
test_aio_local:
<<: *job_defaults
docker:
# Needed because the AIO tests and the PWA score test depend on Chrome being available.
- image: *browsers_docker_image
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- attach_workspace:
at: dist
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
- *start-xvfb
# Build aio (with local Angular packages)
- run: yarn --cwd aio build-local --progress=false
# Run PWA-score tests
# (Run before unit and e2e tests, which destroy the `dist/` directory.)
- run:
name: Run PWA-score tests
command: xvfb-run --auto-servernum yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
- run: yarn --cwd aio test-pwa-score-localhost $CI_AIO_MIN_PWA_SCORE
# Run unit tests
- run: xvfb-run --auto-servernum yarn --cwd aio test --watch=false
- run: yarn --cwd aio test --watch=false
# Run e2e tests
- run: xvfb-run --auto-servernum yarn --cwd aio e2e
- run: yarn --cwd aio e2e
test_aio_tools:
<<: *job_defaults
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- attach_workspace:
at: dist
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
# Install
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
- run: yarn --cwd aio extract-cli-command-docs
@ -229,37 +244,45 @@ jobs:
test_docs_examples_0:
<<: *job_defaults
docker:
# Needed because the example e2e tests depend on Chrome.
- image: *browsers_docker_image
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- attach_workspace:
at: dist
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
- *start-xvfb
# Install root
- run: yarn install --frozen-lockfile --non-interactive
- *yarn_install
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# Run examples tests
- run: xvfb-run --auto-servernum yarn --cwd aio example-e2e --setup --local --shard=0/2
- run: yarn --cwd aio example-e2e --setup --local --shard=0/2
test_docs_examples_1:
<<: *job_defaults
docker:
# Needed because the example e2e tests depend on Chrome.
- image: *browsers_docker_image
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- attach_workspace:
at: dist
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- *define_env_vars
- *start-xvfb
# Install root
- run: yarn install --frozen-lockfile --non-interactive
- *yarn_install
# Install aio
- run: yarn --cwd aio install --frozen-lockfile --non-interactive
# Run examples tests
- run: xvfb-run --auto-servernum yarn --cwd aio example-e2e --setup --local --shard=1/2
- run: yarn --cwd aio example-e2e --setup --local --shard=1/2
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
aio_preview:
@ -267,12 +290,12 @@ jobs:
environment:
AIO_SNAPSHOT_ARTIFACT_PATH: &aio_preview_artifact_path 'aio/tmp/snapshot.tgz'
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- run: yarn install --frozen-lockfile --non-interactive
- *define_env_vars
- *yarn_install
- run: ./aio/scripts/build-artifacts.sh $AIO_SNAPSHOT_ARTIFACT_PATH $CI_PULL_REQUEST $CI_COMMIT
- store_artifacts:
path: *aio_preview_artifact_path
@ -283,16 +306,20 @@ jobs:
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
test_aio_preview:
<<: *job_defaults
docker:
# Needed because the test-preview script runs e2e tests and the PWA score test with Chrome.
- image: *browsers_docker_image
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *start-xvfb
- run: yarn install --cwd aio --frozen-lockfile --non-interactive
- run:
name: Wait for preview and run tests
command: xvfb-run --auto-servernum node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE
command: node aio/scripts/test-preview.js $CI_PULL_REQUEST $CI_COMMIT $CI_AIO_MIN_PWA_SCORE
# This job exists only for backwards-compatibility with old scripts and tests
# that rely on the pre-Bazel dist/packages-dist layout.
@ -305,12 +332,15 @@ jobs:
<<: *job_defaults
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: bazel run @nodejs//:yarn
- restore_cache:
key: *cache_key
- *define_env_vars
- *setup_circleci_bazel_config
- *yarn_install
- *setup_bazel_remote_execution
- run: scripts/build-packages-dist.sh
# Save the npm packages from //packages/... for other workflow jobs to read
@ -330,23 +360,31 @@ jobs:
# See comments inside the integration/run_tests.sh script.
integration_test:
<<: *job_defaults
docker:
# Needed because the integration tests expect Chrome to be installed (e.g cli-hello-world)
- image: *browsers_docker_image
# Note: we run Bazel in one of the integration tests, and it can consume >2G
# of memory. Together with the system under test, this can exhaust the RAM
# on a 4G worker so we use a larger machine here too.
resource_class: xlarge
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- attach_workspace:
at: dist
- run: xvfb-run --auto-servernum ./integration/run_tests.sh
- *define_env_vars
- *start-xvfb
- run: ./integration/run_tests.sh
# This job updates the content of repos like github.com/angular/core-builds
# for every green build on angular/angular.
publish_snapshot:
<<: *job_defaults
steps:
- checkout:
<<: *post_checkout
- *define_env_vars
# See below - ideally this job should not trigger for non-upstream builds.
# But since it does, we have to check this condition.
@ -358,8 +396,6 @@ jobs:
|| "$CI_REPO_OWNER" != "angular"
|| "$CI_REPO_NAME" != "angular"
]] && circleci step halt || true'
- checkout:
<<: *post_checkout
- attach_workspace:
at: dist
# CircleCI has a config setting to force SSH for all github connections
@ -373,15 +409,24 @@ jobs:
aio_monitoring:
<<: *job_defaults
docker:
# This job needs Chrome to be globally installed because the tests run with Protractor
# which does not load the browser through the Bazel webtesting rules.
- image: *browsers_docker_image
steps:
- *define_env_vars
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *start-xvfb
- run:
name: Run tests against the deployed apps
command: xvfb-run --auto-servernum ./aio/scripts/test-production.sh $CI_AIO_MIN_PWA_SCORE
command: ./aio/scripts/test-production.sh $CI_AIO_MIN_PWA_SCORE
- run:
name: Notify caretaker about failure
command: 'curl --request POST --header "Content-Type: application/json" --data "{\"text\":\":x: \`$CIRCLE_JOB\` job failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}" $CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL'
when: on_fail
workflows:
version: 2
@ -392,7 +437,10 @@ workflows:
- test_ivy_jit
- test_ivy_aot
- build-packages-dist
- test_and_deploy_aio
- test_aio
- deploy_aio:
requires:
- test_aio
- test_aio_local:
requires:
- build-packages-dist
@ -427,6 +475,10 @@ workflows:
- test_ivy_jit
- test_ivy_aot
- integration_test
# Only publish if `aio`/`docs` tests using the locally built Angular packages pass
- test_aio_local
- test_docs_examples_0
- test_docs_examples_1
# Get the artifacts to publish from the build-packages-dist job
# since the publishing script expects the legacy outputs layout.
- build-packages-dist

View File

@ -0,0 +1,38 @@
####################################################################################################
# Helpers for defining environment variables for CircleCI.
#
# In CircleCI, each step runs in a new shell. The way to share ENV variables across steps is to
# export them from `$BASH_ENV`, which is automatically sourced at the beginning of every step (for
# the default `bash` shell).
#
# See also https://circleci.com/docs/2.0/env-vars/#using-bash_env-to-set-environment-variables.
####################################################################################################
# Set and print an environment variable.
#
# Use this function for setting environment variables that are public, i.e. it is OK for them to be
# visible to anyone through the CI logs.
#
# Usage: `setPublicVar <name> <value>`
function setPublicVar() {
setSecretVar $1 $2;
echo "$1=$2";
}
# Set (without printing) an environment variable.
#
# Use this function for setting environment variables that are secret, i.e. should not be visible to
# everyone through the CI logs.
#
# Usage: `setSecretVar <name> <value>`
function setSecretVar() {
# WARNING: Secrets (e.g. passwords, access tokens) should NOT be printed.
# (Keep original shell options to restore at the end.)
local -r originalShellOptions=$(set +o);
set +x -eu -o pipefail;
echo "export $1=\"${2:-}\";" >> $BASH_ENV;
# Restore original shell options.
eval "$originalShellOptions";
}

35
.circleci/env.sh Executable file
View File

@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Load helpers and make them available everywhere (through `$BASH_ENV`).
readonly envHelpersPath="`dirname $0`/env-helpers.inc.sh";
source $envHelpersPath;
echo "source $envHelpersPath;" >> $BASH_ENV;
####################################################################################################
# Define PUBLIC environment variables for CircleCI.
####################################################################################################
setPublicVar PROJECT_ROOT "$(pwd)";
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
# This is the branch being built; e.g. `pull/12345` for PR builds.
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
setPublicVar CI_COMMIT "$CIRCLE_SHA1";
# `CI_COMMIT_RANGE` will only be available when `CIRCLE_COMPARE_URL` is also available,
# i.e. on push builds (a.k.a. non-PR builds). That is fine, since we only need it in push builds.
setPublicVar CI_COMMIT_RANGE "$(sed -r 's|^.*/([0-9a-f]+\.\.\.[0-9a-f]+)$|\1|i' <<< ${CIRCLE_COMPARE_URL:-})";
setPublicVar CI_PULL_REQUEST "${CIRCLE_PR_NUMBER:-false}";
setPublicVar CI_REPO_NAME "$CIRCLE_PROJECT_REPONAME";
setPublicVar CI_REPO_OWNER "$CIRCLE_PROJECT_USERNAME";
####################################################################################################
# Define SECRET environment variables for CircleCI.
####################################################################################################
setSecretVar CI_SECRET_AIO_DEPLOY_FIREBASE_TOKEN "$AIO_DEPLOY_TOKEN";
setSecretVar CI_SECRET_PAYLOAD_FIREBASE_TOKEN "$ANGULAR_PAYLOAD_TOKEN";
# Defined in https://angular-team.slack.com/apps/A0F7VRE7N-circleci.
setSecretVar CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL "$SLACK_CARETAKER_WEBHOOK_URL";
# Source `$BASH_ENV` to make the variables available immediately.
source $BASH_ENV;

View File

@ -8,13 +8,6 @@ exports_files([
"protractor-perf.conf.js",
])
# Developers should always run `bazel run :install`
# This ensures that package.json in subdirectories get installed as well.
alias(
name = "install",
actual = "@nodejs//:yarn",
)
filegroup(
name = "web_test_bootstrap_scripts",
# do not sort

View File

@ -1,3 +1,15 @@
<a name="7.0.2"></a>
## [7.0.2](https://github.com/angular/angular/compare/7.0.1...7.0.2) (2018-10-31)
### Bug Fixes
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([c01f340](https://github.com/angular/angular/commit/c01f340))
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([#26879](https://github.com/angular/angular/issues/26879)) ([257ac83](https://github.com/angular/angular/commit/257ac83))
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([b3c6409](https://github.com/angular/angular/commit/b3c6409))
<a name="7.0.1"></a>
## [7.0.1](https://github.com/angular/angular/compare/7.0.0...7.0.1) (2018-10-24)
@ -79,7 +91,6 @@ To learn about the release highlights and our new CLI-powered update workflow fo
### Bug Fixes
* **platform-browser:** fix [#22155](https://github.com/angular/angular/issues/22155), destroy hammer manager when `HammerInstance.off()` is run ([#22156](https://github.com/angular/angular/issues/22156)) ([3b4d9dc](https://github.com/angular/angular/commit/3b4d9dc))
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([623adbb](https://github.com/angular/angular/commit/623adbb)), closes [#26208](https://github.com/angular/angular/issues/26208)

View File

@ -6,6 +6,16 @@ load(
"rules_angular_dev_dependencies",
)
# Uncomment for local bazel rules development
#local_repository(
# name = "build_bazel_rules_nodejs",
# path = "../rules_nodejs",
#)
#local_repository(
# name = "build_bazel_rules_typescript",
# path = "../rules_typescript",
#)
# Angular Bazel users will call this function
rules_angular_dependencies()
# These are the dependencies only for us

View File

@ -49,8 +49,6 @@ You can edit the generated files directly, or add to and modify them using CLI c
Use the [ng generate](cli/generate) command to add new files for additional components and services, and code for new pipes, directives, and so on.
Commands such as [add](cli/add) and [generate](cli/generate), which create or operate on apps and libraries, must be executed from within a workspace or project folder.
When you use the [ng serve](cli/serve) command to build an app and serve it locally, the server automatically rebuilds the app and reloads the page when you change any of the source files.
* See more about the [Workspace file structure](guide/file-structure).
When you use the [ng serve](cli/serve) command to build an app and serve it locally, the server automatically rebuilds the app and reloads the page when you change any of the source files.

View File

@ -13,6 +13,10 @@ describe('Elements', () => {
browser.wait(EC.elementToBeClickable(elem), 5000);
elem.click();
};
const waitForText = (elem: ElementFinder) => {
// Waiting for the element to have some text, makes the tests less flaky.
browser.wait(async () => /\S/.test(await elem.getText()), 5000);
}
beforeEach(() => browser.get(''));
@ -33,6 +37,8 @@ describe('Elements', () => {
messageInput.sendKeys('Angular rocks!');
click(popupComponentButton);
waitForText(popupComponent);
expect(popupComponent.getText()).toContain('Popup: Angular rocks!');
});
@ -62,6 +68,8 @@ describe('Elements', () => {
messageInput.sendKeys('Angular rocks!');
click(popupElementButton);
waitForText(popupElement);
expect(popupElement.getText()).toContain('Popup: Angular rocks!');
});

View File

@ -12,7 +12,7 @@ h2, h3 {
body {
margin: 2em;
}
body, input[text], button {
body, input[type="text"], button {
color: #888;
font-family: Cambria, Georgia;
}

View File

@ -40,7 +40,7 @@ export class HeroService {
// #enddocregion getHeroes-1
.pipe(
// #enddocregion getHeroes-2
tap(heroes => this.log('fetched heroes')),
tap(_ => this.log('fetched heroes')),
// #docregion getHeroes-2
catchError(this.handleError('getHeroes', []))
);

View File

@ -1,6 +1,6 @@
'use strict'; // necessary for es6 output in node
import { browser, element, by, ElementFinder } from 'protractor';
import { browser, element, by, ElementArrayFinder, ElementFinder } from 'protractor';
// Angular E2E Testing Guide:
// https://docs.angularjs.org/guide/e2e-testing
@ -20,6 +20,12 @@ describe('PhoneCat Application', function() {
describe('View: Phone list', function() {
// Helpers
const waitForCount = (elems: ElementArrayFinder, count: number) => {
// Wait for the list to stabilize, which may take a while (e.g. due to animations).
browser.wait(() => elems.count().then(c => c === count), 5000);
};
beforeEach(function() {
browser.get('index.html#!/phones');
});
@ -28,13 +34,16 @@ describe('PhoneCat Application', function() {
let phoneList = element.all(by.repeater('phone in $ctrl.phones'));
let query = element(by.model('$ctrl.query'));
waitForCount(phoneList, 20);
expect(phoneList.count()).toBe(20);
query.sendKeys('nexus');
waitForCount(phoneList, 1);
expect(phoneList.count()).toBe(1);
query.clear();
query.sendKeys('motorola');
waitForCount(phoneList, 8);
expect(phoneList.count()).toBe(8);
});
@ -51,6 +60,7 @@ describe('PhoneCat Application', function() {
}
queryField.sendKeys('tablet'); // Let's narrow the dataset to make the assertions shorter
waitForCount(phoneNameColumn, 2);
expect(getNames()).toEqual([
'Motorola XOOM\u2122 with Wi-Fi',
@ -66,10 +76,16 @@ describe('PhoneCat Application', function() {
});
it('should render phone specific links', function() {
let phoneList = element.all(by.repeater('phone in $ctrl.phones'));
let query = element(by.model('$ctrl.query'));
query.sendKeys('nexus');
element.all(by.css('.phones li a')).first().click();
query.sendKeys('nexus');
waitForCount(phoneList, 1);
let nexusPhone = phoneList.first();
let detailLink = nexusPhone.all(by.css('a')).first()
detailLink.click();
expect(browser.getLocationAbsUrl()).toBe('/phones/nexus-s');
});

View File

@ -1,19 +1,19 @@
# Deployment
When you are ready to deploy your Angular application to a remote server, you have various options for
deployment.
deployment.
{@a dev-deploy}
{@a copy-files}
## Simplest deployment possible
For the simplest deployment, build for development and copy the output directory to a web server.
For the simplest deployment, create a production build and copy the output directory to a web server.
1. Start with the development build:
1. Start with the production build:
<code-example language="none" class="code-shell">
ng build
ng build --prod
</code-example>
@ -22,8 +22,7 @@ For the simplest deployment, build for development and copy the output directory
3. Configure the server to redirect requests for missing files to `index.html`.
Learn more about server-side redirects [below](#fallback).
This is _not_ a production deployment. It's not optimized, and it won't be fast for users.
It might be good enough for sharing your progress and ideas internally with managers, teammates, and other stakeholders. For the next steps in deployment, see [Optimize for production](#optimize).
This is the simplest production-ready deployment of your application.
{@a deploy-to-github}
@ -31,7 +30,7 @@ It might be good enough for sharing your progress and ideas internally with mana
Another simple way to deploy your Angular app is to use [GitHub Pages](https://help.github.com/articles/what-is-github-pages/).
1. You need to [create a GitHub account](https://github.com/join) if you don't have one, and then [create a repository](https://help.github.com/articles/create-a-repo/) for your project.
1. You need to [create a GitHub account](https://github.com/join) if you don't have one, and then [create a repository](https://help.github.com/articles/create-a-repo/) for your project.
Make a note of the user name and project name in GitHub.
1. Build your project using Github project name, with the Angular CLI command [`ng build`](cli/build) and the options shown here:
@ -39,9 +38,9 @@ Make a note of the user name and project name in GitHub.
ng build --prod --output-path docs --base-href <project_name>
</code-example>
1. When the build is complete, make a copy of `docs/index.html` and name it `docs/404.html`.
1. When the build is complete, make a copy of `docs/index.html` and name it `docs/404.html`.
1. Commit your changes and push.
1. Commit your changes and push.
1. On the GitHub project page, configure it to [publish from the docs folder](https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/#publishing-your-github-pages-site-from-a-docs-folder-on-your-master-branch).
@ -97,51 +96,6 @@ There is no single configuration that works for every server.
The following sections describe configurations for some of the most popular servers.
The list is by no means exhaustive, but should provide you with a good starting point.
#### Development servers
During development, the [`ng serve`](cli/serve) CLI command lets you run your app in a local browser.
The CLI recompiles the application each time you save a file,
and reloads the browser with the newly compiled application.
The app is hosted in local memory and served on `http://localhost:4200/`, using [webpack-dev-server](https://webpack.js.org/guides/development/#webpack-dev-server).
{@a serve-from-disk}
Later in development, you might want a closer approximation of how your app will behave when deployed.
You can output your distribution folder (`dist`) to disk, but you need to install a different web server.
Try installing [lite-server](https://github.com/johnpapa/lite-server); like `webpack-dev-server`, it can automatically reload your browser when you write new files.
To get the live-reload experience, you will need to run two terminals.
The first runs the build in a watch mode and compiles the application to the `dist` folder.
The second runs the web server against the `dist` folder.
The combination of these two processes provides the same behavior as `ng serve`.
1. Start the build in terminal A:
<code-example language="none" class="code-shell">
ng build --watch
</code-example>
1. Start the web server in terminal B:
<code-example language="none" class="code-shell">
lite-server --baseDir="dist"
</code-example>
The default browser opens to the appropriate URL.
* [Lite-Server](https://github.com/johnpapa/lite-server): the default dev server installed with the
[Quickstart repo](https://github.com/angular/quickstart) is pre-configured to fallback to `index.html`.
* [Webpack-Dev-Server](https://github.com/webpack/webpack-dev-server): setup the
`historyApiFallback` entry in the dev server options as follows:
<code-example>
historyApiFallback: {
disableDotRule: true,
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml']
}
</code-example>
#### Production servers
* [Apache](https://httpd.apache.org/): add a
[rewrite rule](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) to the `.htaccess` file as shown
(https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/):
@ -230,19 +184,9 @@ Read about how to enable CORS for specific servers at
{@a optimize}
## Optimize for production
## Production optimizations
Although deploying directly from the development environment works,
you can generate an optimized build with additional CLI command line flags,
starting with `--prod`.
### Build with _--prod_
<code-example language="none" class="code-shell">
ng build --prod
</code-example>
The `--prod` _meta-flag_ engages the following optimization features.
The `--prod` _meta-flag_ engages the following build optimization features.
* [Ahead-of-Time (AOT) Compilation](guide/aot-compiler): pre-compiles Angular component templates.
* [Production mode](#enable-prod-mode): deploys the production environment which enables _production mode_.
@ -251,25 +195,22 @@ The `--prod` _meta-flag_ engages the following optimization features.
* Uglification: rewrites code to use short, cryptic variable and function names.
* Dead code elimination: removes unreferenced modules and much unused code.
The remaining [copy deployment steps](#copy-files) are the same as before.
See [`ng build`](cli/build) for more about CLI build options and what they do.
{@a enable-prod-mode}
### Enable production mode
### Enable runtime production mode
Angular apps run in development mode by default, as you can see by the following message on the browser
console:
In addition to build optimizations, Angular also has a runtime production mode. Angular apps run in development mode by default, as you can see by the following message on the browser console:
<code-example format="nocode">
Angular is running in the development mode. Call enableProdMode() to enable the production mode.
</code-example>
Switching to _production mode_ can make it run faster by disabling development specific checks such as the dual change detection cycles.
Switching to _production mode_ makes it run faster by disabling development specific checks such as the dual change detection cycles.
Building for production (or appending the `--environment=prod` flag) enables _production mode_
Look at the CLI-generated `main.ts` to see how this works.
When you enable production builds via `--prod` command line flag, the runtime production mode is enabled as well.
{@a lazy-loading}
@ -293,7 +234,7 @@ If you do that, the module will be loaded immediately.
The bundling configuration must take lazy loading into consideration.
Because lazy-loaded modules aren't imported in JavaScript, bundlers exclude them by default.
Bundlers don't know about the router configuration and can't create separate bundles for lazy-loaded modules.
Bundlers don't know about the router configuration and can't create separate bundles for lazy-loaded modules.
You would have to create these bundles manually.
The CLI runs the
@ -388,7 +329,7 @@ for the missing files. Look at where it _tried_ to find those files and adjust t
## Building and serving for deployment
When you are designing and developing applications, you typically use `ng serve` to build your app for fast, local, iterative development.
When you are designing and developing applications, you typically use `ng serve` to build your app for fast, local, iterative development.
When you are ready to deploy, however, you must use the `ng build` command to build the app and deploy the build artifacts elsewhere.
Both `ng build` and `ng serve` clear the output folder before they build the project, but only the `ng build` command writes the generated build artifacts to the output folder.
@ -401,12 +342,12 @@ To output to a different folder, change the `outputPath` in `angular.json`.
</div>
The `ng serve` command builds, watches, and serves the application from local memory, using a local development server.
When you have deployed your app to another server, however, you might still want to serve the app so that you can continue to see changes that you make in it.
When you have deployed your app to another server, however, you might still want to serve the app so that you can continue to see changes that you make in it.
You can do this by adding the `--watch` option to the `ng build` command.
```
ng build --watch
```
Like the `ng serve` command, this regenerates output files when source files change.
Like the `ng serve` command, this regenerates output files when source files change.
For complete details of the CLI commands, see the [CLI command reference](cli).

View File

@ -98,7 +98,7 @@ When the CLI generated the `CustomerDashboardComponent` for the feature module,
</code-example>
To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardModule`:
To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardComponent`:
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" header="src/app/customer-dashboard/customer-dashboard.module.ts" linenums="false">
</code-example>

View File

@ -672,7 +672,7 @@ format that Angular understands, such as `.xtb`.
How you provide this information depends upon whether you compile with
the JIT compiler or the AOT compiler.
* With [AOT](guide/i18n#merge-aot), you pass the information as a configuration
* With [AOT](guide/i18n#merge-aot), you pass the information as configuration settings.
* With [JIT](guide/i18n#merge-jit), you provide the information at bootstrap time.

View File

@ -1,6 +1,6 @@
# Workspace npm dependencies
The Angular Framework, Angular CLI, and components used by Angular applicatins are packaged as [npm packages](https://docs.npmjs.com/getting-started/what-is-npm "What is npm?") and distributed via the [npm registry](https://docs.npmjs.com/).
The Angular Framework, Angular CLI, and components used by Angular applications are packaged as [npm packages](https://docs.npmjs.com/getting-started/what-is-npm "What is npm?") and distributed via the [npm registry](https://docs.npmjs.com/).
You can download and install these npm packages by using the [npm CLI client](https://docs.npmjs.com/cli/install), which is installed with and runs as a [Node.js®](https://nodejs.org "Nodejs.org") application. By default, the Angular CLI uses the npm client.
@ -138,4 +138,4 @@ Package name | Description
For information about how the Angular CLI handles packages see the following guides:
* [Building and serving](guide/build) describes how packages come together to create a development build.
* [Deployment](guide/deployment) describes how packages come together to create a production build.
* [Deployment](guide/deployment) describes how packages come together to create a production build.

View File

@ -0,0 +1,135 @@
# Angular Workspace Configuration
A file named `angular.json` at the root level of an Angular [workspace](guide/glossary#workspace) provides workspace-wide and project-specific configuration defaults for build and development tools provided by the Angular CLI.
Path values given in the configuration are relative to the root workspace folder.
## Overall JSON structure
At the top level of `angular.json`, a few properties configure the workspace, and a `projects` section contains the remaining per-project configuration options.
* `version`: The configuration-file version.
* `newProjectRoot`: Path where new projects are created. Absolute or relative to the workspace folder.
* `defaultProject`: Default project name to use in commands, where not provided as an argument. When you use `ng new` to create a new app in a new workspace, that app is the default project for the workspace until you change it here.
* `projects` : Contains a subsection for each project (library, app, e2e test app) in the workspace, with the per-project configuration options.
The initial app that you create with `ng new app_name` is listed under "projects", along with its corresponding end-to-end test app:
<code-example format="." language="none" linenums="false">
projects
app_name
...
app_name-e2e
...
</code-example>
Each additional app that you create with `ng generate application` has a corresponding end-to-end test project, with its own configuration section.
When you create a library project with `ng generate library`, the library project is also added to the `projects` section.
<div class="alert is-helpful">
Note that the `projects` section of the configuration file does not correspond exactly to the workspace file structure.
* The initial app created by `ng new` is at the top level of the workspace file structure, along with its e2e app.
* Additional apps, e2e apps, and libraries go into a `projects` folder in the workspace.
For more information, see [Workspace and project file structure](guide/file-structure).
</div>
## Project configuration options
The following top-level configuration properties are available for each project, under `projects:<project_name>`.
<code-example format="." language="json" linenums="false">
"my-v7-app": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {}
}
</code-example>
| PROPERTY | DESCRIPTION |
| :-------------- | :---------------------------- |
| `root` | The root folder for this project's files, relative to the workspace folder. Empty for the initial app, which resides at the top level of the workspace. |
| `sourceRoot` | The root folder for this project's source files. |
| `projectType` | One of "application" or "library". An application can run independently in a browser, while a library cannot. Both an app and its e2e test app are of type "application".|
| `prefix` | A string that Angular prepends to generated selectors. Can be customized to identify an app or feature area. |
| `schematics` | An object containing schematics that customize CLI commands for this project. |
| `architect` | An object containing configuration defaults for Architect builder targets for this project. |
## Project tool configuration options
Architect is the tool that the CLI uses to perform complex tasks such as compilation and test running, according to provided configurations. The `architect` section contains a set of Architect *targets*. Many of the targets correspond to the CLI commands that run them. Some additional predefined targets can be run using the `ng run` command, and you can define your own targets.
Each target object specifies the `builder` for that target, which is the npm package for the tool that Architect runs. In addition, each target has an `options` section that configure default options for the target, and a `configurations` section that names and specifies alternative configurations for the target. See the example in [Build target](#build-target) below.
<code-example format="." language="json" linenums="false">
"architect": {
"build": { },
"serve": { },
"e2e" : { },
"test": { },
"lint": { },
"extract-i18n": { },
"server": { },
"app-shell": { }
}
</code-example>
* The `architect/build` section configures defaults for options of the `ng build` command. See [Build target]{#build-target} below for more information.
* The `architect/serve` section overrides build defaults and supplies additional serve defaults for the `ng serve` command. In addition to the options available for the `ng build` command, it adds options related to serving the app.
* The `architect/e2e` section overrides build-option defaults for building end-to-end testing apps using the `ng e2e` command.
* The `architect/test` section overrides build-option defaults for test builds and supplies additional test-running defaults for the `ng test` command.
* The `architect/lint` section configures defaults for options of the `ng lint` command, which performs code analysis on project source files. The default linting tool for Angular is [TSLint](https://palantir.github.io/tslint/).
* The `architect/extract-i18n` section configures defaults for options of the `ng-xi18n` tool used by the `ng xi18n` command, which extracts marked message strings from source code and outputs translation files.
* The `architect/server` section configures defaults for creating a Universal app with server-side rendering, using the `ng run <project>:server` command.
* The `architect/app-shell` section configures defaults for creating an app shell for a progressive web app (PWA), using the `ng run <project>:app-shell` command.
In general, the options for which you can configure defaults correspond to the command options listed in the [CLI reference page](cli) for each command.
Note that all options in the configuration file must use [camelCase](guide/glossary#case-conventions), rather than dash-case.
{@a build-target}
## Build target
The `architect/build` section configures defaults for options of the `ng build` command. It has the following top-level properties.
| PROPERTY | DESCRIPTION |
| :-------------- | :---------------------------- |
| `builder` | The npm package for the build tool used to create this target. The default is `@angular-devkit/build-angular:browser`, which uses the [webpack](https://webpack.js.org/) package bundler. |
| `options` | This section contains defaults for build options, used when no named alternative configuration is specified. See [Default build options](#build-props) below. |
| `configurations`| This section defines and names alternative configurations for different intended destinations. It contains a section for each named configuration, which sets the default options for that intended environment. See [Alternate build configurations](#build-configs) below. |
{@a build-configs}
### Alternate build configurations
By default, a `production` configuration is defined, and the `ng build` command has `--prod` option that builds using this configuration. The `production` configuration sets defaults that optimize the app in a number of ways, such bundling files, minimizing excess whitespace, removing comments and dead code, and rewriting code to use short, cryptic names ("minification").
You can define and name additional alternate configurations (such as `stage`, for instance) appropriate to your development process. Some examples of different build configurations are `stable`, `archive` and `next` used by AIO itself, and the individual locale-specific configurations required for building localized versions of an app. For details, see [Internationalization (i18n)](guide/i18n#merge-aot).
{@a build-props}
### Additional build and test options
The configurable options for a default or targeted build generally correspond to the options available for the [`ng build`](cli/build), [`ng serve`](cli/serve), and [`ng test`](cli/test) commands. For details of those options and their possible values, see the [CLI Reference](cli).
Some additional options (listed below) can only be set through the configuration file, either by direct editing or with the `ng config` command.
| OPTIONS PROPERTIES | DESCRIPTION |
| :------------------------- | :---------------------------- |
| `fileReplacements` | An object containing files and their compile-time replacements. |
| `stylePreprocessorOptions` | An object containing option-value pairs to pass to style preprocessors. |
| `assets` | An object containing paths to static assets to add to the global context of the project. The default paths point to the project's icon file and its `assets` folder. |
| `styles` | An object containing style files to add to the global context of the project. Angular CLI supports CSS imports and all major CSS preprocessors: [sass/scss](http://sass-lang.com/), [less](http://lesscss.org/), and [stylus](http://stylus-lang.com/). |
| `scripts` | An object containing JavaScript script files to add to the global context of the project. The scripts are loaded exactly as if you had added them in a `<script>` tag inside `index.html`. |
| `budgets` | Default size-budget type and threshholds for all or parts of your app. You can configure the builder to report a warning or an error when the output reaches or exceeds a threshold size. See [Configure size budgets](guide/build#configure-size-budgets). (Not available in `test` section.) |

File diff suppressed because it is too large Load Diff

View File

@ -211,7 +211,7 @@
"logo": "https://cloud.githubusercontent.com/assets/1016365/10639063/138338bc-7806-11e5-8057-d34c75f3cafc.png",
"rev": true,
"title": "Angular Universal",
"url": "https://github.com/angular/universal"
"url": "https://angular.io/guide/universal"
},
"c1": {
"desc": "Lightweight development only Node.js® server",
@ -273,6 +273,13 @@
"rev": true,
"title": "UI-jar - Test Driven Style Guide Development",
"url": "https://github.com/ui-jar/ui-jar"
},
"protactor": {
"desc": "The official end to end testing framework for Angular apps",
"logo": "",
"rev": true,
"title": "Protractor",
"url": "https://protractor.angular.io/"
}
}
},
@ -362,7 +369,7 @@
"logo": "",
"rev": true,
"title": "Angular Material",
"url": "https://github.com/angular/material2"
"url": "https://material.angular.io/"
},
"mcc": {
"desc": "Material components made by the community",
@ -377,6 +384,12 @@
"title": "Ant Design of Angular (ng-zorro-antd)",
"url": "https://ng.ant.design/docs/introduce/en"
},
"ngzorromobile": {
"desc": "A set of enterprise-class mobile UI components based on Ant Design Mobile and Angular",
"rev": true,
"title": "Ant Design Mobile of Angular (ng-zorro-antd-mobile)",
"url": "http://ng.mobile.ant.design/#/docs/introduce/en"
},
"aggrid": {
"desc": "A datagrid for Angular with enterprise style features such as sorting, filtering, custom rendering, editing, grouping, aggregation and pivoting.",
"rev": true,

View File

@ -513,8 +513,14 @@
{
"url": "guide/file-structure",
"title": "Project File Structure",
"tooltip": "How your Angular workspace looks in your filesystem."
"tooltip": "How your Angular workspace looks on your filesystem."
},
{
"url": "guide/workspace-config",
"title": "Workspace Configuration",
"tooltip": "The \"angular.json\" file contains workspace and project configuration defaults for Angular CLI commands."
},
{
"url": "guide/npm-packages",
"title": "npm Dependencies",

View File

@ -18,7 +18,7 @@
"build-for": "yarn ~~build --configuration",
"prebuild-local": "yarn setup-local",
"build-local": "yarn ~~build --configuration=stable",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js a2129510d7d57d1c02bec563872adf0204e11a2f",
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 4faa81e25",
"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",
@ -30,6 +30,8 @@
"setup-local": "yarn aio-use-local && yarn example-use-local",
"postsetup-local": "yarn postsetup",
"set-opensearch-url": "node --eval \"const sh = require('shelljs'); sh.set('-e'); sh.sed('-i', /PLACEHOLDER_URL/g, process.argv[1], 'dist/assets/opensearch.xml');\"",
"presmoke-tests": "yarn update-webdriver",
"smoke-tests": "protractor tests/deployment/e2e/protractor.conf.js --suite smoke --baseUrl",
"test-pwa-score": "node scripts/test-pwa-score",
"test-pwa-score-localhost": "run-p --race \"~~http-server dist -p 4200 --silent\" \"test-pwa-score http://localhost:4200 {1} {2}\" --",
"example-e2e": "yarn example-check-local && node ./tools/examples/run-example-e2e",
@ -109,11 +111,11 @@
"cross-spawn": "^5.1.0",
"css-selector-parser": "^1.3.0",
"dgeni": "^0.4.7",
"dgeni-packages": "^0.26.9",
"dgeni-packages": "^0.26.12",
"entities": "^1.1.1",
"eslint": "^3.19.0",
"eslint-plugin-jasmine": "^2.2.0",
"firebase-tools": "^3.2.1",
"firebase-tools": "^5.1.1",
"fs-extra": "^2.1.2",
"globby": "^6.1.0",
"hast-util-is-element": "^1.0.0",
@ -163,4 +165,4 @@
"xregexp": "^4.0.0",
"yargs": "^7.0.2"
}
}
}

View File

@ -13,7 +13,7 @@ readonly deployedUrl=https://pr${prNumber}-${prLastSha:0:7}.ngbuilds.io/
cd $PROJECT_ROOT/aio
# Build and store the app
yarn build
yarn build --progress=false
# Set deployedUrl as parameter in the opensearch description
# deployedUrl must end with /

View File

@ -93,7 +93,7 @@ fi
cd "`dirname $0`/.."
# Build the app
yarn build-for $deployEnv
yarn build-for $deployEnv --progress=false
# Include any mode-specific files
cp -rf src/extra-files/$deployEnv/. dist/
@ -106,8 +106,8 @@ fi
yarn payload-size
# Deploy to Firebase
firebase use "$projectId" --token "$firebaseToken"
firebase deploy --message "Commit: $CI_COMMIT" --non-interactive --token "$firebaseToken"
yarn firebase use "$projectId" --token "$firebaseToken"
yarn firebase deploy --message "Commit: $CI_COMMIT" --non-interactive --token "$firebaseToken"
# Run PWA-score tests
yarn test-pwa-score "$deployedUrl" "$CI_AIO_MIN_PWA_SCORE"

View File

@ -45,8 +45,9 @@ get(previewabilityCheckUrl).
const totalSecs = Math.round((previewCheckInterval * previewCheckAttempts) / 1000);
throw new Error(`Preview still not available after ${totalSecs}s.`);
}).
// The preview is now available. Run the PWA tests.
then(() => runPwaTests());
// The preview is now available. Run the tests.
then(() => yarnRun('smoke-tests', previewUrl)).
then(() => yarnRun('test-pwa-score', previewUrl, minPwaScore));
}).
catch(onError);
@ -93,15 +94,6 @@ function reportNoPreview(reason) {
console.log(`No (public) preview available. (Reason: ${reason})`);
}
function runPwaTests() {
return new Promise((resolve, reject) => {
const spawnOptions = {cwd: __dirname, stdio: 'inherit'};
spawn('yarn', ['test-pwa-score', previewUrl, minPwaScore], spawnOptions).
on('error', reject).
on('exit', code => (code === 0 ? resolve : reject)());
});
}
function validateArgs(args) {
if (args.length !== 3) {
const relativeScriptPath = relative('.', __filename.replace(/\.js$/, ''));
@ -119,3 +111,12 @@ function wait(delay) {
console.log(`Waiting ${delay}ms...`);
return new Promise(resolve => setTimeout(resolve, delay));
}
function yarnRun(script, ...args) {
return new Promise((resolve, reject) => {
const spawnOptions = {cwd: __dirname, stdio: 'inherit'};
spawn('yarn', [script, ...args], spawnOptions).
on('error', reject).
on('exit', code => (code === 0 ? resolve : reject)());
});
}

View File

@ -16,7 +16,7 @@ set +x -eu -o pipefail
# Install dependencies.
echo -e "\nInstalling dependencies in '$aioDir'...\n-----"
yarn install --frozen-lockfile
yarn install --frozen-lockfile --non-interactive
yarn update-webdriver
# Run checks for all URLs.

View File

@ -3,9 +3,11 @@
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./*.e2e-spec.ts'
],
suites: {
full: './*.e2e-spec.ts',
smoke: './smoke-tests.e2e-spec.ts',
},
suite: 'full',
capabilities: {
browserName: 'chrome',
// For Travis

View File

@ -59,7 +59,9 @@ describe(browser.baseUrl, () => {
it('should serve `index.html` for unknown pages', async () => {
const aioShell = element(by.css('aio-shell'));
const heading = aioShell.element(by.css('h1'));
await page.goTo(unknownPagePath);
await browser.wait(() => page.getDocViewerText(), 5000); // Wait for the document to be loaded.
expect(aioShell.isPresent()).toBe(true);
expect(heading.getText()).toMatch(/page not found/i);

View File

@ -29,6 +29,8 @@ describe(browser.baseUrl, () => {
Object.keys(textPerUrl).forEach(url => {
it(`should show the page at '${url}'`, () => {
page.goTo(url);
browser.wait(() => page.getDocViewerText(), 5000); // Wait for the document to be loaded.
expect(page.getDocViewerText()).toContain(textPerUrl[url]);
});
});
@ -39,7 +41,7 @@ describe(browser.baseUrl, () => {
api: 'api list',
'guide/architecture': 'architecture',
'guide/http': 'httpclient',
'guide/quickstart': 'quickstart',
'guide/quickstart': 'getting started',
'guide/security': 'security',
tutorial: 'tutorial',
};
@ -47,6 +49,8 @@ describe(browser.baseUrl, () => {
Object.keys(textPerUrl).forEach(url => {
it(`should show the page at '${url}'`, () => {
page.goTo(url);
browser.wait(() => page.getDocViewerText(), 5000); // Wait for the document to be loaded.
expect(page.getDocViewerText()).toContain(textPerUrl[url]);
});
});
@ -68,6 +72,8 @@ describe(browser.baseUrl, () => {
Object.keys(textPerUrl).forEach(url => {
it(`should show the page at '${url}'`, () => {
page.goTo(url);
browser.wait(() => page.getDocViewerText(), 5000); // Wait for the document to be loaded.
expect(page.getDocViewerText()).toContain(textPerUrl[url]);
});
});

View File

@ -12,15 +12,15 @@
},
"private": true,
"dependencies": {
"@angular/animations": "~7.0.0-rc.0",
"@angular/common": "~7.0.0-rc.0",
"@angular/compiler": "~7.0.0-rc.0",
"@angular/core": "~7.0.0-rc.0",
"@angular/forms": "~7.0.0-rc.0",
"@angular/http": "~7.0.0-rc.0",
"@angular/platform-browser": "~7.0.0-rc.0",
"@angular/platform-browser-dynamic": "~7.0.0-rc.0",
"@angular/router": "~7.0.0-rc.0",
"@angular/animations": "^7.0.0",
"@angular/common": "^7.0.0",
"@angular/compiler": "^7.0.0",
"@angular/core": "^7.0.0",
"@angular/forms": "^7.0.0",
"@angular/http": "^7.0.0",
"@angular/platform-browser": "^7.0.0",
"@angular/platform-browser-dynamic": "^7.0.0",
"@angular/router": "^7.0.0",
"angular-in-memory-web-api": "^0.6.0",
"core-js": "^2.5.4",
"rxjs": "^6.3.0",
@ -28,10 +28,10 @@
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.9.0-rc.2",
"@angular/cli": "~7.0.0-rc.2",
"@angular/compiler-cli": "~7.0.0-rc.0",
"@angular/language-service": "~7.0.0-rc.0",
"@angular-devkit/build-angular": "^0.10.0",
"@angular/cli": "^7.0.0",
"@angular/compiler-cli": "^7.0.0",
"@angular/language-service": "^7.0.0",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",

View File

@ -15,15 +15,15 @@
},
"private": true,
"dependencies": {
"@angular/animations": "~7.0.0-rc.0",
"@angular/common": "~7.0.0-rc.0",
"@angular/compiler": "~7.0.0-rc.0",
"@angular/core": "~7.0.0-rc.0",
"@angular/forms": "~7.0.0-rc.0",
"@angular/http": "~7.0.0-rc.0",
"@angular/platform-browser": "~7.0.0-rc.0",
"@angular/platform-browser-dynamic": "~7.0.0-rc.0",
"@angular/router": "~7.0.0-rc.0",
"@angular/animations": "^7.0.0",
"@angular/common": "^7.0.0",
"@angular/compiler": "^7.0.0",
"@angular/core": "^7.0.0",
"@angular/forms": "^7.0.0",
"@angular/http": "^7.0.0",
"@angular/platform-browser": "^7.0.0",
"@angular/platform-browser-dynamic": "^7.0.0",
"@angular/router": "^7.0.0",
"angular-in-memory-web-api": "^0.6.0",
"core-js": "^2.5.4",
"rxjs": "^6.3.0",
@ -31,10 +31,10 @@
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.9.0-rc.2",
"@angular/cli": "~7.0.0-rc.2",
"@angular/compiler-cli": "~7.0.0-rc.0",
"@angular/language-service": "~7.0.0-rc.0",
"@angular-devkit/build-angular": "^0.10.0",
"@angular/cli": "^7.0.0",
"@angular/compiler-cli": "^7.0.0",
"@angular/language-service": "^7.0.0",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",

View File

@ -16,18 +16,18 @@
},
"private": true,
"dependencies": {
"@angular/animations": "~7.0.0-rc.0",
"@angular/common": "~7.0.0-rc.0",
"@angular/compiler": "~7.0.0-rc.0",
"@angular/core": "~7.0.0-rc.0",
"@angular/forms": "~7.0.0-rc.0",
"@angular/http": "~7.0.0-rc.0",
"@angular/platform-browser": "~7.0.0-rc.0",
"@angular/platform-browser-dynamic": "~7.0.0-rc.0",
"@angular/router": "~7.0.0-rc.0",
"@nguniversal/common": "^6.1.0",
"@nguniversal/express-engine": "^6.1.0",
"@nguniversal/module-map-ngfactory-loader": "^6.1.0",
"@angular/animations": "^7.0.0",
"@angular/common": "^7.0.0",
"@angular/compiler": "^7.0.0",
"@angular/core": "^7.0.0",
"@angular/forms": "^7.0.0",
"@angular/http": "^7.0.0",
"@angular/platform-browser": "^7.0.0",
"@angular/platform-browser-dynamic": "^7.0.0",
"@angular/router": "^7.0.0",
"@nguniversal/common": "^7.0.0",
"@nguniversal/express-engine": "^7.0.0",
"@nguniversal/module-map-ngfactory-loader": "^7.0.0",
"angular-in-memory-web-api": "^0.6.0",
"core-js": "^2.5.4",
"rxjs": "^6.3.0",
@ -35,11 +35,11 @@
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.9.0-rc.2",
"@angular/cli": "~7.0.0-rc.2",
"@angular/compiler-cli": "~7.0.0-rc.0",
"@angular/language-service": "~7.0.0-rc.0",
"@angular/platform-server": "~7.0.0-rc.0",
"@angular-devkit/build-angular": "^0.10.0",
"@angular/cli": "^7.0.0",
"@angular/compiler-cli": "^7.0.0",
"@angular/language-service": "^7.0.0",
"@angular/platform-server": "^7.0.0",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",

View File

@ -18,21 +18,21 @@
"author": "",
"license": "MIT",
"dependencies": {
"@angular/animations": "~7.0.0-rc.0",
"@angular/common": "~7.0.0-rc.0",
"@angular/compiler": "~7.0.0-rc.0",
"@angular/core": "~7.0.0-rc.0",
"@angular/elements": "~7.0.0-rc.0",
"@angular/forms": "~7.0.0-rc.0",
"@angular/http": "~7.0.0-rc.0",
"@angular/platform-browser": "~7.0.0-rc.0",
"@angular/platform-browser-dynamic": "~7.0.0-rc.0",
"@angular/router": "~7.0.0-rc.0",
"@angular/service-worker": "~7.0.0-rc.0",
"@angular/upgrade": "~7.0.0-rc.0",
"@nguniversal/common": "^6.1.0",
"@nguniversal/express-engine": "^6.1.0",
"@nguniversal/module-map-ngfactory-loader": "^6.1.0",
"@angular/animations": "^7.0.0",
"@angular/common": "^7.0.0",
"@angular/compiler": "^7.0.0",
"@angular/core": "^7.0.0",
"@angular/elements": "^7.0.0",
"@angular/forms": "^7.0.0",
"@angular/http": "^7.0.0",
"@angular/platform-browser": "^7.0.0",
"@angular/platform-browser-dynamic": "^7.0.0",
"@angular/router": "^7.0.0",
"@angular/service-worker": "^7.0.0",
"@angular/upgrade": "^7.0.0",
"@nguniversal/common": "^7.0.0",
"@nguniversal/express-engine": "^7.0.0",
"@nguniversal/module-map-ngfactory-loader": "^7.0.0",
"angular-in-memory-web-api": "^0.6.0",
"core-js": "^2.5.4",
"express": "^4.14.1",
@ -42,11 +42,11 @@
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.9.0-rc.2",
"@angular/cli": "^7.0.0-rc.2",
"@angular/compiler-cli": "~7.0.0-rc.0",
"@angular/language-service": "~7.0.0-rc.0",
"@angular/platform-server": "~7.0.0-rc.0",
"@angular-devkit/build-angular": "^0.10.0",
"@angular/cli": "^7.0.0",
"@angular/compiler-cli": "^7.0.0",
"@angular/language-service": "^7.0.0",
"@angular/platform-server": "^7.0.0",
"@types/angular": "^1.6.47",
"@types/angular-animate": "^1.5.10",
"@types/angular-mocks": "^1.6.0",

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,9 @@ module.exports = function autoLinkCode(getDocFromAlias) {
return (ast) => {
visit(ast, 'element', (node, ancestors) => {
// Only interested in code elements that are not inside links
if (autoLinkCodeImpl.codeElements.some(elementType => is(node, elementType)) &&
if (autoLinkCodeImpl.codeElements.some(elementType =>
is(node, elementType)) &&
(!node.properties.className || node.properties.className.indexOf('no-auto-link') === -1) &&
ancestors.every(ancestor => !is(ancestor, 'a'))) {
visit(node, 'text', (node, ancestors) => {
// Only interested in text nodes that are not inside links

View File

@ -109,4 +109,11 @@ describe('autoLinkCode post-processor', () => {
processor.$process([doc]);
expect(doc.renderedContent).toEqual('<code-example><a href="a/b/myclass" class="code-anchor">MyClass</a></code-example>');
});
it('should ignore code blocks that are marked with a `no-auto-link` class', () => {
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
const doc = { docType: 'test-doc', renderedContent: '<code class="no-auto-link">MyClass</code>' };
processor.$process([doc]);
expect(doc.renderedContent).toEqual('<code class="no-auto-link">MyClass</code>');
});
});

View File

@ -47,40 +47,6 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
var ignoreWordsMap = convertToMap(wordsToIgnore);
// If the heading contains a name starting with ng, e.g. "ngController", then add the
// name without the ng to the text, e.g. "controller".
function tokenize(text) {
const rawTokens = text.split(/[\s\/]+/mg);
const tokens = [];
rawTokens.forEach(token => {
// Strip off unwanted trivial characters
token = token
.trim()
.replace(/^[_\-"'`({[<$*)}\]>.]+/, '')
.replace(/[_\-"'`({[<$*)}\]>.]+$/, '');
// Ignore tokens that contain weird characters
if (/^[\w.\-]+$/.test(token)) {
tokens.push(token.toLowerCase());
const ngTokenMatch = /^[nN]g([A-Z]\w*)/.exec(token);
if (ngTokenMatch) {
tokens.push(ngTokenMatch[1].toLowerCase());
}
}
});
return tokens;
}
function extractWords(text, words, keywordMap) {
var tokens = tokenize(text);
tokens.forEach(function(token) {
if (!keywordMap[token]) {
words.push(token);
keywordMap[token] = true;
}
});
}
const filteredDocs = docs
// We are not interested in some docTypes
.filter(function(doc) { return !docTypesToIgnore[doc.docType]; })
@ -104,14 +70,10 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
if (isString(value) && !propertiesToIgnore[key]) {
extractWords(value, words, keywordMap);
}
// Special case properties that contain content relating to "members"
// of a doc that represents, say, a class or interface
if (key === 'members' || key === 'statics') {
value.forEach(function(member) { extractWords(member.name, members, membersMap); });
}
});
extractMemberWords(doc, members, membersMap);
// Extract all the keywords from the headings
if (doc.vFile && doc.vFile.headings) {
Object.keys(doc.vFile.headings).forEach(function(headingTag) {
@ -166,4 +128,54 @@ function convertToMap(collection) {
const obj = {};
collection.forEach(key => { obj[key] = true; });
return obj;
}
// If the heading contains a name starting with ng, e.g. "ngController", then add the
// name without the ng to the text, e.g. "controller".
function tokenize(text) {
const rawTokens = text.split(/[\s\/]+/mg);
const tokens = [];
rawTokens.forEach(token => {
// Strip off unwanted trivial characters
token = token
.trim()
.replace(/^[_\-"'`({[<$*)}\]>.]+/, '')
.replace(/[_\-"'`({[<$*)}\]>.]+$/, '');
// Ignore tokens that contain weird characters
if (/^[\w.\-]+$/.test(token)) {
tokens.push(token.toLowerCase());
const ngTokenMatch = /^[nN]g([A-Z]\w*)/.exec(token);
if (ngTokenMatch) {
tokens.push(ngTokenMatch[1].toLowerCase());
}
}
});
return tokens;
}
function extractWords(text, words, keywordMap) {
var tokens = tokenize(text);
tokens.forEach(function(token) {
if (!keywordMap[token]) {
words.push(token);
keywordMap[token] = true;
}
});
}
function extractMemberWords(doc, members, membersMap) {
if (!doc) return;
if (doc.members) {
doc.members.forEach(member => extractWords(member.name, members, membersMap));
}
if (doc.statics) {
doc.statics.forEach(member => extractWords(member.name, members, membersMap));
}
if (doc.extendsClauses) {
doc.extendsClauses.forEach(clause => extractMemberWords(clause.doc, members, membersMap));
}
if (doc.implementsClauses) {
doc.implementsClauses.forEach(clause => extractMemberWords(clause.doc, members, membersMap));
}
}

View File

@ -128,6 +128,46 @@ describe('generateKeywords processor', () => {
);
});
it('should add inherited member doc properties to the search terms', () => {
const processor = processorFactory(mockLogger, mockReadFilesProcessor);
const parentClass = {
docType: 'class',
name: 'ParentClass',
members: [
{ name: 'parentMember1' },
],
statics: [
{ name: 'parentMember2' },
],
};
const parentInterface = {
docType: 'interface',
name: 'ParentInterface',
members: [
{ name: 'parentMember3' },
]
};
const childClass = {
docType: 'class',
name: 'Child',
members: [
{ name: 'childMember1' }
],
statics: [
{ name: 'childMember2' }
],
extendsClauses: [{ doc: parentClass }],
implementsClauses: [{ doc: parentInterface }]
};
const docs = [childClass, parentClass, parentInterface];
processor.$process(docs);
const keywordsDoc = docs[docs.length - 1];
expect(keywordsDoc.data[0].members.split(' ').sort().join(' ')).toEqual(
'childmember1 childmember2 parentmember1 parentmember2 parentmember3'
);
});
it('should process terms prefixed with "ng" to include the term stripped of "ng"', () => {
const processor = processorFactory(mockLogger, mockReadFilesProcessor);
const docs = [

View File

@ -12,9 +12,14 @@
{$ doc.shortDescription | marked $}
{$ doc.description | marked $}
{$ cli.renderSyntax(doc) $}
{% if doc.longDescription.length %}
<h2 class="no-anchor">Description</h2>
{$ doc.longDescription | marked $}
{% endif%}
{$ cli.renderArguments(doc.positionalOptions, 2) $}
{$ cli.renderNamedOptions(doc.namedOptions, 2) $}
{$ cli.renderSubcommands(doc) $}
{$ doc.longDescription | marked $}
</div>
</article>

View File

@ -17,8 +17,8 @@
<tbody>
{% for command in doc.commands %}
<tr>
<td><a class="code-anchor" href="{$ command.path $}"><code>{$ command.name $}</code></a></td>
<td>{% for alias in command.commandAliases %}<code>{$ alias $} </code>{% endfor %}</td>
<td><a class="code-anchor" href="{$ command.path $}"><code class="no-auto-link">{$ command.name $}</code></a></td>
<td>{% for alias in command.commandAliases %}<code class="no-auto-link">{$ alias $} </code>{% endfor %}</td>
<td>{$ command.description | marked $}</td>
</tr>
{% endfor %}

View File

@ -1,6 +1,6 @@
{% macro renderSyntax(container, prefix) -%}
{% for name in container.names %}
<code-example hideCopy="true" class="no-box api-heading">ng {%if prefix %}{$ prefix $} {% endif %}<span class="cli-name">{$ name $}</span>
<code-example hideCopy="true" class="no-box api-heading no-auto-link">ng {%if prefix %}{$ prefix $} {% endif %}<span class="cli-name">{$ name $}</span>
{%- for arg in container.positionalOptions %} &lt;<var>{$ arg.name $}</var>&gt;{% endfor %}
{%- if container.namedOptions.length %} [<var>options</var>]{% endif -%}
</code-example>
@ -20,14 +20,14 @@
<tbody>
{% for option in arguments %}
<tr class="cli-option">
<td><code>&lt;<var>{$ option.name $}</var>&gt;</code></td>
<td><code class="no-auto-link">&lt;<var>{$ option.name $}</var>&gt;</code></td>
<td>
{$ option.description | marked $}
{% if option.subcommands.length -%}
<p>This option can take one of the following <a href="#{$ option.name $}-commands">sub-commands</a>:<p>
<ul>
{% for subcommand in option.subcommands %}
<li><code><a class="code-anchor" href="#{$ subcommand.name $}-command">{$ subcommand.name $}</a></code></li>
<li><code class="no-auto-link"><a class="code-anchor" href="#{$ subcommand.name $}-command">{$ subcommand.name $}</a></code></li>
{% endfor %}
</ul>
{%- endif %}
@ -53,11 +53,11 @@
{% for option in options %}
<tr class="cli-option">
<td>
<code class="cli-option-syntax">{$ renderOption(option.name, option.type, option.default, option.enum) $}</code>
<code class="cli-option-syntax no-auto-link">{$ renderOption(option.name, option.type, option.default, option.enum) $}</code>
</td>
<td>
{$ option.description | marked $}
{% if option.default !== undefined %}<p><span class="cli-default">Default:</span> <code>{$ option.default $}</code></p>{% endif %}
{% if option.default !== undefined %}<p><span class="cli-default">Default:</span> <code class="no-auto-link">{$ option.default $}</code></p>{% endif %}
{% if option.aliases.length %}<p><span class="cli-aliases">Aliases:</span> {% for alias in option.aliases %}{$ renderOptionName(alias) $}{% if not loop.last %}, {% endif %}{% endfor %}</p>{% endif %}
</td>
</tr>
@ -92,7 +92,7 @@
{% for command in container.positionalOptions %}{% if command.subcommands.length %}
<h2><a id="{$ command.name $}-commands"></a>{$ command.name | title $} commands</h2>
{% for subcommand in command.subcommands %}
<h3><code><a id="{$ subcommand.name $}-command"></a>{$ subcommand.name $}</code></h3>
<h3><code class="no-auto-link"><a id="{$ subcommand.name $}-command"></a>{$ subcommand.name $}</code></h3>
{% for name in container.names %}
{$ renderSyntax(subcommand, name) $}
{% endfor %}

File diff suppressed because it is too large Load Diff

View File

@ -9,21 +9,14 @@ Bazel.
## Installation
Install Bazel from the distribution, see [install] instructions.
On Mac, just `brew install bazel`.
In order to ensure that everyone builds Angular in a _consistent_ way, Bazel
will be installed through NPM and therefore it's not necessary to install Bazel
manually.
Bazel will install a hermetic version of Node, npm, and Yarn when
you run the first build.
The binaries for Bazel will be provided by the [`@bazel/bazel`](https://github.com/bazelbuild/rules_nodejs/tree/master/packages)
NPM package and its platform-specific dependencies.
[install]: https://bazel.build/versions/master/docs/install.html
### Installation of ibazel
Install interactive bazel runner / fs watcher via:
```
yarn global add @bazel/ibazel
```
You can access Bazel with the `yarn bazel` command
## Configuration
@ -33,12 +26,6 @@ use to execute build steps, from `build_bazel_rules_typescript`.
The sources on [GitHub] are published from Google's internal
repository (google3).
That repository defines dependencies on specific versions of
all the tools. You can run the tools Bazel installed, for
example rather than `yarn install` (which depends on whatever
version you have installed on your machine), you can
`bazel run @nodejs//:yarn`.
Bazel accepts a lot of options. We check in some options in the
`.bazelrc` file. See the [bazelrc doc]. For example, if you don't
want Bazel to create several symlinks in your project directory
@ -50,8 +37,8 @@ want Bazel to create several symlinks in your project directory
## Building Angular
- Build a package: `bazel build packages/core`
- Build all packages: `bazel build packages/...`
- Build a package: `yarn bazel build packages/core`
- Build all packages: `yarn bazel build packages/...`
You can use [ibazel] to get a "watch mode" that continuously
keeps the outputs up-to-date as you save sources. Note this is
@ -61,9 +48,9 @@ new as of May 2017 and not very stable yet.
## Testing Angular
- Test package in node: `bazel test packages/core/test:test`
- Test package in karma: `bazel test packages/core/test:test_web`
- Test all packages: `bazel test packages/...`
- Test package in node: `yarn bazel test packages/core/test:test`
- Test package in karma: `yarn bazel test packages/core/test:test_web`
- Test all packages: `yarn bazel test packages/...`
You can use [ibazel] to get a "watch mode" that continuously
keeps the outputs up-to-date as you save sources.
@ -72,19 +59,20 @@ keeps the outputs up-to-date as you save sources.
If you're experiencing problems with seemingly unrelated tests failing, it may be because you're not using the proper flags with your Bazel test runs in Angular.
See also: [`//.bazelrc`](https://github.com/angular/angular/blob/master/.bazelrc) where `--define=ivy=false` is defined as default.
See also: [`//.bazelrc`](https://github.com/angular/angular/blob/master/.bazelrc) where `--define=compile=legacy` is defined as default.
- `--config=debug`: build and launch in debug mode (see [debugging](#debugging) instructions below)
- `--test_arg=--node_options=--inspect=9228`: change the inspector port.
- `--define=compile=<option>` Controls if ivy or legacy mode is enabled. This is done by generating the [`src/ivy_switch.ts`](https://github.com/angular/angular/blob/master/packages/core/src/ivy_switch.ts) file from [`ivy_switch_legacy.ts`](https://github.com/angular/angular/blob/master/packages/core/src/ivy_switch_legacy.ts) (default), [`ivy_switch_jit.ts`](https://github.com/angular/angular/blob/master/packages/core/src/ivy_switch_jit.ts), or [`ivy_switch_local.ts`](https://github.com/angular/angular/blob/master/packages/core/src/ivy_switch_local.ts).
- `legacy`: (default behavior) compile against View Engine, e.g. `--define=compile=legacy`
- `jit`: Compile in ivy JIT mode, e.g. `--define=compile=jit`
- `local`: Compile in ivy AOT move, e.g. `--define=compile=local`
- `--test_tag_filters=<tag>`: filter tests down to tags defined in the `tag` config
of your rules in any given `BUILD.bazel`.
- `ivy-jit`: This flag should be set for tests that should be excuted with ivy JIT, e.g. `--test_tag_filters=ivy-jit`. For this, you may have to include `--define=compile=jit`.
- `ivy-local`: Only run tests that have to do with ivy AOT. For this, you may have to include `--define=compile=local`, e.g. `--test_tag_filters=ivy-local`..
- `ivy-only`: Only run ivy related tests, e.g. `--test_tag_filters=ivy-only`.
- `aot`: Compile in ivy AOT move, e.g. `--define=compile=aot`
- `--test_tag_filters=<tag>`: filter tests down to tags defined in the `tag` config of your rules in any given `BUILD.bazel`.
- `no-ivy-aot`: Useful for excluding build and test targets that are not meant to be executed in Ivy AOT mode (`--define=compile=aot`).
- `no-ivy-jit`: Useful for excluding build and test targets that are not meant to be executed in Ivy JIT mode (`--define=compile=jit`).
- `ivy-only`: Useful for excluding all Ivy build and tests targets with `--define=compile=legacy`.
- `fixme-ivy-aot`: Useful for including/excluding build and test targets that are currently broken in Ivy AOT mode (`--define=compile=aot`).
- `fixme-ivy-jit`: Useful for including/excluding build and test targets that are currently broken in Ivy JIT mode (`--define=compile=jit`).
### Debugging a Node Test
@ -92,7 +80,7 @@ of your rules in any given `BUILD.bazel`.
- Open chrome at: [chrome://inspect](chrome://inspect)
- Click on `Open dedicated DevTools for Node` to launch a debugger.
- Run test: `bazel test packages/core/test:test --config=debug`
- Run test: `yarn bazel test packages/core/test:test --config=debug`
The process should automatically connect to the debugger. For additional info and testing options, see the [nodejs_test documentation](https://bazelbuild.github.io/rules_nodejs/node/node.html#nodejs_test).
@ -129,7 +117,7 @@ First time setup:
**Setting breakpoints directly in your code files may not work in VSCode**. This is because the files you're actually debugging are built files that exist in a `./private/...` folder.
The easiest way to debug a test for now is to add a `debugger` statement in the code
and launch the bazel corresponding test (`bazel test <target> --config=debug`).
and launch the bazel corresponding test (`yarn bazel test <target> --config=debug`).
Bazel will wait on a connection. Go to the debug view (by clicking on the sidebar or
Apple+Shift+D on Mac) and click on the green play icon next to the configuration name
@ -137,7 +125,7 @@ Apple+Shift+D on Mac) and click on the green play icon next to the configuration
### Debugging a Karma Test
- Run test: `bazel run packages/core/test:test_web`
- Run test: `yarn bazel run packages/core/test:test_web`
- Open chrome at: [http://localhost:9876/debug.html](http://localhost:9876/debug.html)
- Open chrome inspector
@ -150,7 +138,7 @@ open $(bazel info output_base)/external
See subcommands that bazel executes (helpful for debugging):
```sh
bazel build //packages/core:package -s
yarn bazel build //packages/core:package -s
```
To debug nodejs_binary executable paths uncomment `find . -name rollup 1>&2` (~ line 96) in
@ -167,7 +155,7 @@ In our repo, here is how it's configured:
1) In `tools/bazel_stamp_vars.sh` we run the `git` commands to generate our versioning info.
1) In `.bazelrc` we register this script as the value for the `workspace_status_command` flag. Bazel will run the script when it needs to stamp a binary.
Note that Bazel has a `--stamp` argument to `bazel build`, but this has no effect since our stamping takes place in Skylark rules. See https://github.com/bazelbuild/bazel/issues/1054
Note that Bazel has a `--stamp` argument to `yarn bazel build`, but this has no effect since our stamping takes place in Skylark rules. See https://github.com/bazelbuild/bazel/issues/1054
## Remote cache
@ -205,7 +193,7 @@ See [bazelbuild/intellij#246](https://github.com/bazelbuild/intellij/issues/246)
If you see the following error:
```
$ bazel build packages/...
$ yarn bazel build packages/...
ERROR: /private/var/tmp/[...]/external/local_config_cc/BUILD:50:5: in apple_cc_toolchain rule @local_config_cc//:cc-compiler-darwin_x86_64: Xcode version must be specified to use an Apple CROSSTOOL
ERROR: Analysis of target '//packages/core/test/render3:render3' failed; build aborted: Analysis of target '@local_config_cc//:cc-compiler-darwin_x86_64' failed; build aborted
```
@ -227,7 +215,7 @@ If VSCode is not the root cause, you might try:
bazel clean --expunge
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license
bazel build //packages/core # Run a build outside VSCode to pre-build the xcode; then safe to run VSCode
yarn bazel build //packages/core # Run a build outside VSCode to pre-build the xcode; then safe to run VSCode
```
Source: https://stackoverflow.com/questions/45276830/xcode-version-must-be-specified-to-use-an-apple-crosstool

View File

@ -5,6 +5,9 @@
"license": "MIT",
"dependencies": {
},
"devDependencies": {
"@bazel/bazel": "file:../../node_modules/@bazel/bazel"
},
"scripts": {
"//": "deps are listed in src/package.json which is used by yarn_install",
"//": "this package.json file is only here so that `yarn test` can be called by /integration/run_tests.sh",

View File

@ -2,3 +2,24 @@
# yarn lockfile v1
"@bazel/bazel-darwin_x64@0.18.0":
version "0.18.0"
resolved "https://registry.yarnpkg.com/@bazel/bazel-darwin_x64/-/bazel-darwin_x64-0.18.0.tgz#bab437605a702279d42f59caa4741bb327eb7dbc"
integrity sha512-um2OzgLL2Gd/W6joOpvrSTcqpnupliPNpwe/uE7sB0huBSJ/4Im0w2IlCTI6C7OfgMcbpUj4YxgUa9T6u6WY6w==
"@bazel/bazel-linux_x64@0.18.0":
version "0.18.0"
resolved "https://registry.yarnpkg.com/@bazel/bazel-linux_x64/-/bazel-linux_x64-0.18.0.tgz#0c02b2404ec95c180e17615cc7079ee07df48a69"
integrity sha512-Rq8X8bL6SgQvbOHnfPhSgF6hp+f6Fbt2w6pRmBlFvV1J+CeUyrSrrRXfnnO1bjIuq05Ur3mV8ULA0qK6rtA5lQ==
"@bazel/bazel-win32_x64@0.18.0":
version "0.18.0"
resolved "https://registry.yarnpkg.com/@bazel/bazel-win32_x64/-/bazel-win32_x64-0.18.0.tgz#aa4575fb00066dcf59a6d464971774dea6a0bafd"
integrity sha512-U2TbfK8B7dc3JqXSFwj2oXCQrxEaSzCCUkAHjAOIGOKzx/HLKIKs+NJj9IQkLLr7BsMU+Qqzo8aqo11E+Vs+aA==
"@bazel/bazel@file:../../node_modules/@bazel/bazel":
version "0.18.0"
optionalDependencies:
"@bazel/bazel-darwin_x64" "0.18.0"
"@bazel/bazel-linux_x64" "0.18.0"
"@bazel/bazel-win32_x64" "0.18.0"

View File

@ -17,7 +17,7 @@ ts_library(
"//modules/benchmarks/src/largetable:util_lib",
"//packages:types",
"//packages/core",
"@rxjs",
"@ngdeps//reflect-metadata",
],
)
@ -59,7 +59,11 @@ protractor_web_test(
],
on_prepare = ":protractor.on-prepare.js",
server = ":devserver",
tags = ["manual"],
tags = [
"fixme-ivy-aot",
"fixme-ivy-jit",
"ivy-only",
],
deps = [
"//modules/benchmarks/src/largetable:perf_lib",
],

View File

@ -1,6 +1,8 @@
package(default_visibility = ["//visibility:public"])
load("//tools:defaults.bzl", "ng_module")
load("//tools:defaults.bzl", "ng_module", "ng_rollup_bundle")
load("//packages/bazel:index.bzl", "protractor_web_test")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
ng_module(
name = "render3_lib",
@ -13,6 +15,54 @@ ng_module(
"//modules/benchmarks/src/tree:util_lib",
"//packages:types",
"//packages/core",
"@rxjs",
"@ngdeps//reflect-metadata",
],
)
ng_rollup_bundle(
name = "bundle",
entry_point = "modules/benchmarks/src/tree/render3/index.js",
tags = ["ivy-only"],
deps = [
":tree_lib",
],
)
genrule(
name = "favicon",
srcs = ["//modules/benchmarks:favicon"],
outs = ["favicon.ico"],
cmd = "cp $< $@",
)
ts_devserver(
name = "devserver",
static_files = [
":bundle.min_debug.js",
":bundle.min.js",
"index.html",
":favicon",
],
tags = ["ivy-only"],
)
protractor_web_test(
name = "perf",
configuration = "//:protractor-perf.conf.js",
data = [
"//packages/bazel/src/protractor/utils",
"//packages/benchpress",
],
on_prepare = ":protractor.on_prepare.js",
server = ":devserver",
tags = [
"fixme-ivy-aot",
"fixme-ivy-jit",
"ivy-only",
],
deps = [
"@ngdeps//node-uuid",
"@ngdeps//protractor",
"@ngdeps//yargs",
],
)

View File

@ -1,6 +1,6 @@
{
"name": "angular-srcs",
"version": "7.0.1",
"version": "7.0.2",
"private": true,
"branchPattern": "2.0.*",
"description": "Angular - a web framework for modern web apps",
@ -26,43 +26,28 @@
"update-webdriver": "webdriver-manager update --gecko false $CHROMEDRIVER_VERSION_ARG",
"check-env": "gulp check-env",
"commitmsg": "node ./scripts/git/commit-msg.js",
"test-ivy-jit": "bazel test --define=compile=jit --build_tag_filters=ivy-jit --test_tag_filters=ivy-jit",
"test-fixme-ivy-jit": "bazel test --define=compile=jit --build_tag_filters=-no-ivy --test_tag_filters=-no-ivy",
"test-ivy-aot": "bazel test --define=compile=aot --build_tag_filters=ivy-aot --test_tag_filters=ivy-aot",
"test-fixme-ivy-aot": "bazel test --define=compile=aot --build_tag_filters=-no-ivy --test_tag_filters=-no-ivy"
"test-ivy-jit": "bazel test --define=compile=jit --build_tag_filters=-no-ivy-jit,-fixme-ivy-jit --test_tag_filters=-no-ivy-jit,-fixme-ivy-jit",
"test-fixme-ivy-jit": "bazel test --define=compile=jit --build_tag_filters=-no-ivy-jit --test_tag_filters=-no-ivy-jit",
"test-ivy-aot": "bazel test --define=compile=aot --build_tag_filters=-no-ivy-aot,-fixme-ivy-aot --test_tag_filters=-no-ivy-aot,-fixme-ivy-aot",
"test-fixme-ivy-aot": "bazel test --define=compile=aot --build_tag_filters=-no-ivy-aot --test_tag_filters=-no-ivy-aot",
"bazel": "bazel"
},
"// 1": "dependencies are used locally and by bazel",
"dependencies": {
"@angular-devkit/schematics": "^0.5.5",
"@schematics/angular": "^0.5.4",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.3",
"rxjs": "^6.3.0",
"tslib": "^1.7.1",
"zone.js": "^0.8.26"
},
"optionalDependencies": {
"fsevents": "1.1.2"
},
"devDependencies": {
"@bazel/ibazel": "^0.1.1",
"@bazel/karma": "0.20.3",
"@bazel/typescript": "0.20.3",
"@types/angular": "^1.6.47",
"@types/base64-js": "1.2.5",
"@schematics/angular": "^0.5.4",
"@types/chokidar": "1.7.3",
"@types/convert-source-map": "^1.5.1",
"@types/diff": "^3.2.2",
"@types/fs-extra": "4.0.2",
"@types/hammerjs": "2.0.35",
"@types/jasmine": "^2.8.8",
"@types/jasminewd2": "^2.0.4",
"@types/minimist": "^1.2.0",
"@types/mock-fs": "^3.6.30",
"@types/node": "^10.9.4",
"@types/selenium-webdriver": "3.0.7",
"@types/shelljs": "^0.7.8",
"@types/source-map": "^0.5.1",
"@types/systemjs": "0.19.32",
"@types/yargs": "^11.1.1",
"@webcomponents/custom-elements": "^1.0.4",
"angular": "npm:angular@1.7",
@ -72,23 +57,57 @@
"angular-mocks-1.5": "npm:angular-mocks@1.5",
"angular-mocks-1.6": "npm:angular-mocks@1.6",
"base64-js": "1.2.1",
"bower": "1.8.2",
"browserstacktunnel-wrapper": "2.0.1",
"canonical-path": "0.0.2",
"chokidar": "1.7.0",
"convert-source-map": "^1.5.1",
"dependency-graph": "^0.7.2",
"domino": "2.1.0",
"fs-extra": "4.0.2",
"jasmine": "^3.1.0",
"jasmine-core": "^3.1.0",
"karma": "^2.0.4",
"magic-string": "^0.25.0",
"minimist": "1.2.0",
"mock-fs": "^4.5.0",
"node-uuid": "1.4.8",
"protractor": "5.1.2",
"reflect-metadata": "^0.1.3",
"selenium-webdriver": "3.5.0",
"shelljs": "^0.8.1",
"source-map": "^0.6.1",
"source-map-support": "0.4.18",
"tsickle": "0.32.1",
"tslib": "^1.7.1",
"typescript": "~3.1.1",
"xhr2": "0.1.4",
"yargs": "9.0.1",
"zone.js": "^0.8.26"
},
"optionalDependencies": {
"fsevents": "1.1.2"
},
"// 2": "devDependencies are not used under Bazel. Many can be removed after test.sh is deleted.",
"devDependencies": {
"@bazel/bazel": "^0.18.1",
"@bazel/ibazel": "^0.1.1",
"@bazel/karma": "0.20.3",
"@types/angular": "^1.6.47",
"@types/base64-js": "1.2.5",
"@types/jasminewd2": "^2.0.4",
"@types/minimist": "^1.2.0",
"@types/systemjs": "0.19.32",
"bower": "1.8.2",
"browserstacktunnel-wrapper": "2.0.1",
"clang-format": "1.0.41",
"cldr": "4.10.0",
"cldr-data-downloader": "0.3.2",
"cldrjs": "0.5.0",
"conventional-changelog": "^2.0.3",
"convert-source-map": "^1.5.1",
"core-js": "^2.4.1",
"cors": "2.8.4",
"dependency-graph": "^0.7.2",
"diff": "^3.5.0",
"domino": "2.1.0",
"entities": "1.1.1",
"firefox-profile": "1.0.3",
"fs-extra": "4.0.2",
"glob": "7.1.2",
"gulp": "3.9.1",
"gulp-clang-format": "1.0.23",
@ -100,44 +119,29 @@
"hammerjs": "2.0.8",
"husky": "^0.14.3",
"incremental-dom": "0.4.1",
"jasmine": "^3.1.0",
"jasmine-core": "^3.1.0",
"jpm": "1.3.1",
"karma": "^2.0.4",
"karma-browserstack-launcher": "^1.3.0",
"karma-chrome-launcher": "^2.2.0",
"karma-jasmine": "^1.1.2",
"karma-sauce-launcher": "^1.2.0",
"karma-sourcemap-loader": "^0.3.7",
"madge": "0.5.0",
"magic-string": "^0.25.0",
"minimist": "1.2.0",
"mock-fs": "^4.5.0",
"mutation-observer": "^1.0.3",
"node-uuid": "1.4.8",
"protractor": "5.1.2",
"rewire": "2.5.2",
"rollup": "0.47.4",
"rollup-plugin-commonjs": "8.1.0",
"rollup-plugin-node-resolve": "3.0.0",
"rollup-plugin-sourcemaps": "0.4.2",
"selenium-webdriver": "3.5.0",
"rxjs": "^6.3.0",
"semver": "5.4.1",
"shelljs": "^0.8.1",
"source-map": "^0.6.1",
"source-map-support": "0.4.18",
"systemjs": "0.18.10",
"tsickle": "0.32.1",
"tslint": "5.7.0",
"tslint-eslint-rules": "4.1.1",
"tsutils": "2.27.2",
"typescript": "~3.1.1",
"uglify-es": "^3.3.9",
"universal-analytics": "0.4.15",
"vlq": "0.2.2",
"vrsource-tslint-rules": "5.1.1",
"webpack": "1.12.9",
"xhr2": "0.1.4",
"yargs": "9.0.1"
"webpack": "1.12.9"
}
}

View File

@ -22,4 +22,4 @@ protractor_web_test = _protractor_web_test
protractor_web_test_suite = _protractor_web_test_suite
ng_setup_workspace = _ng_setup_workspace
# DO NOT ADD PUBLIC API without including in the documentation generation
# Run `bazel build //packages/bazel/docs` to verify
# Run `yarn bazel build //packages/bazel/docs` to verify

View File

@ -22,6 +22,13 @@ def rules_angular_dependencies():
# Download Bazel toolchain dependencies as needed by build actions
#
# TODO(gmagolan): updated to next tagged rules_typescript release
_maybe(
http_archive,
name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.15.3.zip",
strip_prefix = "rules_nodejs-0.15.3",
)
_maybe(
http_archive,
name = "build_bazel_rules_typescript",
@ -80,16 +87,11 @@ def rules_angular_dev_dependencies():
url = "https://github.com/bazelbuild/bazel/archive/0.18.0.zip",
)
# This commit matches the version of buildifier in angular/ngcontainer
# If you change this, also check if it matches the version in the angular/ngcontainer
# version in /.circleci/config.yml
BAZEL_BUILDTOOLS_VERSION = "49a6c199e3fbf5d94534b2771868677d3f9c6de9"
http_archive(
name = "com_github_bazelbuild_buildtools",
sha256 = "edf39af5fc257521e4af4c40829fffe8fba6d0ebff9f4dd69a6f8f1223ae047b",
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
sha256 = "a82d4b353942b10c1535528b02bff261d020827c9c57e112569eddcb1c93d7f6",
strip_prefix = "buildtools-0.17.2",
url = "https://github.com/bazelbuild/buildtools/archive/0.17.2.zip",
)
#############################################

View File

@ -209,16 +209,20 @@ export function compile({allowNonHermeticReads, allDepsCompiledWithBazel = true,
// compilationTargetSrc.
// However we still want to give it an AMD module name for devmode.
// We can't easily tell which file is the synthetic one, so we build up the path we expect
// it to have
// and compare against that.
// it to have and compare against that.
if (fileName ===
path.join(compilerOpts.baseUrl, bazelOpts.package, compilerOpts.flatModuleOutFile + '.ts'))
return true;
// Also handle the case when angular is built from source as an external repository
if (fileName ===
path.join(
compilerOpts.baseUrl, 'external/angular', bazelOpts.package,
compilerOpts.flatModuleOutFile + '.ts'))
// Also handle the case the target is in an external repository.
// Pull the workspace name from the target which is formatted as `@wksp//package:target`
// if it the target is from an external workspace. If the target is from the local
// workspace then it will be formatted as `//package:target`.
const targetWorkspace = bazelOpts.target.split('/')[0].replace(/^@/, '');
if (targetWorkspace &&
fileName ===
path.join(
compilerOpts.baseUrl, 'external', targetWorkspace, bazelOpts.package,
compilerOpts.flatModuleOutFile + '.ts'))
return true;
return origBazelHostShouldNameModule(fileName) || NGC_GEN_FILES.test(fileName);
};

View File

@ -101,7 +101,7 @@ function runPackageGoldTest(testPackage: TestPackage) {
` Diff:\n` +
` ${patch}\n\n` +
` To accept the new golden file, run:\n` +
` bazel run ${process.env['BAZEL_TARGET']}.accept\n`;
` yarn bazel run ${process.env['BAZEL_TARGET']}.accept\n`;
fail(failureMessage);
}

View File

@ -15,5 +15,6 @@ ts_library(
"//packages:types",
"//packages/core",
"@ngdeps//@types/node",
"@ngdeps//reflect-metadata",
],
)

View File

@ -2,6 +2,7 @@ load("//packages/bazel:index.bzl", "ng_module")
ng_module(
name = "test_module",
testonly = True,
srcs = glob(["*.ts"]),
compiler = "//packages/bazel/src/ngc-wrapped",
entry_point = "index.ts",
@ -9,6 +10,10 @@ ng_module(
module_name = "some_npm_module",
ng_xi18n = "//packages/bazel/src/ngc-wrapped:xi18n",
node_modules = "@ngdeps//typescript:typescript__typings",
tags = [
"fixme-ivy-aot",
"no-ivy-jit",
],
deps = [
"//packages/core",
"@ngdeps//@types",
@ -19,6 +24,7 @@ load(":extract_flat_module_index.bzl", "extract_flat_module_index")
extract_flat_module_index(
name = "flat_module_index",
testonly = True,
deps = [":test_module"],
)

View File

@ -10,7 +10,7 @@ This conversion will allow such "legacy" packages to be used by the Ivy renderin
The project is built using Bazel:
```bash
bazel build //packages/compiler-cli/src/ngcc
yarn bazel build //packages/compiler-cli/src/ngcc
```
## Unit Testing
@ -18,7 +18,7 @@ bazel build //packages/compiler-cli/src/ngcc
The unit tests are built and run using Bazel:
```bash
bazel test //packages/compiler-cli/src/ngcc/test
yarn bazel test //packages/compiler-cli/src/ngcc/test
```
## Integration Testing
@ -26,5 +26,5 @@ bazel test //packages/compiler-cli/src/ngcc/test
There are tests that check the behaviour of the overall executable:
```bash
bazel test //packages/compiler-cli/test/ngcc
yarn bazel test //packages/compiler-cli/test/ngcc
```

View File

@ -202,6 +202,7 @@ export class ComponentDecoratorHandler implements
directives: EMPTY_MAP,
wrapDirectivesInClosure: false, //
animations,
viewProviders: null,
},
parsedTemplate: template.nodes,
},

View File

@ -177,6 +177,7 @@ export function extractDirectiveMetadata(
type: new WrappedNodeExpr(clazz.name !),
typeArgumentCount: reflector.getGenericArityOfClass(clazz) || 0,
typeSourceSpan: null !, usesInheritance, exportAs,
providers: null,
};
return {decoratedElements, decorator: directive, metadata};
}
@ -327,7 +328,7 @@ function parseFieldToPropertyMapping(
*/
function parseDecoratedFields(
fields: {member: ClassMember, decorators: Decorator[]}[], reflector: ReflectionHost,
checker: ts.TypeChecker): {[field: string]: string} {
checker: ts.TypeChecker) {
return fields.reduce(
(results, field) => {
const fieldName = field.member.name;
@ -353,6 +354,14 @@ function parseDecoratedFields(
{} as{[field: string]: string});
}
function resolveInput(publicName: string, internalName: string): [string, string] {
return [publicName, internalName];
}
function resolveOutput(publicName: string, internalName: string) {
return publicName;
}
export function queriesFromFields(
fields: {member: ClassMember, decorators: Decorator[]}[], reflector: ReflectionHost,
checker: ts.TypeChecker): R3QueryMetadata[] {

View File

@ -518,7 +518,7 @@ function tcbGetInputBindingExpressions(
// is desired. Invert `dir.inputs` into `propMatch` to create this map.
const propMatch = new Map<string, string>();
const inputs = dir.inputs;
Object.keys(inputs).forEach(key => propMatch.set(inputs[key], key));
Object.keys(inputs).forEach(key => propMatch.set(inputs[key] as string, key));
// Add a binding expression to the map for each input of the directive that has a
// matching binding.

View File

@ -1,3 +1,5 @@
Tests in this directory should be run with:
bazel test --define=compile=aot packages/compiler-cli/test/compliance:compliance
```
yarn bazel test --define=compile=aot packages/compiler-cli/test/compliance:compliance
```

View File

@ -13,6 +13,9 @@
"paths": {
"@angular/compiler": ["../../dist/packages/compiler"]
},
"types": [
"node"
],
"outDir": "../../dist/packages/compiler-cli"
},
"bazelOptions": {

View File

@ -22,5 +22,5 @@
"ng-update": {
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
},
"sideEffects": false
}
"sideEffects": true
}

View File

@ -353,8 +353,8 @@ export class StaticSymbolResolver {
// correctly.
const originFilePath = this.resolveModule(origin, filePath);
if (!originFilePath) {
this.reportError(
new Error(`Couldn't resolve original symbol for ${origin} from ${filePath}`));
this.reportError(new Error(
`Couldn't resolve original symbol for ${origin} from ${this.host.getOutputName(filePath)}`));
} else {
this.symbolResourcePaths.set(symbol, originFilePath);
}
@ -420,7 +420,8 @@ export class StaticSymbolResolver {
if (!filePath) {
return {
__symbolic: 'error',
message: `Could not resolve ${module} relative to ${sourceSymbol.filePath}.`,
message:
`Could not resolve ${module} relative to ${self.host.getMetadataFor(sourceSymbol.filePath)}.`,
line: map.line,
character: map.character,
fileName: getOriginalName()
@ -504,7 +505,7 @@ export class StaticSymbolResolver {
if (moduleMetadata['version'] != SUPPORTED_SCHEMA_VERSION) {
const errorMessage = moduleMetadata['version'] == 2 ?
`Unsupported metadata version ${moduleMetadata['version']} for module ${module}. This module should be compiled with a newer version of ngc` :
`Metadata version mismatch for module ${module}, found version ${moduleMetadata['version']}, expected ${SUPPORTED_SCHEMA_VERSION}`;
`Metadata version mismatch for module ${this.host.getOutputName(module)}, found version ${moduleMetadata['version']}, expected ${SUPPORTED_SCHEMA_VERSION}`;
this.reportError(new Error(errorMessage));
}
this.metadataCache.set(module, moduleMetadata);
@ -518,7 +519,7 @@ export class StaticSymbolResolver {
if (!filePath) {
this.reportError(
new Error(`Could not resolve module ${module}${containingFile ? ' relative to ' +
containingFile : ''}`));
this.host.getOutputName(containingFile) : ''}`));
return this.getStaticSymbol(`ERROR:${module}`, symbolName);
}
return this.getStaticSymbol(filePath, symbolName);

View File

@ -6,6 +6,11 @@
* found in the LICENSE file at https://angular.io/license
*/
//////////////////////////////////////
// THIS FILE HAS GLOBAL SIDE EFFECT //
// (see bottom of file) //
//////////////////////////////////////
/**
* @module
* @description
@ -23,6 +28,8 @@
*/
import * as core from './core';
import {publishFacade} from './jit_compiler_facade';
import {global} from './util';
export {core};
@ -91,4 +98,9 @@ export {compilePipeFromMetadata, R3PipeMetadata} from './render3/r3_pipe_compile
export {makeBindingParser, parseTemplate} from './render3/view/template';
export {R3Reference} from './render3/util';
export {compileBaseDefFromMetadata, R3BaseRefMetaData, compileComponentFromMetadata, compileDirectiveFromMetadata, parseHostBindings} from './render3/view/compiler';
export {publishFacade} from './jit_compiler_facade';
// This file only reexports content of the `src` folder. Keep it that way.
// This function call has a global side effects and publishes the compiler into global namespace for
// the late binding of the Compiler to the @angular/core for jit compilation.
publishFacade(global);

View File

@ -0,0 +1,146 @@
/**
* @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
*/
/**
* A set of interfaces which are shared between `@angular/core` and `@angular/compiler` to allow
* for late binding of `@angular/compiler` for JIT purposes.
*
* This file has two copies. Please ensure that they are in sync:
* - packages/compiler/src/compiler_facade_interface.ts (master)
* - packages/core/src/render3/jit/compiler_facade_interface.ts (copy)
*
* Please ensure that the two files are in sync using this command:
* ```
* cp packages/compiler/src/compiler_facade_interface.ts \
* packages/core/src/render3/jit/compiler_facade_interface.ts
* ```
*/
export interface ExportedCompilerFacade { ɵcompilerFacade: CompilerFacade; }
export interface CompilerFacade {
compilePipe(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3PipeMetadataFacade):
any;
compileInjectable(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectableMetadataFacade): any;
compileInjector(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectorMetadataFacade): any;
compileNgModule(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3NgModuleMetadataFacade): any;
compileDirective(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3DirectiveMetadataFacade): any;
compileComponent(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3ComponentMetadataFacade): any;
R3ResolvedDependencyType: typeof R3ResolvedDependencyType;
}
export interface CoreEnvironment { [name: string]: Function; }
export type StringMap = {
[key: string]: string;
};
export type StringMapWithRename = {
[key: string]: string | [string, string];
};
export type Provider = any;
export enum R3ResolvedDependencyType {
Token = 0,
Attribute = 1,
Injector = 2,
}
export interface R3DependencyMetadataFacade {
token: any;
resolved: R3ResolvedDependencyType;
host: boolean;
optional: boolean;
self: boolean;
skipSelf: boolean;
}
export interface R3PipeMetadataFacade {
name: string;
type: any;
pipeName: string;
deps: R3DependencyMetadataFacade[]|null;
pure: boolean;
}
export interface R3InjectableMetadataFacade {
name: string;
type: any;
ctorDeps: R3DependencyMetadataFacade[]|null;
providedIn: any;
useClass?: any;
useFactory?: any;
useExisting?: any;
useValue?: any;
userDeps?: R3DependencyMetadataFacade[];
}
export interface R3NgModuleMetadataFacade {
type: any;
bootstrap: Function[];
declarations: Function[];
imports: Function[];
exports: Function[];
emitInline: boolean;
}
export interface R3InjectorMetadataFacade {
name: string;
type: any;
deps: R3DependencyMetadataFacade[]|null;
providers: any;
imports: any;
}
export interface R3DirectiveMetadataFacade {
name: string;
type: any;
typeArgumentCount: number;
typeSourceSpan: null;
deps: R3DependencyMetadataFacade[]|null;
selector: string|null;
queries: R3QueryMetadataFacade[];
host: {[key: string]: string};
propMetadata: {[key: string]: any[]};
lifecycle: {usesOnChanges: boolean;};
inputs: string[];
outputs: string[];
usesInheritance: boolean;
exportAs: string|null;
providers: Provider[]|null;
}
export interface R3ComponentMetadataFacade extends R3DirectiveMetadataFacade {
template: string;
preserveWhitespaces: boolean;
animations: any[]|undefined;
viewQueries: R3QueryMetadataFacade[];
pipes: Map<string, any>;
directives: Map<string, any>;
styles: string[];
encapsulation: ViewEncapsulation;
viewProviders: Provider[]|null;
}
export type ViewEncapsulation = number;
export interface R3QueryMetadataFacade {
propertyName: string;
first: boolean;
predicate: any|string[];
descendants: boolean;
read: any|null;
}

View File

@ -0,0 +1,294 @@
/**
* @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 {CompilerFacade, CoreEnvironment, ExportedCompilerFacade, R3ComponentMetadataFacade, R3DependencyMetadataFacade, R3DirectiveMetadataFacade, R3InjectableMetadataFacade, R3InjectorMetadataFacade, R3NgModuleMetadataFacade, R3PipeMetadataFacade, R3QueryMetadataFacade, StringMap, StringMapWithRename} from './compiler_facade_interface';
import {ConstantPool} from './constant_pool';
import {HostBinding, HostListener, Input, Output, Type} from './core';
import {compileInjectable} from './injectable_compiler_2';
import {Expression, LiteralExpr, WrappedNodeExpr} from './output/output_ast';
import {R3DependencyMetadata, R3ResolvedDependencyType} from './render3/r3_factory';
import {jitExpression} from './render3/r3_jit';
import {R3InjectorMetadata, R3NgModuleMetadata, compileInjector, compileNgModule} from './render3/r3_module_compiler';
import {compilePipeFromMetadata} from './render3/r3_pipe_compiler';
import {R3Reference} from './render3/util';
import {R3DirectiveMetadata, R3QueryMetadata} from './render3/view/api';
import {compileComponentFromMetadata, compileDirectiveFromMetadata, parseHostBindings} from './render3/view/compiler';
import {makeBindingParser, parseTemplate} from './render3/view/template';
export class CompilerFacadeImpl implements CompilerFacade {
R3ResolvedDependencyType = R3ResolvedDependencyType as any;
compilePipe(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, facade: R3PipeMetadataFacade):
any {
const res = compilePipeFromMetadata({
name: facade.name,
type: new WrappedNodeExpr(facade.type),
deps: convertR3DependencyMetadataArray(facade.deps),
pipeName: facade.pipeName,
pure: facade.pure,
});
return jitExpression(res.expression, angularCoreEnv, sourceMapUrl, res.statements);
}
compileInjectable(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
facade: R3InjectableMetadataFacade): any {
const {expression, statements} = compileInjectable({
name: facade.name,
type: new WrappedNodeExpr(facade.type),
providedIn: computeProvidedIn(facade.providedIn),
useClass: wrapExpression(facade, USE_CLASS),
useFactory: wrapExpression(facade, USE_FACTORY),
useValue: wrapExpression(facade, USE_VALUE),
useExisting: wrapExpression(facade, USE_EXISTING),
ctorDeps: convertR3DependencyMetadataArray(facade.ctorDeps),
userDeps: convertR3DependencyMetadataArray(facade.userDeps) || undefined,
});
return jitExpression(expression, angularCoreEnv, sourceMapUrl, statements);
}
compileInjector(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
facade: R3InjectorMetadataFacade): any {
const meta: R3InjectorMetadata = {
name: facade.name,
type: new WrappedNodeExpr(facade.type),
deps: convertR3DependencyMetadataArray(facade.deps),
providers: new WrappedNodeExpr(facade.providers),
imports: new WrappedNodeExpr(facade.imports),
};
const res = compileInjector(meta);
return jitExpression(res.expression, angularCoreEnv, sourceMapUrl, res.statements);
}
compileNgModule(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
facade: R3NgModuleMetadataFacade): any {
const meta: R3NgModuleMetadata = {
type: new WrappedNodeExpr(facade.type),
bootstrap: facade.bootstrap.map(wrapReference),
declarations: facade.declarations.map(wrapReference),
imports: facade.imports.map(wrapReference),
exports: facade.exports.map(wrapReference),
emitInline: true,
};
const res = compileNgModule(meta);
return jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []);
}
compileDirective(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
facade: R3DirectiveMetadataFacade): any {
const constantPool = new ConstantPool();
const bindingParser = makeBindingParser();
const meta: R3DirectiveMetadata = convertDirectiveFacadeToMetadata(facade);
const res = compileDirectiveFromMetadata(meta, constantPool, bindingParser);
const preStatements = [...constantPool.statements, ...res.statements];
return jitExpression(res.expression, angularCoreEnv, sourceMapUrl, preStatements);
}
compileComponent(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
facade: R3ComponentMetadataFacade): any {
// The ConstantPool is a requirement of the JIT'er.
const constantPool = new ConstantPool();
// Parse the template and check for errors.
const template = parseTemplate(
facade.template, sourceMapUrl, {
preserveWhitespaces: facade.preserveWhitespaces || false,
},
'');
if (template.errors !== undefined) {
const errors = template.errors.map(err => err.toString()).join(', ');
throw new Error(`Errors during JIT compilation of template for ${facade.name}: ${errors}`);
}
// Compile the component metadata, including template, into an expression.
// TODO(alxhub): implement inputs, outputs, queries, etc.
const res = compileComponentFromMetadata(
{
...facade as R3ComponentMetadataFacadeNoPropAndWhitespace,
...convertDirectiveFacadeToMetadata(facade),
template,
viewQueries: facade.viewQueries.map(convertToR3QueryMetadata),
wrapDirectivesInClosure: false,
styles: facade.styles || [],
encapsulation: facade.encapsulation as any,
animations: facade.animations != null ? new WrappedNodeExpr(facade.animations) : null,
viewProviders: facade.viewProviders != null ? new WrappedNodeExpr(facade.viewProviders) :
null,
},
constantPool, makeBindingParser());
const preStatements = [...constantPool.statements, ...res.statements];
return jitExpression(res.expression, angularCoreEnv, sourceMapUrl, preStatements);
}
}
// This seems to be needed to placate TS v3.0 only
type R3ComponentMetadataFacadeNoPropAndWhitespace = Pick<
R3ComponentMetadataFacade,
Exclude<Exclude<keyof R3ComponentMetadataFacade, 'preserveWhitespaces'>, 'propMetadata'>>;
const USE_CLASS = Object.keys({useClass: null})[0];
const USE_FACTORY = Object.keys({useFactory: null})[0];
const USE_VALUE = Object.keys({useValue: null})[0];
const USE_EXISTING = Object.keys({useExisting: null})[0];
const wrapReference = function(value: Type): R3Reference {
const wrapped = new WrappedNodeExpr(value);
return {value: wrapped, type: wrapped};
};
function convertToR3QueryMetadata(facade: R3QueryMetadataFacade): R3QueryMetadata {
return {
...facade,
predicate: Array.isArray(facade.predicate) ? facade.predicate :
new WrappedNodeExpr(facade.predicate),
read: facade.read ? new WrappedNodeExpr(facade.read) : null,
};
}
function convertDirectiveFacadeToMetadata(facade: R3DirectiveMetadataFacade): R3DirectiveMetadata {
const inputsFromMetadata = parseInputOutputs(facade.inputs || []);
const outputsFromMetadata = parseInputOutputs(facade.outputs || []);
const propMetadata = facade.propMetadata;
const inputsFromType: StringMapWithRename = {};
const outputsFromType: StringMap = {};
for (const field in propMetadata) {
if (propMetadata.hasOwnProperty(field)) {
propMetadata[field].forEach(ann => {
if (isInput(ann)) {
inputsFromType[field] =
ann.bindingPropertyName ? [ann.bindingPropertyName, field] : field;
} else if (isOutput(ann)) {
outputsFromType[field] = ann.bindingPropertyName || field;
}
});
}
}
return {
...facade as R3DirectiveMetadataFacadeNoPropAndWhitespace,
typeSourceSpan: null !,
type: new WrappedNodeExpr(facade.type),
deps: convertR3DependencyMetadataArray(facade.deps),
host: extractHostBindings(facade.host, facade.propMetadata),
inputs: {...inputsFromMetadata, ...inputsFromType},
outputs: {...outputsFromMetadata, ...outputsFromType},
providers: facade.providers != null ? new WrappedNodeExpr(facade.providers) : null,
};
}
// This seems to be needed to placate TS v3.0 only
type R3DirectiveMetadataFacadeNoPropAndWhitespace =
Pick<R3DirectiveMetadataFacade, Exclude<keyof R3DirectiveMetadataFacade, 'propMetadata'>>;
function wrapExpression(obj: any, property: string): WrappedNodeExpr<any>|undefined {
if (obj.hasOwnProperty(property)) {
return new WrappedNodeExpr(obj[property]);
} else {
return undefined;
}
}
function computeProvidedIn(providedIn: Type | string | null | undefined): Expression {
if (providedIn == null || typeof providedIn === 'string') {
return new LiteralExpr(providedIn);
} else {
return new WrappedNodeExpr(providedIn);
}
}
function convertR3DependencyMetadata(facade: R3DependencyMetadataFacade): R3DependencyMetadata {
let tokenExpr;
if (facade.token === null) {
tokenExpr = new LiteralExpr(null);
} else if (facade.resolved === R3ResolvedDependencyType.Attribute) {
tokenExpr = new LiteralExpr(facade.token);
} else {
tokenExpr = new WrappedNodeExpr(facade.token);
}
return {
token: tokenExpr,
resolved: facade.resolved,
host: facade.host,
optional: facade.optional,
self: facade.self,
skipSelf: facade.skipSelf
};
}
function convertR3DependencyMetadataArray(facades: R3DependencyMetadataFacade[] | null | undefined):
R3DependencyMetadata[]|null {
return facades == null ? null : facades.map(convertR3DependencyMetadata);
}
function extractHostBindings(host: {[key: string]: string}, propMetadata: {[key: string]: any[]}): {
attributes: StringMap,
listeners: StringMap,
properties: StringMap,
} {
// First parse the declarations from the metadata.
const {attributes, listeners, properties, animations} = parseHostBindings(host || {});
if (Object.keys(animations).length > 0) {
throw new Error(`Animation bindings are as-of-yet unsupported in Ivy`);
}
// Next, loop over the properties of the object, looking for @HostBinding and @HostListener.
for (const field in propMetadata) {
if (propMetadata.hasOwnProperty(field)) {
propMetadata[field].forEach(ann => {
if (isHostBinding(ann)) {
properties[ann.hostPropertyName || field] = field;
} else if (isHostListener(ann)) {
listeners[ann.eventName || field] = `${field}(${(ann.args || []).join(',')})`;
}
});
}
}
return {attributes, listeners, properties};
}
function isHostBinding(value: any): value is HostBinding {
return value.ngMetadataName === 'HostBinding';
}
function isHostListener(value: any): value is HostListener {
return value.ngMetadataName === 'HostListener';
}
function isInput(value: any): value is Input {
return value.ngMetadataName === 'Input';
}
function isOutput(value: any): value is Output {
return value.ngMetadataName === 'Output';
}
function parseInputOutputs(values: string[]): StringMap {
return values.reduce(
(map, value) => {
const [field, property] = value.split(',').map(piece => piece.trim());
map[field] = property || field;
return map;
},
{} as StringMap);
}
export function publishFacade(global: any) {
const ng: ExportedCompilerFacade = global.ng || (global.ng = {});
ng.ɵcompilerFacade = new CompilerFacadeImpl();
}

View File

@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.io/license
*/
import {StaticSymbol} from '../aot/static_symbol';
import {CompileShallowModuleMetadata, identifierName} from '../compile_metadata';
import {InjectableCompiler} from '../injectable_compiler';
import {mapLiteral} from '../output/map_util';

View File

@ -86,7 +86,7 @@ export interface R3DirectiveMetadata {
/**
* A mapping of input field names to the property names.
*/
inputs: {[field: string]: string};
inputs: {[field: string]: string | [string, string]};
/**
* A mapping of output field names to the property names.
@ -103,6 +103,11 @@ export interface R3DirectiveMetadata {
* if any.
*/
exportAs: string|null;
/**
* The list of providers defined in the directive.
*/
providers: o.Expression|null;
}
/**
@ -180,6 +185,11 @@ export interface R3ComponentMetadata extends R3DirectiveMetadata {
* A collection of animation triggers that will be used in the component template.
*/
animations: o.Expression|null;
/**
* The list of view providers defined in the component.
*/
viewProviders: o.Expression|null;
}
/**

View File

@ -320,6 +320,7 @@ export function compileComponentFromRender2(
encapsulation:
(summary.template && summary.template.encapsulation) || core.ViewEncapsulation.Emulated,
animations: null,
viewProviders: null,
};
const res = compileComponentFromMetadata(meta, outputCtx.constantPool, bindingParser);
@ -362,6 +363,7 @@ function directiveMetadataFromGlobalMetadata(
outputs: directive.outputs,
usesInheritance: false,
exportAs: null,
providers: null,
};
}
@ -505,7 +507,7 @@ function stringAsType(str: string): o.Type {
return o.expressionType(o.literal(str));
}
function stringMapAsType(map: {[key: string]: string}): o.Type {
function stringMapAsType(map: {[key: string]: string | [string, string]}): o.Type {
const mapValues = Object.keys(map).map(key => ({
key,
value: o.literal(map[key]),

View File

@ -44,7 +44,7 @@ export interface DirectiveMeta {
*
* Goes from property names to field names.
*/
inputs: {[property: string]: string};
inputs: {[property: string]: string | [string, string]};
/**
* Set of outputs which this directive claims.

View File

@ -67,8 +67,8 @@ export function asLiteral(value: any): o.Expression {
return o.literal(value, o.INFERRED_TYPE);
}
export function conditionallyCreateMapObjectLiteral(keys: {[key: string]: string}): o.Expression|
null {
export function conditionallyCreateMapObjectLiteral(
keys: {[key: string]: string | [string, string]}): o.Expression|null {
if (Object.getOwnPropertyNames(keys).length > 0) {
return mapToExpression(keys);
}

View File

@ -233,3 +233,19 @@ export interface Console {
log(message: string): void;
warn(message: string): void;
}
declare var WorkerGlobalScope: any;
// CommonJS / Node have global context exposed as "global" variable.
// We don't want to include the whole node.d.ts this this compilation unit so we'll just fake
// the global "global" var for now.
declare var global: any;
const __window = typeof window !== 'undefined' && window;
const __self = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
self instanceof WorkerGlobalScope && self;
const __global = typeof global !== 'undefined' && global;
// Check __global first, because in Node tests both __global and __window may be defined and _global
// should be __global in that case.
const _global: {[name: string]: any} = __global || __window || __self;
export {_global as global};

View File

@ -0,0 +1,100 @@
/**
* @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 * as core from '../../core/src/render3/jit/compiler_facade_interface';
import {R3ResolvedDependencyType} from '../public_api';
import * as compiler from '../src/compiler_facade_interface';
/**
* This file is compiler level file which asserts that the set of interfaces in `@angular/core` and
* `@angular/compiler` match. (Build time failure.)
*
* If this file fails to compile it means these two files when out of sync:
* - packages/compiler/src/compiler_facade_interface.ts (master)
* - packages/core/src/render3/jit/compiler_facade_interface.ts (copy)
*
* Please ensure that the two files are in sync using this command:
* ```
* cp packages/compiler/src/compiler_facade_interface.ts \
* packages/core/src/render3/jit/compiler_facade_interface.ts
* ```
*/
const coreExportedCompilerFacade1: core.ExportedCompilerFacade =
null !as compiler.ExportedCompilerFacade;
const compilerExportedCompilerFacade2: compiler.ExportedCompilerFacade =
null !as core.ExportedCompilerFacade;
const coreCompilerFacade: core.CompilerFacade = null !as compiler.CompilerFacade;
const compilerCompilerFacade: compiler.CompilerFacade = null !as core.CompilerFacade;
const coreCoreEnvironment: core.CoreEnvironment = null !as compiler.CoreEnvironment;
const compilerCoreEnvironment: compiler.CoreEnvironment = null !as core.CoreEnvironment;
const coreStringMap: core.StringMap = null !as compiler.StringMap;
const compilerStringMap: compiler.StringMap = null !as core.StringMap;
const coreProvider: core.Provider = null !as compiler.Provider;
const compilerProvider: compiler.Provider = null !as core.Provider;
const coreR3ResolvedDependencyType: core.R3ResolvedDependencyType =
null !as compiler.R3ResolvedDependencyType;
const compilerR3ResolvedDependencyType: compiler.R3ResolvedDependencyType =
null !as core.R3ResolvedDependencyType;
const coreR3ResolvedDependencyType2: R3ResolvedDependencyType =
null !as core.R3ResolvedDependencyType;
const compilerR3ResolvedDependencyType2: R3ResolvedDependencyType =
null !as core.R3ResolvedDependencyType;
const coreR3ResolvedDependencyType3: core.R3ResolvedDependencyType =
null !as R3ResolvedDependencyType;
const compilerR3ResolvedDependencyType3: compiler.R3ResolvedDependencyType =
null !as R3ResolvedDependencyType;
const coreR3DependencyMetadataFacade: core.R3DependencyMetadataFacade =
null !as compiler.R3DependencyMetadataFacade;
const compilerR3DependencyMetadataFacade: compiler.R3DependencyMetadataFacade =
null !as core.R3DependencyMetadataFacade;
const coreR3PipeMetadataFacade: core.R3PipeMetadataFacade = null !as compiler.R3PipeMetadataFacade;
const compilerR3PipeMetadataFacade: compiler.R3PipeMetadataFacade =
null !as core.R3PipeMetadataFacade;
const coreR3InjectableMetadataFacade: core.R3InjectableMetadataFacade =
null !as compiler.R3InjectableMetadataFacade;
const compilerR3InjectableMetadataFacade: compiler.R3InjectableMetadataFacade =
null !as core.R3InjectableMetadataFacade;
const coreR3NgModuleMetadataFacade: core.R3NgModuleMetadataFacade =
null !as compiler.R3NgModuleMetadataFacade;
const compilerR3NgModuleMetadataFacade: compiler.R3NgModuleMetadataFacade =
null !as core.R3NgModuleMetadataFacade;
const coreR3InjectorMetadataFacade: core.R3InjectorMetadataFacade =
null !as compiler.R3InjectorMetadataFacade;
const compilerR3InjectorMetadataFacade: compiler.R3InjectorMetadataFacade =
null !as core.R3InjectorMetadataFacade;
const coreR3DirectiveMetadataFacade: core.R3DirectiveMetadataFacade =
null !as compiler.R3DirectiveMetadataFacade;
const compilerR3DirectiveMetadataFacade: compiler.R3DirectiveMetadataFacade =
null !as core.R3DirectiveMetadataFacade;
const coreR3ComponentMetadataFacade: core.R3ComponentMetadataFacade =
null !as compiler.R3ComponentMetadataFacade;
const compilerR3ComponentMetadataFacade: compiler.R3ComponentMetadataFacade =
null !as core.R3ComponentMetadataFacade;
const coreViewEncapsulation: core.ViewEncapsulation = null !as compiler.ViewEncapsulation;
const compilerViewEncapsulation: compiler.ViewEncapsulation = null !as core.ViewEncapsulation;
const coreR3QueryMetadataFacade: core.R3QueryMetadataFacade =
null !as compiler.R3QueryMetadataFacade;
const compilerR3QueryMetadataFacade: compiler.R3QueryMetadataFacade =
null !as core.R3QueryMetadataFacade;

View File

@ -20,7 +20,6 @@ ng_module(
module_name = "@angular/core",
deps = [
"//packages:types",
"//packages/compiler",
"@ngdeps//zone.js",
"@rxjs",
"@rxjs//operators",

View File

@ -16,7 +16,6 @@
"tslib": "^1.9.0"
},
"peerDependencies": {
"@angular/compiler": "0.0.0-PLACEHOLDER",
"rxjs": "^6.0.0",
"zone.js": "~0.8.26"
},
@ -28,4 +27,4 @@
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
},
"sideEffects": false
}
}

View File

@ -18,9 +18,9 @@ import {GetterFn, MethodFn, SetterFn} from './types';
* Attention: These regex has to hold even if the code is minified!
*/
export const DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*arguments\)/;
export const INHERITED_CLASS = /^class\s+[A-Za-z\d$_]*\s*extends\s+[A-Za-z\d$_]+\s*{/;
export const INHERITED_CLASS = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{/;
export const INHERITED_CLASS_WITH_CTOR =
/^class\s+[A-Za-z\d$_]*\s*extends\s+[A-Za-z\d$_]+\s*{[\s\S]*constructor\s*\(/;
/^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{[\s\S]*constructor\s*\(/;
export class ReflectionCapabilities implements PlatformReflectionCapabilities {
private _reflect: any;

View File

@ -448,6 +448,7 @@ function searchDirectivesOnInjector<T>(
*/
export function bloomHashBitOrFactory(token: Type<any>| InjectionToken<any>): number|Function|
undefined {
ngDevMode && assertDefined(token, 'token must be defined');
const tokenId: number|undefined = (token as any)[NG_ELEMENT_ID];
return typeof tokenId === 'number' ? tokenId & BLOOM_MASK : tokenId;
}

View File

@ -0,0 +1,22 @@
/**
* @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 {global} from '../../util';
import {CompilerFacade, ExportedCompilerFacade} from './compiler_facade_interface';
export * from './compiler_facade_interface';
export function getCompilerFacade(): CompilerFacade {
const globalNg: ExportedCompilerFacade = global.ng;
if (!globalNg || !globalNg.ɵcompilerFacade) {
throw new Error(
`Angular JIT compilation failed: '@angular/compiler' not loaded!\n` +
` - JIT compilation is discouraged for production use-cases! Consider AOT mode instead.\n` +
` - Did you bootstrap using '@angular/platform-browser-dynamic' or '@angular/platform-server'?\n` +
` - Alternatively provide the compiler with 'import "@angular/compiler";' before bootstrapping.`);
}
return globalNg.ɵcompilerFacade;
}

View File

@ -0,0 +1,146 @@
/**
* @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
*/
/**
* A set of interfaces which are shared between `@angular/core` and `@angular/compiler` to allow
* for late binding of `@angular/compiler` for JIT purposes.
*
* This file has two copies. Please ensure that they are in sync:
* - packages/compiler/src/compiler_facade_interface.ts (master)
* - packages/core/src/render3/jit/compiler_facade_interface.ts (copy)
*
* Please ensure that the two files are in sync using this command:
* ```
* cp packages/compiler/src/compiler_facade_interface.ts \
* packages/core/src/render3/jit/compiler_facade_interface.ts
* ```
*/
export interface ExportedCompilerFacade { ɵcompilerFacade: CompilerFacade; }
export interface CompilerFacade {
compilePipe(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3PipeMetadataFacade):
any;
compileInjectable(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectableMetadataFacade): any;
compileInjector(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectorMetadataFacade): any;
compileNgModule(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3NgModuleMetadataFacade): any;
compileDirective(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3DirectiveMetadataFacade): any;
compileComponent(
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3ComponentMetadataFacade): any;
R3ResolvedDependencyType: typeof R3ResolvedDependencyType;
}
export interface CoreEnvironment { [name: string]: Function; }
export type StringMap = {
[key: string]: string;
};
export type StringMapWithRename = {
[key: string]: string | [string, string];
};
export type Provider = any;
export enum R3ResolvedDependencyType {
Token = 0,
Attribute = 1,
Injector = 2,
}
export interface R3DependencyMetadataFacade {
token: any;
resolved: R3ResolvedDependencyType;
host: boolean;
optional: boolean;
self: boolean;
skipSelf: boolean;
}
export interface R3PipeMetadataFacade {
name: string;
type: any;
pipeName: string;
deps: R3DependencyMetadataFacade[]|null;
pure: boolean;
}
export interface R3InjectableMetadataFacade {
name: string;
type: any;
ctorDeps: R3DependencyMetadataFacade[]|null;
providedIn: any;
useClass?: any;
useFactory?: any;
useExisting?: any;
useValue?: any;
userDeps?: R3DependencyMetadataFacade[];
}
export interface R3NgModuleMetadataFacade {
type: any;
bootstrap: Function[];
declarations: Function[];
imports: Function[];
exports: Function[];
emitInline: boolean;
}
export interface R3InjectorMetadataFacade {
name: string;
type: any;
deps: R3DependencyMetadataFacade[]|null;
providers: any;
imports: any;
}
export interface R3DirectiveMetadataFacade {
name: string;
type: any;
typeArgumentCount: number;
typeSourceSpan: null;
deps: R3DependencyMetadataFacade[]|null;
selector: string|null;
queries: R3QueryMetadataFacade[];
host: {[key: string]: string};
propMetadata: {[key: string]: any[]};
lifecycle: {usesOnChanges: boolean;};
inputs: string[];
outputs: string[];
usesInheritance: boolean;
exportAs: string|null;
providers: Provider[]|null;
}
export interface R3ComponentMetadataFacade extends R3DirectiveMetadataFacade {
template: string;
preserveWhitespaces: boolean;
animations: any[]|undefined;
viewQueries: R3QueryMetadataFacade[];
pipes: Map<string, any>;
directives: Map<string, any>;
styles: string[];
encapsulation: ViewEncapsulation;
viewProviders: Provider[]|null;
}
export type ViewEncapsulation = number;
export interface R3QueryMetadataFacade {
propertyName: string;
first: boolean;
predicate: any|string[];
descendants: boolean;
read: any|null;
}

View File

@ -6,22 +6,22 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ConstantPool, R3DirectiveMetadata, WrappedNodeExpr, compileComponentFromMetadata as compileR3Component, compileDirectiveFromMetadata as compileR3Directive, jitExpression, makeBindingParser, parseHostBindings, parseTemplate} from '@angular/compiler';
import {Component, Directive, HostBinding, HostListener, Input, Output} from '../../metadata/directives';
import {Query} from '../../metadata/di';
import {Component, Directive} from '../../metadata/directives';
import {componentNeedsResolution, maybeQueueResolutionOfComponentResources} from '../../metadata/resource_loading';
import {ViewEncapsulation} from '../../metadata/view';
import {Type} from '../../type';
import {stringify} from '../../util';
import {EMPTY_ARRAY} from '../definition';
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF} from '../fields';
import {R3DirectiveMetadataFacade, getCompilerFacade} from './compiler_facade';
import {R3ComponentMetadataFacade, R3QueryMetadataFacade} from './compiler_facade_interface';
import {angularCoreEnv} from './environment';
import {patchComponentDefWithScope, transitiveScopesFor} from './module';
import {getReflect, reflectDependencies} from './util';
type StringMap = {
[key: string]: string
};
/**
* Compile an Angular component according to its decorator metadata, and patch the resulting
@ -38,6 +38,7 @@ export function compileComponent(type: Type<any>, metadata: Component): void {
maybeQueueResolutionOfComponentResources(metadata);
Object.defineProperty(type, NG_COMPONENT_DEF, {
get: () => {
const compiler = getCompilerFacade();
if (ngComponentDef === null) {
if (componentNeedsResolution(metadata)) {
const error = [`Component '${stringify(type)}' is not resolved:`];
@ -50,42 +51,20 @@ export function compileComponent(type: Type<any>, metadata: Component): void {
error.push(`Did you run and wait for 'resolveComponentResources()'?`);
throw new Error(error.join('\n'));
}
// The ConstantPool is a requirement of the JIT'er.
const constantPool = new ConstantPool();
// Parse the template and check for errors.
const template = parseTemplate(
metadata.template !, `ng://${stringify(type)}/template.html`, {
preserveWhitespaces: metadata.preserveWhitespaces || false,
},
'');
if (template.errors !== undefined) {
const errors = template.errors.map(err => err.toString()).join(', ');
throw new Error(
`Errors during JIT compilation of template for ${stringify(type)}: ${errors}`);
}
const animations =
metadata.animations !== null ? new WrappedNodeExpr(metadata.animations) : null;
// Compile the component metadata, including template, into an expression.
// TODO(alxhub): implement inputs, outputs, queries, etc.
const res = compileR3Component(
{
...directiveMetadata(type, metadata),
template,
directives: new Map(),
pipes: new Map(),
viewQueries: [],
wrapDirectivesInClosure: false,
styles: metadata.styles || [],
encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated, animations,
},
constantPool, makeBindingParser());
const preStatements = [...constantPool.statements, ...res.statements];
ngComponentDef = jitExpression(
res.expression, angularCoreEnv, `ng://${type.name}/ngComponentDef.js`, preStatements);
const meta: R3ComponentMetadataFacade = {
...directiveMetadata(type, metadata),
template: metadata.template || '',
preserveWhitespaces: metadata.preserveWhitespaces || false,
styles: metadata.styles || EMPTY_ARRAY,
animations: metadata.animations,
viewQueries: extractQueriesMetadata(getReflect().propMetadata(type), isViewQuery),
directives: new Map(),
pipes: new Map(),
encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated,
viewProviders: metadata.viewProviders || null,
};
ngComponentDef = compiler.compileComponent(
angularCoreEnv, `ng://${stringify(type)}/template.html`, meta);
// If component compilation is async, then the @NgModule annotation which declares the
// component may execute and set an ngSelectorScope property on the component type. This
@ -120,12 +99,9 @@ export function compileDirective(type: Type<any>, directive: Directive): void {
Object.defineProperty(type, NG_DIRECTIVE_DEF, {
get: () => {
if (ngDirectiveDef === null) {
const constantPool = new ConstantPool();
const sourceMapUrl = `ng://${type && type.name}/ngDirectiveDef.js`;
const res = compileR3Directive(
directiveMetadata(type, directive), constantPool, makeBindingParser());
const preStatements = [...constantPool.statements, ...res.statements];
ngDirectiveDef = jitExpression(res.expression, angularCoreEnv, sourceMapUrl, preStatements);
const facade = directiveMetadata(type, directive);
ngDirectiveDef = getCompilerFacade().compileDirective(
angularCoreEnv, `ng://${type && type.name}/ngDirectiveDef.js`, facade);
}
return ngDirectiveDef;
},
@ -142,97 +118,72 @@ export function extendsDirectlyFromObject(type: Type<any>): boolean {
* Extract the `R3DirectiveMetadata` for a particular directive (either a `Directive` or a
* `Component`).
*/
function directiveMetadata(type: Type<any>, metadata: Directive): R3DirectiveMetadata {
function directiveMetadata(type: Type<any>, metadata: Directive): R3DirectiveMetadataFacade {
// Reflect inputs and outputs.
const propMetadata = getReflect().propMetadata(type);
const host = extractHostBindings(metadata, propMetadata);
const inputsFromMetadata = parseInputOutputs(metadata.inputs || []);
const outputsFromMetadata = parseInputOutputs(metadata.outputs || []);
const inputsFromType: StringMap = {};
const outputsFromType: StringMap = {};
for (const field in propMetadata) {
if (propMetadata.hasOwnProperty(field)) {
propMetadata[field].forEach(ann => {
if (isInput(ann)) {
inputsFromType[field] = ann.bindingPropertyName || field;
} else if (isOutput(ann)) {
outputsFromType[field] = ann.bindingPropertyName || field;
}
});
}
}
return {
name: type.name,
type: new WrappedNodeExpr(type),
type: type,
typeArgumentCount: 0,
selector: metadata.selector !,
deps: reflectDependencies(type), host,
inputs: {...inputsFromMetadata, ...inputsFromType},
outputs: {...outputsFromMetadata, ...outputsFromType},
queries: [],
deps: reflectDependencies(type),
host: metadata.host || EMPTY_OBJ,
propMetadata: propMetadata,
inputs: metadata.inputs || EMPTY_ARRAY,
outputs: metadata.outputs || EMPTY_ARRAY,
queries: extractQueriesMetadata(propMetadata, isContentQuery),
lifecycle: {
usesOnChanges: type.prototype.ngOnChanges !== undefined,
},
typeSourceSpan: null !,
usesInheritance: !extendsDirectlyFromObject(type),
exportAs: metadata.exportAs || null,
providers: metadata.providers || null,
};
}
function extractHostBindings(metadata: Directive, propMetadata: {[key: string]: any[]}): {
attributes: StringMap,
listeners: StringMap,
properties: StringMap,
} {
// First parse the declarations from the metadata.
const {attributes, listeners, properties, animations} = parseHostBindings(metadata.host || {});
const EMPTY_OBJ = {};
if (Object.keys(animations).length > 0) {
throw new Error(`Animation bindings are as-of-yet unsupported in Ivy`);
}
function convertToR3QueryPredicate(selector: any): any|string[] {
return typeof selector === 'string' ? splitByComma(selector) : selector;
}
// Next, loop over the properties of the object, looking for @HostBinding and @HostListener.
export function convertToR3QueryMetadata(propertyName: string, ann: Query): R3QueryMetadataFacade {
return {
propertyName: propertyName,
predicate: convertToR3QueryPredicate(ann.selector),
descendants: ann.descendants,
first: ann.first,
read: ann.read ? ann.read : null
};
}
function extractQueriesMetadata(
propMetadata: {[key: string]: any[]},
isQueryAnn: (ann: any) => ann is Query): R3QueryMetadataFacade[] {
const queriesMeta: R3QueryMetadataFacade[] = [];
for (const field in propMetadata) {
if (propMetadata.hasOwnProperty(field)) {
propMetadata[field].forEach(ann => {
if (isHostBinding(ann)) {
properties[ann.hostPropertyName || field] = field;
} else if (isHostListener(ann)) {
listeners[ann.eventName || field] = `${field}(${(ann.args || []).join(',')})`;
if (isQueryAnn(ann)) {
queriesMeta.push(convertToR3QueryMetadata(field, ann));
}
});
}
}
return {attributes, listeners, properties};
return queriesMeta;
}
function isInput(value: any): value is Input {
return value.ngMetadataName === 'Input';
function isContentQuery(value: any): value is Query {
const name = value.ngMetadataName;
return name === 'ContentChild' || name === 'ContentChildren';
}
function isOutput(value: any): value is Output {
return value.ngMetadataName === 'Output';
function isViewQuery(value: any): value is Query {
const name = value.ngMetadataName;
return name === 'ViewChild' || name === 'ViewChildren';
}
function isHostBinding(value: any): value is HostBinding {
return value.ngMetadataName === 'HostBinding';
}
function isHostListener(value: any): value is HostListener {
return value.ngMetadataName === 'HostListener';
}
function parseInputOutputs(values: string[]): StringMap {
return values.reduce(
(map, value) => {
const [field, property] = value.split(',').map(piece => piece.trim());
map[field] = property || field;
return map;
},
{} as StringMap);
function splitByComma(value: string): string[] {
return value.split(',').map(piece => piece.trim());
}

View File

@ -6,14 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Expression, LiteralExpr, R3DependencyMetadata, R3InjectableMetadata, WrappedNodeExpr, compileInjectable as compileR3Injectable, jitExpression} from '@angular/compiler';
import {Injectable} from '../../di/injectable';
import {ClassSansProvider, ExistingSansProvider, FactorySansProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from '../../di/provider';
import {ClassSansProvider, ExistingSansProvider, FactorySansProvider, ValueProvider, ValueSansProvider} from '../../di/provider';
import {Type} from '../../type';
import {getClosureSafeProperty} from '../../util/property';
import {NG_INJECTABLE_DEF} from '../fields';
import {R3InjectableMetadataFacade, getCompilerFacade} from './compiler_facade';
import {angularCoreEnv} from './environment';
import {convertDependencies, reflectDependencies} from './util';
@ -31,84 +30,60 @@ export function compileInjectable(type: Type<any>, srcMeta?: Injectable): void {
Object.defineProperty(type, NG_INJECTABLE_DEF, {
get: () => {
if (def === null) {
// Check whether the injectable metadata includes a provider specification.
const meta: Injectable = srcMeta || {providedIn: null};
const hasAProvider = isUseClassProvider(meta) || isUseFactoryProvider(meta) ||
isUseValueProvider(meta) || isUseExistingProvider(meta);
const ctorDeps = reflectDependencies(type);
let userDeps: R3DependencyMetadata[]|undefined = undefined;
const compilerMeta: R3InjectableMetadataFacade = {
name: type.name,
type: type,
providedIn: meta.providedIn,
ctorDeps: reflectDependencies(type),
userDeps: undefined
};
if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
userDeps = convertDependencies(meta.deps);
compilerMeta.userDeps = convertDependencies(meta.deps);
}
// Decide which flavor of factory to generate, based on the provider specified.
// Only one of the use* fields should be set.
let useClass: Expression|undefined = undefined;
let useFactory: Expression|undefined = undefined;
let useValue: Expression|undefined = undefined;
let useExisting: Expression|undefined = undefined;
if (!hasAProvider) {
// In the case the user specifies a type provider, treat it as {provide: X, useClass: X}.
// The deps will have been reflected above, causing the factory to create the class by
// calling
// its constructor with injected deps.
useClass = new WrappedNodeExpr(type);
compilerMeta.useClass = type;
} else if (isUseClassProvider(meta)) {
// The user explicitly specified useClass, and may or may not have provided deps.
useClass = new WrappedNodeExpr(meta.useClass);
compilerMeta.useClass = meta.useClass;
} else if (isUseValueProvider(meta)) {
// The user explicitly specified useValue.
useValue = new WrappedNodeExpr(meta.useValue);
compilerMeta.useValue = meta.useValue;
} else if (isUseFactoryProvider(meta)) {
// The user explicitly specified useFactory.
useFactory = new WrappedNodeExpr(meta.useFactory);
compilerMeta.useFactory = meta.useFactory;
} else if (isUseExistingProvider(meta)) {
// The user explicitly specified useExisting.
useExisting = new WrappedNodeExpr(meta.useExisting);
compilerMeta.useExisting = meta.useExisting;
} else {
// Can't happen - either hasAProvider will be false, or one of the providers will be set.
throw new Error(`Unreachable state.`);
}
const {expression, statements} = compileR3Injectable({
name: type.name,
type: new WrappedNodeExpr(type),
providedIn: computeProvidedIn(meta.providedIn),
useClass,
useFactory,
useValue,
useExisting,
ctorDeps,
userDeps,
});
def = jitExpression(
expression, angularCoreEnv, `ng://${type.name}/ngInjectableDef.js`, statements);
def = getCompilerFacade().compileInjectable(
angularCoreEnv, `ng://${type.name}/ngInjectableDef.js`, compilerMeta);
}
return def;
},
});
}
function computeProvidedIn(providedIn: Type<any>| string | null | undefined): Expression {
if (providedIn == null || typeof providedIn === 'string') {
return new LiteralExpr(providedIn);
} else {
return new WrappedNodeExpr(providedIn);
}
}
type UseClassProvider = Injectable & ClassSansProvider & {deps?: any[]};
const USE_VALUE =
getClosureSafeProperty<ValueProvider>({provide: String, useValue: getClosureSafeProperty});
function isUseClassProvider(meta: Injectable): meta is UseClassProvider {
return (meta as UseClassProvider).useClass !== undefined;
}
const USE_VALUE =
getClosureSafeProperty<ValueProvider>({provide: String, useValue: getClosureSafeProperty});
function isUseValueProvider(meta: Injectable): meta is Injectable&ValueSansProvider {
return USE_VALUE in meta;
}

View File

@ -6,14 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Expression, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, WrappedNodeExpr, compileInjector, compileNgModule as compileR3NgModule, jitExpression} from '@angular/compiler';
import {ModuleWithProviders, NgModule, NgModuleDef, NgModuleTransitiveScopes} from '../../metadata/ng_module';
import {Type} from '../../type';
import {getComponentDef, getDirectiveDef, getNgModuleDef, getPipeDef} from '../definition';
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_INJECTOR_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from '../fields';
import {ComponentDef} from '../interfaces/definition';
import {R3InjectorMetadataFacade, getCompilerFacade} from './compiler_facade';
import {angularCoreEnv} from './environment';
import {reflectDependencies} from './util';
@ -37,48 +36,39 @@ export function compileNgModuleDefs(moduleType: Type<any>, ngModule: NgModule):
let ngModuleDef: any = null;
Object.defineProperty(moduleType, NG_MODULE_DEF, {
configurable: true,
get: () => {
if (ngModuleDef === null) {
const meta: R3NgModuleMetadata = {
type: wrap(moduleType),
bootstrap: flatten(ngModule.bootstrap || EMPTY_ARRAY).map(wrapReference),
declarations: declarations.map(wrapReference),
imports: flatten(ngModule.imports || EMPTY_ARRAY)
.map(expandModuleWithProviders)
.map(wrapReference),
exports: flatten(ngModule.exports || EMPTY_ARRAY)
.map(expandModuleWithProviders)
.map(wrapReference),
emitInline: true,
};
const res = compileR3NgModule(meta);
ngModuleDef = jitExpression(
res.expression, angularCoreEnv, `ng://${moduleType.name}/ngModuleDef.js`, []);
ngModuleDef = getCompilerFacade().compileNgModule(
angularCoreEnv, `ng://${moduleType.name}/ngModuleDef.js`, {
type: moduleType,
bootstrap: flatten(ngModule.bootstrap || EMPTY_ARRAY),
declarations: declarations,
imports: flatten(ngModule.imports || EMPTY_ARRAY).map(expandModuleWithProviders),
exports: flatten(ngModule.exports || EMPTY_ARRAY).map(expandModuleWithProviders),
emitInline: true,
});
}
return ngModuleDef;
},
// Make the property configurable in dev mode to allow overriding in tests
configurable: !!ngDevMode,
}
});
let ngInjectorDef: any = null;
Object.defineProperty(moduleType, NG_INJECTOR_DEF, {
get: () => {
if (ngInjectorDef === null) {
const meta: R3InjectorMetadata = {
const meta: R3InjectorMetadataFacade = {
name: moduleType.name,
type: wrap(moduleType),
type: moduleType,
deps: reflectDependencies(moduleType),
providers: new WrappedNodeExpr(ngModule.providers || EMPTY_ARRAY),
imports: new WrappedNodeExpr([
providers: ngModule.providers || EMPTY_ARRAY,
imports: [
ngModule.imports || EMPTY_ARRAY,
ngModule.exports || EMPTY_ARRAY,
]),
],
};
const res = compileInjector(meta);
ngInjectorDef = jitExpression(
res.expression, angularCoreEnv, `ng://${moduleType.name}/ngInjectorDef.js`,
res.statements);
ngInjectorDef = getCompilerFacade().compileInjector(
angularCoreEnv, `ng://${moduleType.name}/ngInjectorDef.js`, meta);
}
return ngInjectorDef;
},
@ -235,15 +225,6 @@ function expandModuleWithProviders(value: Type<any>| ModuleWithProviders<{}>): T
return value;
}
function wrap(value: Type<any>): Expression {
return new WrappedNodeExpr(value);
}
function wrapReference(value: Type<any>): R3Reference {
const wrapped = wrap(value);
return {value: wrapped, type: wrapped};
}
function isModuleWithProviders(value: any): value is ModuleWithProviders<{}> {
return (value as{ngModule?: any}).ngModule !== undefined;
}

View File

@ -6,13 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/
import {WrappedNodeExpr, compilePipeFromMetadata, jitExpression} from '@angular/compiler';
import {Pipe} from '../../metadata/directives';
import {Type} from '../../type';
import {NG_PIPE_DEF} from '../fields';
import {stringify} from '../util';
import {getCompilerFacade} from './compiler_facade';
import {angularCoreEnv} from './environment';
import {reflectDependencies} from './util';
@ -21,18 +20,14 @@ export function compilePipe(type: Type<any>, meta: Pipe): void {
Object.defineProperty(type, NG_PIPE_DEF, {
get: () => {
if (ngPipeDef === null) {
const sourceMapUrl = `ng://${stringify(type)}/ngPipeDef.js`;
const name = type.name;
const res = compilePipeFromMetadata({
name,
type: new WrappedNodeExpr(type),
deps: reflectDependencies(type),
pipeName: meta.name,
pure: meta.pure !== undefined ? meta.pure : true,
});
ngPipeDef = jitExpression(res.expression, angularCoreEnv, sourceMapUrl, res.statements);
ngPipeDef = getCompilerFacade().compilePipe(
angularCoreEnv, `ng://${stringify(type)}/ngPipeDef.js`, {
type: type,
name: type.name,
deps: reflectDependencies(type),
pipeName: meta.name,
pure: meta.pure !== undefined ? meta.pure : true
});
}
return ngPipeDef;
},

View File

@ -6,48 +6,41 @@
* found in the LICENSE file at https://angular.io/license
*/
import {LiteralExpr, R3DependencyMetadata, R3ResolvedDependencyType, WrappedNodeExpr} from '@angular/compiler';
import {Injector} from '../../di/injector';
import {Host, Inject, Optional, Self, SkipSelf} from '../../di/metadata';
import {ElementRef} from '../../linker/element_ref';
import {TemplateRef} from '../../linker/template_ref';
import {ViewContainerRef} from '../../linker/view_container_ref';
import {Attribute} from '../../metadata/di';
import {ReflectionCapabilities} from '../../reflection/reflection_capabilities';
import {Type} from '../../type';
import {CompilerFacade, R3DependencyMetadataFacade, getCompilerFacade} from './compiler_facade';
let _reflect: ReflectionCapabilities|null = null;
export function getReflect(): ReflectionCapabilities {
return (_reflect = _reflect || new ReflectionCapabilities());
}
export function reflectDependencies(type: Type<any>): R3DependencyMetadata[] {
export function reflectDependencies(type: Type<any>): R3DependencyMetadataFacade[] {
return convertDependencies(getReflect().parameters(type));
}
export function convertDependencies(deps: any[]): R3DependencyMetadata[] {
return deps.map(dep => reflectDependency(dep));
export function convertDependencies(deps: any[]): R3DependencyMetadataFacade[] {
const compiler = getCompilerFacade();
return deps.map(dep => reflectDependency(compiler, dep));
}
function reflectDependency(dep: any | any[]): R3DependencyMetadata {
const meta: R3DependencyMetadata = {
token: new LiteralExpr(null),
function reflectDependency(compiler: CompilerFacade, dep: any | any[]): R3DependencyMetadataFacade {
const meta: R3DependencyMetadataFacade = {
token: null,
host: false,
optional: false,
resolved: R3ResolvedDependencyType.Token,
resolved: compiler.R3ResolvedDependencyType.Token,
self: false,
skipSelf: false,
};
function setTokenAndResolvedType(token: any): void {
if (token === Injector) {
meta.resolved = R3ResolvedDependencyType.Injector;
} else {
meta.resolved = R3ResolvedDependencyType.Token;
}
meta.token = new WrappedNodeExpr(token);
meta.resolved = compiler.R3ResolvedDependencyType.Token;
meta.token = token;
}
if (Array.isArray(dep)) {
@ -65,13 +58,13 @@ function reflectDependency(dep: any | any[]): R3DependencyMetadata {
} else if (param instanceof Host || param.__proto__.ngMetadataName === 'Host') {
meta.host = true;
} else if (param instanceof Inject) {
meta.token = new WrappedNodeExpr(param.token);
meta.token = param.token;
} else if (param instanceof Attribute) {
if (param.attributeName === undefined) {
throw new Error(`Attribute name must be defined.`);
}
meta.token = new LiteralExpr(param.attributeName);
meta.resolved = R3ResolvedDependencyType.Attribute;
meta.token = param.attributeName;
meta.resolved = compiler.R3ResolvedDependencyType.Attribute;
} else {
setTokenAndResolvedType(param);
}

View File

@ -7,7 +7,10 @@ load("//tools/http-server:http_server.bzl", "http_server")
ng_module(
name = "animation_world",
srcs = ["index.ts"],
tags = ["ivy-only"],
tags = [
"ivy-only",
"no-ivy-jit",
],
type_check = False, # see #26462
deps = [
"//packages/common",
@ -25,7 +28,10 @@ ng_rollup_bundle(
# has an "external" directory for external dependencies.
# This should probably start with "angular/" and let the rule deal with it.
entry_point = "packages/core/test/bundling/animation_world/index.js",
tags = ["ivy-only"],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
":animation_world",
"//packages/core",
@ -38,6 +44,7 @@ js_expected_symbol_test(
golden = ":bundle.golden_symbols.json",
tags = [
"ivy-only",
"no-ivy-jit",
],
)
@ -50,4 +57,8 @@ http_server(
":bundle.min.js",
":bundle.min_debug.js",
],
tags = [
"ivy-only",
"no-ivy-jit",
],
)

View File

@ -57,7 +57,7 @@
"name": "EMPTY_ARR"
},
{
"name": "EMPTY_ARRAY$1"
"name": "EMPTY_ARRAY"
},
{
"name": "EMPTY_OBJ"
@ -213,7 +213,7 @@
"name": "ViewContainerRef"
},
{
"name": "ViewEncapsulation$1"
"name": "ViewEncapsulation"
},
{
"name": "ViewRef"
@ -402,7 +402,7 @@
"name": "createNodeAtIndex"
},
{
"name": "createOutput$1"
"name": "createOutput"
},
{
"name": "createRootComponent"
@ -1032,10 +1032,10 @@
"name": "storeCleanupWithContext"
},
{
"name": "stringify$1"
"name": "stringify"
},
{
"name": "stringify$2"
"name": "stringify$1"
},
{
"name": "swapMultiContextEntries"

View File

@ -7,7 +7,10 @@ load("//tools/http-server:http_server.bzl", "http_server")
ng_module(
name = "hello_world",
srcs = ["index.ts"],
tags = ["ivy-only"],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
"//packages/core",
],
@ -22,7 +25,10 @@ ng_rollup_bundle(
# has an "external" directory for external dependencies.
# This should probably start with "angular/" and let the rule deal with it.
entry_point = "packages/core/test/bundling/hello_world/index.js",
tags = ["ivy-only"],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
":hello_world",
"//packages/core",
@ -33,8 +39,13 @@ ts_library(
name = "test_lib",
testonly = True,
srcs = glob(["*_spec.ts"]),
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
"//packages:types",
"//packages/compiler",
"//packages/core/testing",
"//packages/private/testing",
],
@ -50,6 +61,7 @@ jasmine_node_test(
],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [":test_lib"],
)
@ -60,6 +72,7 @@ js_expected_symbol_test(
golden = ":bundle.golden_symbols.json",
tags = [
"ivy-only",
"no-ivy-jit",
],
)
@ -70,4 +83,8 @@ http_server(
":bundle.min.js",
":bundle.min_debug.js",
],
tags = [
"ivy-only",
"no-ivy-jit",
],
)

View File

@ -27,7 +27,7 @@
"name": "EMPTY$1"
},
{
"name": "EMPTY_ARRAY$1"
"name": "EMPTY_ARRAY"
},
{
"name": "EmptyErrorImpl"
@ -114,7 +114,7 @@
"name": "VIEWS"
},
{
"name": "ViewEncapsulation$1"
"name": "ViewEncapsulation"
},
{
"name": "_getViewData"
@ -360,7 +360,7 @@
"name": "setUpBloom"
},
{
"name": "stringify$2"
"name": "stringify$1"
},
{
"name": "syncViewWithBlueprint"

View File

@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import '@angular/compiler';
import {withBody} from '@angular/private/testing';
import * as fs from 'fs';
import * as path from 'path';

View File

@ -6,6 +6,7 @@ load("//tools/http-server:http_server.bzl", "http_server")
ivy_ng_module(
name = "hello_world_i18n",
srcs = ["index.ts"],
tags = ["ivy-only"],
deps = [
"//packages/core",
],
@ -20,6 +21,7 @@ ng_rollup_bundle(
# has an "external" directory for external dependencies.
# This should probably start with "angular/" and let the rule deal with it.
entry_point = "packages/core/test/bundling/hello_world_i18n/index.js",
tags = ["ivy-only"],
deps = [
":hello_world_i18n",
"//packages/core",
@ -33,4 +35,5 @@ http_server(
":bundle.min.js",
":bundle.min_debug.js",
],
tags = ["ivy-only"],
)

View File

@ -7,6 +7,10 @@ load("//tools/http-server:http_server.bzl", "http_server")
ng_module(
name = "hello_world",
srcs = ["index.ts"],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
"//packages/core",
"//packages/platform-browser-dynamic",
@ -22,6 +26,10 @@ ng_rollup_bundle(
# has an "external" directory for external dependencies.
# This should probably start with "angular/" and let the rule deal with it.
entry_point = "packages/core/test/bundling/hello_world_r2/index.js",
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
":hello_world",
"//packages/core",
@ -33,8 +41,13 @@ ts_library(
name = "test_lib",
testonly = True,
srcs = glob(["*_spec.ts"]),
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
"//packages:types",
"//packages/compiler",
"//packages/core/testing",
"//packages/private/testing",
],
@ -48,6 +61,10 @@ jasmine_node_test(
":bundle.min.js.br",
":bundle.min_debug.js",
],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [":test_lib"],
)
@ -55,6 +72,10 @@ js_expected_symbol_test(
name = "symbol_test",
src = ":bundle.min_debug.js",
golden = ":bundle.golden_symbols.json",
tags = [
"ivy-only",
"no-ivy-jit",
],
)
http_server(
@ -64,4 +85,8 @@ http_server(
":bundle.min.js",
":bundle.min_debug.js",
],
tags = [
"ivy-only",
"no-ivy-jit",
],
)

View File

@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import '@angular/compiler';
import * as fs from 'fs';
import * as path from 'path';

View File

@ -9,6 +9,10 @@ ts_library(
"index.ts",
"usage.ts",
],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
"//packages/core",
],
@ -23,6 +27,10 @@ ng_rollup_bundle(
# has an "external" directory for external dependencies.
# This should probably start with "angular/" and let the rule deal with it.
entry_point = "packages/core/test/bundling/injection/index.js",
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
":injection",
"//packages/core",
@ -33,9 +41,14 @@ ts_library(
name = "test_lib",
testonly = True,
srcs = glob(["*_spec.ts"]),
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
":injection",
"//packages:types",
"//packages/compiler",
"//packages/core/testing",
"//packages/private/testing",
],
@ -43,6 +56,10 @@ ts_library(
jasmine_node_test(
name = "test",
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [":test_lib"],
)
@ -50,4 +67,8 @@ js_expected_symbol_test(
name = "symbol_test",
src = ":bundle.min_debug.js",
golden = ":bundle.golden_symbols.json",
tags = [
"ivy-only",
"no-ivy-jit",
],
)

View File

@ -6,7 +6,7 @@
"name": "CIRCULAR$2"
},
{
"name": "EMPTY_ARRAY$2"
"name": "EMPTY_ARRAY$1"
},
{
"name": "EmptyErrorImpl"

View File

@ -6,15 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
import * as fs from 'fs';
import * as path from 'path';
import '@angular/compiler';
import {INJECTOR, ScopedService} from './usage';
const UTF8 = {
encoding: 'utf-8'
};
const PACKAGE = 'angular/packages/core/test/bundling/hello_world';
describe('functional test for injection system bundling', () => {
it('should be able to inject the scoped service',

View File

@ -8,7 +8,10 @@ load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
ng_module(
name = "todo",
srcs = ["index.ts"],
tags = ["ivy-only"],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
"//packages/common",
"//packages/core",
@ -25,13 +28,15 @@ ng_rollup_bundle(
# has an "external" directory for external dependencies.
# This should probably start with "angular/" and let the rule deal with it.
entry_point = "packages/core/test/bundling/todo/index.js",
tags = ["ivy-only"],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
":todo",
"//packages/common",
"//packages/core",
"//packages/core/test/bundling/util:reflect_metadata",
"@ngdeps//reflect-metadata",
],
)
@ -39,8 +44,13 @@ ts_library(
name = "test_lib",
testonly = True,
srcs = glob(["*_spec.ts"]),
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
"//packages:types",
"//packages/compiler",
"//packages/core",
"//packages/core/testing",
"//packages/private/testing",
@ -57,6 +67,7 @@ jasmine_node_test(
],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [":test_lib"],
)
@ -67,6 +78,7 @@ js_expected_symbol_test(
golden = ":bundle.golden_symbols.json",
tags = [
"ivy-only",
"no-ivy-jit",
],
)
@ -79,6 +91,10 @@ genrule(
"tslib.js",
],
cmd = "cp $< $@",
tags = [
"ivy-only",
"no-ivy-jit",
],
)
ts_devserver(
@ -91,6 +107,10 @@ ts_devserver(
"todo.css",
"base.css",
],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [":todo"],
)
@ -103,4 +123,8 @@ http_server(
":bundle.min.js.br",
":bundle.min_debug.js",
],
tags = [
"ivy-only",
"no-ivy-jit",
],
)

View File

@ -48,7 +48,7 @@
"name": "EMPTY$1"
},
{
"name": "EMPTY_ARRAY$1"
"name": "EMPTY_ARRAY"
},
{
"name": "ElementRef"
@ -228,7 +228,7 @@
"name": "ViewContainerRef"
},
{
"name": "ViewEncapsulation$1"
"name": "ViewEncapsulation"
},
{
"name": "ViewRef"
@ -459,7 +459,7 @@
"name": "createNodeAtIndex"
},
{
"name": "createOutput$1"
"name": "createOutput"
},
{
"name": "createRootComponent"
@ -1050,10 +1050,10 @@
"name": "storeCleanupWithContext"
},
{
"name": "stringify$1"
"name": "stringify"
},
{
"name": "stringify$2"
"name": "stringify$1"
},
{
"name": "syncViewWithBlueprint"

View File

@ -6,9 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
import '@angular/compiler';
import {ɵwhenRendered as whenRendered} from '@angular/core';
import {withBody} from '@angular/private/testing';
import * as fs from 'fs';
import * as path from 'path';
const UTF8 = {

View File

@ -8,7 +8,10 @@ load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
ng_module(
name = "todo",
srcs = ["index.ts"],
tags = ["ivy-only"],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
"//packages/common",
"//packages/core",
@ -27,7 +30,10 @@ ng_rollup_bundle(
# has an "external" directory for external dependencies.
# This should probably start with "angular/" and let the rule deal with it.
entry_point = "packages/core/test/bundling/todo_r2/index.js",
tags = ["ivy-only"],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
":todo",
"//packages/common",
@ -35,7 +41,6 @@ ng_rollup_bundle(
"//packages/core/test/bundling/util:reflect_metadata",
"//packages/platform-browser",
"//packages/platform-browser-dynamic",
"@ngdeps//reflect-metadata",
],
)
@ -43,8 +48,13 @@ ts_library(
name = "test_lib",
testonly = True,
srcs = glob(["*_spec.ts"]),
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [
"//packages:types",
"//packages/compiler",
"//packages/core",
"//packages/core/testing",
"//packages/platform-browser",
@ -63,6 +73,7 @@ jasmine_node_test(
],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [":test_lib"],
)
@ -73,6 +84,7 @@ js_expected_symbol_test(
golden = ":bundle.golden_symbols.json",
tags = [
"ivy-only",
"no-ivy-jit",
],
)
@ -85,6 +97,10 @@ genrule(
"tslib.js",
],
cmd = "cp $< $@",
tags = [
"ivy-only",
"no-ivy-jit",
],
)
ts_devserver(
@ -97,6 +113,10 @@ ts_devserver(
"todo.css",
"base.css",
],
tags = [
"ivy-only",
"no-ivy-jit",
],
deps = [":todo"],
)
@ -109,4 +129,8 @@ http_server(
":bundle.min.js.br",
":bundle.min_debug.js",
],
tags = [
"ivy-only",
"no-ivy-jit",
],
)

View File

@ -102,13 +102,13 @@
"name": "COMPONENT_REGEX"
},
{
"name": "COMPONENT_VARIABLE$1"
"name": "COMPONENT_VARIABLE"
},
{
"name": "CONTAINER_INDEX"
},
{
"name": "CONTENT_ATTR$1"
"name": "CONTENT_ATTR"
},
{
"name": "CONTEXT"
@ -258,10 +258,10 @@
"name": "EMPTY$1"
},
{
"name": "EMPTY_ARRAY$1"
"name": "EMPTY_ARRAY"
},
{
"name": "EMPTY_ARRAY$2"
"name": "EMPTY_ARRAY$1"
},
{
"name": "EMPTY_PAYLOAD"
@ -333,7 +333,7 @@
"name": "HOST"
},
{
"name": "HOST_ATTR$1"
"name": "HOST_ATTR"
},
{
"name": "HOST_NODE"
@ -786,7 +786,7 @@
"name": "SanitizingHtmlSerializer"
},
{
"name": "SecurityContext$1"
"name": "SecurityContext"
},
{
"name": "Self"
@ -900,7 +900,7 @@
"name": "URL_RE"
},
{
"name": "USE_VALUE$1"
"name": "USE_VALUE"
},
{
"name": "UnsubscriptionError"
@ -924,13 +924,13 @@
"name": "VOID_ELEMENTS"
},
{
"name": "Version$1"
"name": "Version"
},
{
"name": "ViewContainerRef"
},
{
"name": "ViewEncapsulation$1"
"name": "ViewEncapsulation"
},
{
"name": "ViewRef"
@ -1341,7 +1341,7 @@
"name": "createNodeAtIndex"
},
{
"name": "createOutput$1"
"name": "createOutput"
},
{
"name": "createPlatform"
@ -2046,10 +2046,10 @@
"name": "isProceduralRenderer"
},
{
"name": "isPromise$1"
"name": "isPromise"
},
{
"name": "isPromise$2"
"name": "isPromise$1"
},
{
"name": "isScheduler"
@ -2187,7 +2187,7 @@
"name": "parseCookieValue"
},
{
"name": "parseIntAutoRadix$1"
"name": "parseIntAutoRadix"
},
{
"name": "parseNumber"
@ -2304,7 +2304,7 @@
"name": "resolveDirective"
},
{
"name": "resolveForwardRef$1"
"name": "resolveForwardRef"
},
{
"name": "resolveProvider"
@ -2433,10 +2433,10 @@
"name": "strToNumber"
},
{
"name": "stringify$1"
"name": "stringify"
},
{
"name": "stringify$2"
"name": "stringify$1"
},
{
"name": "subscribeTo"

View File

@ -6,9 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
import '@angular/compiler';
import {ɵwhenRendered as whenRendered} from '@angular/core';
import {withBody} from '@angular/private/testing';
import * as fs from 'fs';
import * as path from 'path';
const UTF8 = {

Some files were not shown because too many files have changed in this diff Show More