Compare commits
180 Commits
8.0.0-beta
...
g3
Author | SHA1 | Date | |
---|---|---|---|
c34c223122 | |||
26a8c5961e | |||
41225289d7 | |||
3612ddb433 | |||
09fab58109 | |||
b3102b9de1 | |||
cfe6581fc8 | |||
bef5043a5a | |||
b5295ad277 | |||
769d960db1 | |||
21be0fb926 | |||
9bcc1e8dce | |||
a06f0340d2 | |||
66b72bfa58 | |||
00075647be | |||
ce789b75a4 | |||
7baf45fe88 | |||
f3e0cc89ed | |||
cfa6e8e008 | |||
02debebcff | |||
ed8d60d060 | |||
9ea0d64d8b | |||
dfcf759e33 | |||
21835af70c | |||
2790352d04 | |||
bb6a3632f6 | |||
2d859a8c3a | |||
70fffba054 | |||
e185d3a4ad | |||
6f3052b799 | |||
c18fa7b5bd | |||
693b350567 | |||
0b27c09b51 | |||
861d6f1523 | |||
dc10355d61 | |||
6cd3743b44 | |||
a24f4b51b3 | |||
84baa0bb08 | |||
e721c08c7f | |||
37a154e4e6 | |||
415de9a291 | |||
b3dda0ebc1 | |||
41737bb4d3 | |||
afe3e72601 | |||
5e3bbf79a6 | |||
d2b64cc008 | |||
9eb8274991 | |||
17b3f11e07 | |||
10734ac607 | |||
68a9fe817c | |||
64e5628897 | |||
849b327986 | |||
a827bc2e3a | |||
083fb99033 | |||
55ea8da6eb | |||
7ea0d1bd3a | |||
bdcbd9ed4b | |||
b48d6e1b13 | |||
68f9d705f8 | |||
229f035969 | |||
c9f7cdaafd | |||
7b55ba58b9 | |||
cd449021c1 | |||
4bb0259bc0 | |||
66239b9d09 | |||
a770aa231d | |||
cf4718c366 | |||
07aeafa75c | |||
7a67f8935d | |||
bc88816c10 | |||
0d0445063a | |||
ddfdf3cd26 | |||
d6d081e120 | |||
38c778e371 | |||
3249020466 | |||
d6e27a41ed | |||
1a4d4a0e13 | |||
3121409957 | |||
fd122b0739 | |||
9a364a82fb | |||
a530ed11e8 | |||
2d7435daae | |||
b460b26308 | |||
ea90435a6b | |||
ea0e832e5f | |||
7c4afb0da7 | |||
603df13b14 | |||
f9b7b6d2f1 | |||
dafbbf8b64 | |||
d59f02d902 | |||
20bf4ca382 | |||
aae6f7b40b | |||
5f50562be5 | |||
efcd6af17d | |||
56c345baec | |||
19ff32036e | |||
37cc514f0f | |||
067657c1e9 | |||
8714daf276 | |||
d5e3f2c64b | |||
bc99b774ba | |||
a3ec058f6b | |||
4605df83e1 | |||
c0ad9e104d | |||
a9020a028f | |||
e769f9cfe4 | |||
4a665ca50b | |||
e9fab63385 | |||
5454227057 | |||
0244a2433e | |||
86aba1e8f3 | |||
ae4a86e3b5 | |||
ce4da3f8e5 | |||
e79f57a6b8 | |||
c439e14d39 | |||
a8d84660e5 | |||
4525619a73 | |||
4742385e95 | |||
d87b035ebb | |||
b759d63389 | |||
fe759ee0cf | |||
105cfaf5e4 | |||
2ab194c999 | |||
7b5d326d77 | |||
8e70ca39cc | |||
9d090cb3db | |||
3d5b98631a | |||
e8df000e97 | |||
604f37b679 | |||
4d912b6b12 | |||
bf2db12fc9 | |||
dfb220ea6b | |||
04b5ea089c | |||
7561698675 | |||
8ef690c342 | |||
3facdebd07 | |||
1db8bf312e | |||
f7738ad8d6 | |||
fc8048ddaf | |||
b2aadffbbc | |||
8ed13a37f0 | |||
1877e6c3f8 | |||
1a9ab2727e | |||
bf0704d685 | |||
1fb670e06c | |||
f50928f5b7 | |||
fe448e8222 | |||
7c297e05f3 | |||
487d4157ac | |||
90df7de54d | |||
8ef46f38f4 | |||
7b70760c8d | |||
6ab8c0b371 | |||
80379697e2 | |||
a5c747f46d | |||
410ccacf38 | |||
e76cf8c775 | |||
9be4ab51ea | |||
4990b935b4 | |||
08231f0bfa | |||
a3e105487d | |||
2064508876 | |||
0c59342cd0 | |||
018477e2c4 | |||
1f0eadfab6 | |||
f2dc32e5c7 | |||
019e65abfb | |||
0ffa2f2e73 | |||
a5a35ff54a | |||
7b20cec986 | |||
eb00a37eb8 | |||
75748d6044 | |||
9a7f5601fa | |||
955e4e704e | |||
73da2792c9 | |||
1625d86178 | |||
c4c34fe60e | |||
29fae6de08 | |||
ccb70e1c64 | |||
940fbf796c |
10
.bazelrc
@ -1,5 +1,3 @@
|
||||
# Load any settings specific to the current user
|
||||
try-import .bazelrc.user
|
||||
################################
|
||||
# Settings for Angular team members only
|
||||
################################
|
||||
@ -12,8 +10,10 @@ build:angular-team --remote_http_cache=https://storage.googleapis.com/angular-te
|
||||
|
||||
# Make compilation fast, by keeping a few copies of the compilers
|
||||
# running as daemons, and cache SourceFile AST's to reduce parse time.
|
||||
build --strategy=TypeScriptCompile=worker
|
||||
build --strategy=AngularTemplateCompile=worker
|
||||
# TODO(alexeagle): re-enable after fixing worker instability with rxjs typings
|
||||
# build --strategy=TypeScriptCompile=worker
|
||||
build --strategy=TypeScriptCompile=standalone
|
||||
|
||||
# Enable debugging tests with --config=debug
|
||||
test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test_strategy=exclusive --test_timeout=9999 --nocache_test_results
|
||||
@ -135,3 +135,7 @@ build:remote --remote_instance_name=projects/internal-200822/instances/default_i
|
||||
# Do not accept remote cache.
|
||||
# We need to understand the security risks of using prior build artifacts.
|
||||
build:remote --remote_accept_cached=false
|
||||
|
||||
# Load any settings specific to the current user. Needs to be last statement in this
|
||||
# config, as the user configuration should be able to overwrite flags from this file.
|
||||
try-import .bazelrc.user
|
||||
|
@ -463,6 +463,7 @@ jobs:
|
||||
steps:
|
||||
- *attach_workspace
|
||||
- *init_environment
|
||||
- run: uname -r
|
||||
# Runs the integration tests in parallel across multiple CircleCI container instances. The
|
||||
# amount of container nodes for this job is controlled by the "parallelism" option.
|
||||
- run: ./integration/run_tests.sh ${CIRCLE_NODE_INDEX} ${CIRCLE_NODE_TOTAL}
|
||||
@ -559,10 +560,43 @@ jobs:
|
||||
resource_class: xlarge
|
||||
docker:
|
||||
- image: *browsers_docker_image
|
||||
# The Material unit tests support splitting the browsers across multiple CircleCI
|
||||
# instances. Since by default this job launches two browsers, we run each browser
|
||||
# in its own container instance.
|
||||
# https://github.com/angular/material2/blob/7baeaa797b19da2d2998f0d26f6fede3c8a13714/test/karma.conf.js#L107-L110
|
||||
parallelism: 2
|
||||
environment:
|
||||
# The Material unit tests also support launching the same browser multiple times by
|
||||
# sharding individual specs across the defined multiple instances.
|
||||
# See: https://github.com/angular/material2/blob/7baeaa797b19da2d2998f0d26f6fede3c8a13714/test/karma.conf.js#L113-L116
|
||||
KARMA_PARALLEL_BROWSERS: 3
|
||||
steps:
|
||||
- *attach_workspace
|
||||
- *init_environment
|
||||
- run: ./scripts/ci/run_angular_material_unit_tests.sh
|
||||
- run:
|
||||
name: "Cloning Material repository"
|
||||
command: ./scripts/ci/clone_angular_material_repo.sh
|
||||
- restore_cache:
|
||||
# Material directory must be kept in sync with the `$MATERIAL_REPO_TMP_DIR` env variable.
|
||||
# It needs to be hardcoded here, because env variables interpolation is not supported.
|
||||
keys:
|
||||
- v2-angular-material-{{ checksum "/tmp/material2/yarn.lock" }}
|
||||
- v2-angular-material-
|
||||
- run:
|
||||
name: Installing Material dependencies.
|
||||
command: yarn --cwd ${MATERIAL_REPO_TMP_DIR} install --frozen-lockfile --non-interactive
|
||||
# Save the cache before we run the Material unit tests script. This is necessary
|
||||
# because we don't want to cache the node modules which have been modified to contain
|
||||
# the attached Ivy package output.
|
||||
- save_cache:
|
||||
# Material directory must be kept in sync with the `$MATERIAL_REPO_TMP_DIR` env variable.
|
||||
# It needs to be hardcoded here, because env variables interpolation is not supported.
|
||||
key: v2-angular-material-{{ checksum "/tmp/material2/yarn.lock" }}
|
||||
paths:
|
||||
- "/tmp/material2/node_modules"
|
||||
- run:
|
||||
name: "Running Material unit tests"
|
||||
command: ./scripts/ci/run_angular_material_unit_tests.sh
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
|
@ -62,6 +62,15 @@ setPublicVar SAUCE_TUNNEL_IDENTIFIER "angular-${CIRCLE_BUILD_NUM}-${CIRCLE_NODE_
|
||||
# acquire CircleCI instances for too long if sauceconnect failed, we need a connect timeout.
|
||||
setPublicVar SAUCE_READY_FILE_TIMEOUT 120
|
||||
|
||||
####################################################################################################
|
||||
# Define environment variables for the Angular Material unit tests job.
|
||||
####################################################################################################
|
||||
# We specifically use a directory within "/tmp" here because we want the cloned repo to be
|
||||
# completely isolated from angular/angular in order to avoid any bad interactions between
|
||||
# their separate build setups.
|
||||
setPublicVar MATERIAL_REPO_TMP_DIR "/tmp/material2"
|
||||
setPublicVar MATERIAL_REPO_URL "https://github.com/angular/material2.git"
|
||||
setPublicVar MATERIAL_REPO_BRANCH "ivy-2019"
|
||||
|
||||
# Source `$BASH_ENV` to make the variables available immediately.
|
||||
source $BASH_ENV;
|
||||
|
103
.codefresh/Dockerfile.win-1809
Normal file
@ -0,0 +1,103 @@
|
||||
ARG core=mcr.microsoft.com/windows/servercore:1809
|
||||
ARG target=mcr.microsoft.com/powershell:windowsservercore-1809
|
||||
|
||||
FROM $core as download
|
||||
|
||||
ARG node_version=10.13.0
|
||||
ARG yarn_version=1.13.0
|
||||
|
||||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
|
||||
|
||||
ENV GPG_VERSION 2.3.4
|
||||
|
||||
RUN Invoke-WebRequest $('https://files.gpg4win.org/gpg4win-vanilla-{0}.exe' -f $env:GPG_VERSION) -OutFile 'gpg4win.exe' -UseBasicParsing ; \
|
||||
Start-Process .\gpg4win.exe -ArgumentList '/S' -NoNewWindow -Wait
|
||||
|
||||
RUN @( \
|
||||
'94AE36675C464D64BAFA68DD7434390BDBE9B9C5', \
|
||||
'FD3A5288F042B6850C66B31F09FE44734EB7990E', \
|
||||
'71DCFD284A79C3B38668286BC97EC7A07EDE3FC1', \
|
||||
'DD8F2338BAE7501E3DD5AC78C273792F7D83545D', \
|
||||
'C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8', \
|
||||
'B9AE9905FFD7803F25714661B63B535A4C206CA9', \
|
||||
'77984A986EBC2AA786BC0F66B01FBB92821C587A', \
|
||||
'8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600', \
|
||||
'4ED778F539E3634C779C87C6D7062848A1AB005C', \
|
||||
'A48C2BEE680E841632CD4E44F07496B3EB3C1762', \
|
||||
'B9E2F5981AA6E0CD28160D9FF13993A75599653C' \
|
||||
) | foreach { \
|
||||
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys $_ ; \
|
||||
}
|
||||
|
||||
ENV NODE_VERSION=$node_version
|
||||
|
||||
RUN Invoke-WebRequest $('https://nodejs.org/dist/v{0}/SHASUMS256.txt.asc' -f $env:NODE_VERSION) -OutFile 'SHASUMS256.txt.asc' -UseBasicParsing ; \
|
||||
gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc
|
||||
|
||||
RUN Invoke-WebRequest $('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION) -OutFile 'node.zip' -UseBasicParsing ; \
|
||||
$sum = $(cat SHASUMS256.txt.asc | sls $(' node-v{0}-win-x64.zip' -f $env:NODE_VERSION)) -Split ' ' ; \
|
||||
if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $sum[0]) { Write-Error 'SHA256 mismatch' } ; \
|
||||
Expand-Archive node.zip -DestinationPath C:\ ; \
|
||||
Rename-Item -Path $('C:\node-v{0}-win-x64' -f $env:NODE_VERSION) -NewName 'C:\nodejs'
|
||||
|
||||
ENV YARN_VERSION=$yarn_version
|
||||
|
||||
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; \
|
||||
Invoke-WebRequest $('https://yarnpkg.com/downloads/{0}/yarn-{0}.msi' -f $env:YARN_VERSION) -OutFile yarn.msi -UseBasicParsing ; \
|
||||
$sig = Get-AuthenticodeSignature yarn.msi ; \
|
||||
if ($sig.Status -ne 'Valid') { Write-Error 'Authenticode signature is not valid' } ; \
|
||||
Write-Output $sig.SignerCertificate.Thumbprint ; \
|
||||
if (@( \
|
||||
'7E253367F8A102A91D04829E37F3410F14B68A5F', \
|
||||
'AF764E1EA56C762617BDC757C8B0F3780A0CF5F9' \
|
||||
) -notcontains $sig.SignerCertificate.Thumbprint) { Write-Error 'Unknown signer certificate' } ; \
|
||||
Start-Process msiexec.exe -ArgumentList '/i', 'yarn.msi', '/quiet', '/norestart' -NoNewWindow -Wait
|
||||
|
||||
ENV GIT_VERSION 2.20.1
|
||||
ENV GIT_DOWNLOAD_URL https://github.com/git-for-windows/git/releases/download/v${GIT_VERSION}.windows.1/MinGit-${GIT_VERSION}-busybox-64-bit.zip
|
||||
ENV GIT_SHA256 9817ab455d9cbd0b09d8664b4afbe4bbf78d18b556b3541d09238501a749486c
|
||||
|
||||
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; \
|
||||
Invoke-WebRequest -UseBasicParsing $env:GIT_DOWNLOAD_URL -OutFile git.zip; \
|
||||
if ((Get-FileHash git.zip -Algorithm sha256).Hash -ne $env:GIT_SHA256) {exit 1} ; \
|
||||
Expand-Archive git.zip -DestinationPath C:\git; \
|
||||
Remove-Item git.zip
|
||||
|
||||
FROM $target as baseimage
|
||||
|
||||
ENV NPM_CONFIG_LOGLEVEL info
|
||||
|
||||
COPY --from=download /nodejs /nodejs
|
||||
COPY --from=download [ "/Program Files (x86)/yarn", "/yarn" ]
|
||||
COPY --from=download /git /git
|
||||
|
||||
ARG SETX=/M
|
||||
RUN setx %SETX% PATH "%PATH%;C:\nodejs;C:\yarn\bin;C:\git\cmd;C:\git\mingw64\bin;C:\git\usr\bin"
|
||||
|
||||
CMD [ "node.exe" ]
|
||||
|
||||
FROM baseimage
|
||||
|
||||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
|
||||
|
||||
RUN Invoke-WebRequest -UseBasicParsing 'https://www.7-zip.org/a/7z1805-x64.exe' -OutFile 7z.exe; \
|
||||
Start-Process -FilePath 'C:\\7z.exe' -ArgumentList '/S', '/D=C:\\7zip0' -NoNewWindow -Wait; \
|
||||
Invoke-WebRequest -UseBasicParsing 'http://repo.msys2.org/distrib/x86_64/msys2-base-x86_64-20180531.tar.xz' -OutFile msys2.tar.xz; \
|
||||
Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'e', 'msys2.tar.xz' -Wait; \
|
||||
Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'x', 'msys2.tar', '-oC:\\' -Wait; \
|
||||
Remove-Item msys2.tar.xz; \
|
||||
Remove-Item msys2.tar; \
|
||||
Remove-Item 7z.exe; \
|
||||
Remove-Item -Recurse 7zip; \
|
||||
[Environment]::SetEnvironmentVariable('Path', $env:Path + ';C:\msys64\usr\bin', [System.EnvironmentVariableTarget]::Machine); \
|
||||
[Environment]::SetEnvironmentVariable('BAZEL_SH', 'C:\msys64\usr\bin\bash.exe', [System.EnvironmentVariableTarget]::Machine); \
|
||||
Invoke-WebRequest -UseBasicParsing 'https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe' -OutFile vc_redist.x64.exe; \
|
||||
Start-Process 'c:\\vc_redist.x64.exe' -ArgumentList '/Install', '/Passive', '/NoRestart' -NoNewWindow -Wait; \
|
||||
Remove-Item vc_redist.x64.exe
|
||||
|
||||
# Add a fix for https://github.com/docker/for-win/issues/2920 as entry point to the container.
|
||||
SHELL ["cmd", "/c"]
|
||||
COPY "fix-msys64.cmd" "C:\\fix-msys64.cmd"
|
||||
ENTRYPOINT cmd /C C:\\fix-msys64.cmd && cmd /c
|
||||
|
||||
CMD ["cmd.exe"]
|
33
.codefresh/README.md
Normal file
@ -0,0 +1,33 @@
|
||||
# CodeFresh configuration
|
||||
|
||||
[](https://g.codefresh.io/public/accounts/angular/pipelines/angular/angular/angular)
|
||||
|
||||
This folder contains configuration for the [CodeFresh](<https://codefresh.io/>) based CI checks for this repository.
|
||||
|
||||
## The build pipeline
|
||||
|
||||
CodeFresh uses a several pipeline for each repository. The `codefresh.yml` file defines pipeline [build steps](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/introduction-to-codefresh-pipelines/) for this repository.
|
||||
|
||||
Run results can be seen in the GitHub checks interface and in the [public pipeline](https://g.codefresh.io/public/accounts/angular/pipelines/angular/angular/angular)
|
||||
|
||||
Although most configuration is done via `pipeline.yml`, some options are only available in the online [pipeline settings](https://g.codefresh.io/pipelines/angular/services?repoOwner=angular&repoName=angular&project=angular%2Fangular&context=github&serviceName=angular%2Fangular), which needs a login to access.
|
||||
|
||||
|
||||
## Caretaker
|
||||
|
||||
CodeFresh status can be found at <http://status.codefresh.io/>.
|
||||
|
||||
Issues related to the CodeFresh setup should be escalated to the Tools Team via the current caretaker, followed by Alex Eagle and Filipe Silva.
|
||||
|
||||
## Rollout strategy
|
||||
|
||||
Currently it is only used for tests on Windows platforms, on the master branch, and without pushing user-facing reports. It's only possible to see current builds in the [public pipeline dashboard](https://g.codefresh.io/public/accounts/angular/pipelines/angular/angular/angular).
|
||||
|
||||
After a week or two of running like this, we should reassess how stable and reliable it is.
|
||||
|
||||
Next steps include:
|
||||
- building PRs
|
||||
- showing build status publicly
|
||||
- blocking PRs that break the build
|
||||
- expanding the test suite
|
||||
|
40
.codefresh/bazel.rc
Normal file
@ -0,0 +1,40 @@
|
||||
# These options are enabled when running on CI
|
||||
# We do this by copying this file to /etc/bazel.bazelrc at the start of the build.
|
||||
# See documentation in /docs/BAZEL.md
|
||||
|
||||
# Save downloaded repositories in a location that can be cached by CodeFresh. This helps us
|
||||
# speeding up the analysis time significantly with Bazel managed node dependencies on the CI.
|
||||
# build --repository_cache=C:/codefresh/volume/bazel_repository_cache
|
||||
|
||||
# Don't be spammy in the logs
|
||||
# TODO(gmagolan): Hide progress again once build performance improves
|
||||
# Presently, CircleCI can timeout during bazel test ... with the following
|
||||
# error: Too long with no output (exceeded 10m0s)
|
||||
# build --noshow_progress
|
||||
|
||||
# Print all the options that apply to the build.
|
||||
# This helps us diagnose which options override others
|
||||
# (e.g. /etc/bazel.bazelrc vs. tools/bazel.rc)
|
||||
build --announce_rc
|
||||
|
||||
# Workaround https://github.com/bazelbuild/bazel/issues/3645
|
||||
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
|
||||
# Limit Bazel to consuming resources that fit in CodeFresh VMs
|
||||
# TODO(filipesilva): determine the correct memory limit
|
||||
build --local_resources=8000,8.0,1.0
|
||||
|
||||
# Retry in the event of flakes, eg. https://circleci.com/gh/angular/angular/31309
|
||||
test --flaky_test_attempts=2
|
||||
|
||||
# More details on failures
|
||||
build --verbose_failures=true
|
||||
|
||||
# Include PATH in Windows build/tests
|
||||
# https://github.com/bazelbuild/rules_typescript/pull/356
|
||||
build --action_env=PATH
|
||||
test --action_env=PATH --test_env=PATH
|
||||
|
||||
# Exclude tests known to not work on Windows.
|
||||
|
||||
# Chrome web tests are currently broken.
|
||||
test --test_tag_filters=-browser:chromium-local
|
26
.codefresh/codefresh.yml
Normal file
@ -0,0 +1,26 @@
|
||||
version: '1.0'
|
||||
|
||||
steps:
|
||||
BuildImage:
|
||||
type: build
|
||||
image_name: node-bazel-windows
|
||||
working_directory: ./.codefresh
|
||||
no_cf_cache: true
|
||||
build_arguments:
|
||||
- node_version=10.13.0
|
||||
- yarn_version=1.13.0
|
||||
dockerfile: ./Dockerfile.win-1809
|
||||
|
||||
RunTests:
|
||||
title: Run Example
|
||||
image: ${{BuildImage}}
|
||||
commands:
|
||||
# Install dependencies
|
||||
- yarn install --frozen-lockfile --non-interactive --network-timeout 100000 --no-progress
|
||||
# Create symlinks needed for Windows.
|
||||
- scripts\windows\create-symlinks.cmd
|
||||
# Add Bazel CI config
|
||||
- copy .codefresh\bazel.rc %ProgramData%\bazel.bazelrc
|
||||
# Run tests
|
||||
- yarn bazel test //tools/ts-api-guardian:all
|
||||
- yarn test-ivy-aot //packages/animations/test //packages/common/test //packages/forms/test //packages/http/test //packages/platform-browser/test //packages/platform-browser-dynamic/test //packages/router/test
|
6
.codefresh/fix-msys64.cmd
Normal file
@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
REM Fix for https://github.com/docker/for-win/issues/2920
|
||||
REM echo "Fixing msys64 folder..."
|
||||
REM Touch all .dll files inside C:\msys64\
|
||||
forfiles /p C:\msys64\ /s /m *.dll /c "cmd /c Copy /B @path+,, >NUL"
|
||||
REM echo "Fixed msys64 folder."
|
5
.github/CODEOWNERS
vendored
@ -46,6 +46,7 @@
|
||||
# andrewseguin - Andrew Seguin
|
||||
# benlesh - Ben Lesh
|
||||
# brandonroberts - Brandon Roberts
|
||||
# devversion - Paul Gschwendtner
|
||||
# filipesilva - Filipe Silva
|
||||
# gkalpak - George Kalpakas
|
||||
# hansl - Hans Larsen
|
||||
@ -87,6 +88,7 @@
|
||||
# - IgorMinar
|
||||
# - kara
|
||||
# - mhevery
|
||||
# - alexeagle
|
||||
|
||||
|
||||
# ===========================================================
|
||||
@ -325,6 +327,7 @@
|
||||
# ===========================================================
|
||||
#
|
||||
# - alexeagle
|
||||
# - devversion
|
||||
# - filipesilva
|
||||
# - gkalpak
|
||||
# - IgorMinar
|
||||
@ -818,7 +821,9 @@ testing/** @angular/fw-test
|
||||
/* @angular/fw-dev-infra
|
||||
/.buildkite/** @angular/fw-dev-infra
|
||||
/.circleci/** @angular/fw-dev-infra
|
||||
/.codefresh/** @angular/fw-dev-infra
|
||||
/.github/** @angular/fw-dev-infra
|
||||
/.vscode/** @angular/fw-dev-infra
|
||||
/docs/BAZEL.md @angular/fw-dev-infra
|
||||
/packages/* @angular/fw-dev-infra
|
||||
/scripts/** @angular/fw-dev-infra
|
||||
|
1
.vscode/extensions.json
vendored
@ -4,6 +4,7 @@
|
||||
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": [
|
||||
"devondcarew.bazel-code",
|
||||
"gkalpak.aio-docs-utils",
|
||||
"ms-vscode.vscode-typescript-tslint-plugin",
|
||||
"xaver.clang-format",
|
||||
|
2
.vscode/settings.json
vendored
@ -14,12 +14,14 @@
|
||||
"**/node_modules/**": true,
|
||||
"**/bazel-out/**": true,
|
||||
"**/dist/**": true,
|
||||
"**/aio/src/generated/**": true,
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/bower_components": true,
|
||||
"**/bazel-out": true,
|
||||
"**/dist": true,
|
||||
"**/aio/src/generated": true,
|
||||
},
|
||||
"git.ignoreLimitWarning": true,
|
||||
}
|
||||
|
60
CHANGELOG.md
@ -1,3 +1,63 @@
|
||||
<a name="8.0.0-beta.9"></a>
|
||||
# [8.0.0-beta.9](https://github.com/angular/angular/compare/8.0.0-beta.8...8.0.0-beta.9) (2019-03-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** correct regexp test for self-references in metadata ([#29346](https://github.com/angular/angular/issues/29346)) ([9d090cb](https://github.com/angular/angular/commit/9d090cb))
|
||||
* **bazel:** don't produce self-references in metadata ([#29317](https://github.com/angular/angular/issues/29317)) ([3facdeb](https://github.com/angular/angular/commit/3facdeb)), closes [#29315](https://github.com/angular/angular/issues/29315)
|
||||
* **bazel:** fix strict null checks compile error in packages/bazel/src/schematics/ng-add/index.ts ([#29282](https://github.com/angular/angular/issues/29282)) ([9a7f560](https://github.com/angular/angular/commit/9a7f560))
|
||||
* **bazel:** Remove [@angular](https://github.com/angular)/upgrade from dev dependencies ([#29319](https://github.com/angular/angular/issues/29319)) ([1db8bf3](https://github.com/angular/angular/commit/1db8bf3))
|
||||
* **bazel:** Support new e2e project layout ([#29318](https://github.com/angular/angular/issues/29318)) ([8ef690c](https://github.com/angular/angular/commit/8ef690c))
|
||||
* **bazel:** turn off pure call tree shaking for ng_package ([#29210](https://github.com/angular/angular/issues/29210)) ([4990b93](https://github.com/angular/angular/commit/4990b93))
|
||||
* **compiler-cli:** incorrect metadata bundle for multiple unnamed re-exports ([#29360](https://github.com/angular/angular/issues/29360)) ([105cfaf](https://github.com/angular/angular/commit/105cfaf)), closes [/github.com/angular/material2/blob/master/tools/package-tools/build-release.ts#L78-L85](https://github.com//github.com/angular/material2/blob/master/tools/package-tools/build-release.ts/issues/L78-L85)
|
||||
* **core:** don't wrap `<tr>` and `<col>` elements into a required parent ([#29219](https://github.com/angular/angular/issues/29219)) ([f2dc32e](https://github.com/angular/angular/commit/f2dc32e))
|
||||
* **core:** parse incorrect ML open tag as text ([#29328](https://github.com/angular/angular/issues/29328)) ([4605df8](https://github.com/angular/angular/commit/4605df8)), closes [#29231](https://github.com/angular/angular/issues/29231)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add support for TypeScript 3.3 (and drop older versions) ([#29004](https://github.com/angular/angular/issues/29004)) ([75748d6](https://github.com/angular/angular/commit/75748d6))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **core:** Certain elements (like `<tr>` or `<col>`) require parent elements to be of a certain type by the HTML specification
|
||||
(ex. `<tr>` can only be inside `<tbody>` / `<thead>`). Before this change Angular template parser was auto-correcting
|
||||
"invalid" HTML using the following rules:
|
||||
- `<tr>` would be wrapped in `<tbody>` if not inside `<tbody>`, `<tfoot>` or `<thead>`;
|
||||
- `<col>` would be wrapped in `<colgroup>` if not inside `<colgroup>`.
|
||||
|
||||
This meachanism of automatic wrapping / auto-correcting was problematic for several reasons:
|
||||
- it is non-obvious and arbitrary (ex. there are more HTML elements that has rules for parent type);
|
||||
- it is incorrect for cases where `<tr>` / `<col>` are at the root of a component's content, ex.:
|
||||
|
||||
```html
|
||||
<projecting-tr-inside-tbody>
|
||||
<tr>...</tr>
|
||||
</projecting-tr-inside-tbody>
|
||||
```
|
||||
|
||||
In the above example the `<projecting-tr-inside-tbody>` component could be "surprised" to see additional
|
||||
`<tbody>` elements inserted by Angular HTML parser.
|
||||
|
||||
|
||||
* TypeScript 3.1 and 3.2 are no longer supported.
|
||||
|
||||
Please update your TypeScript version to 3.3
|
||||
|
||||
|
||||
|
||||
<a name="7.2.10"></a>
|
||||
## [7.2.10](https://github.com/angular/angular/compare/7.2.9...7.2.10) (2019-03-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler-cli:** incorrect metadata bundle for multiple unnamed re-exports ([#29360](https://github.com/angular/angular/issues/29360)) ([cf8d934](https://github.com/angular/angular/commit/cf8d934)), closes [/github.com/angular/material2/blob/master/tools/package-tools/build-release.ts#L78-L85](https://github.com//github.com/angular/material2/blob/master/tools/package-tools/build-release.ts/issues/L78-L85)
|
||||
|
||||
|
||||
|
||||
<a name="8.0.0-beta.8"></a>
|
||||
# [8.0.0-beta.8](https://github.com/angular/angular/compare/8.0.0-beta.7...8.0.0-beta.8) (2019-03-12)
|
||||
|
||||
|
15
WORKSPACE
@ -15,13 +15,12 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
# Fetch rules_nodejs so we can install our npm dependencies
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
sha256 = "5c86b055c57e15bf32d9009a15bcd6d8e190c41b1ff2fb18037b75e0012e4e7c",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.26.0/rules_nodejs-0.26.0.tar.gz"],
|
||||
sha256 = "fb87ed5965cef93188af9a7287511639403f4b0da418961ce6defb9dcf658f51",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.27.7/rules_nodejs-0.27.7.tar.gz"],
|
||||
)
|
||||
|
||||
# Check the bazel version and download npm dependencies
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
|
||||
load("@build_bazel_rules_nodejs//:package.bzl", "check_rules_nodejs_version")
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "check_rules_nodejs_version", "node_repositories", "yarn_install")
|
||||
|
||||
# Bazel version must be at least v0.21.0 because:
|
||||
# - 0.21.0 Using --incompatible_strict_action_env flag fixes cache when running `yarn bazel`
|
||||
@ -49,6 +48,14 @@ node_repositories(
|
||||
node_version = "10.9.0",
|
||||
package_json = ["//:package.json"],
|
||||
preserve_symlinks = True,
|
||||
# yarn 1.13.0 under Bazel has a regression on Windows that causes build errors on rebuilds:
|
||||
# ```
|
||||
# ERROR: Source forest creation failed: C:/.../fyuc5c3n/execroot/angular/external (Directory not empty)
|
||||
# ```
|
||||
# See https://github.com/angular/angular/pull/29431 for more information.
|
||||
# It possible that versions of yarn past 1.13.0 do not have this issue, however, before
|
||||
# advancing this version we need to test manually on Windows that the above error does not
|
||||
# happen as the issue is not caught by CI.
|
||||
yarn_version = "1.12.1",
|
||||
)
|
||||
|
||||
|
@ -26,8 +26,8 @@ ARG AIO_GITHUB_ORGANIZATION=angular
|
||||
ARG TEST_AIO_GITHUB_ORGANIZATION=test-org
|
||||
ARG AIO_GITHUB_REPO=angular
|
||||
ARG TEST_AIO_GITHUB_REPO=test-repo
|
||||
ARG AIO_GITHUB_TEAM_SLUGS=aio-contributors
|
||||
ARG TEST_AIO_GITHUB_TEAM_SLUGS=aio-contributors
|
||||
ARG AIO_GITHUB_TEAM_SLUGS=aio-auto-previews,aio-contributors
|
||||
ARG TEST_AIO_GITHUB_TEAM_SLUGS=test-team-1,test-team-2
|
||||
ARG AIO_NGINX_HOSTNAME=$AIO_DOMAIN_NAME
|
||||
ARG TEST_AIO_NGINX_HOSTNAME=$TEST_AIO_DOMAIN_NAME
|
||||
ARG AIO_NGINX_PORT_HTTP=80
|
||||
|
38
aio/content/cli/usage-analytics-gathering.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Gathering Usage Analytics
|
||||
Administrators can configure their instances of Angular CLI to share usage analytics with
|
||||
third parties. This sharing is separate from and in addition to usage analytics shared
|
||||
with Google. It is disabled by default and cannot be enabled at the project level for
|
||||
all users. It must be set at the global configuration level for each user to allow
|
||||
managed users to opt in and share usage analytics.
|
||||
|
||||
To configure usage analytics sharing, use the `ng config` command to add both the user ID
|
||||
and the third-party ID to the user's global Angular CLI configuration.
|
||||
|
||||
- The third-party ID is the tracking identifier of the third-party Google Analytics
|
||||
account. This ID is a string that looks like `UA-123456-12`.
|
||||
- You can choose a user ID, or be assigned a random user ID when you run the CLI command.
|
||||
|
||||
Once you have the third-party tracking ID, add it to your global configuration using the following command:
|
||||
|
||||
```
|
||||
ng config --global cli.analyticsSharing.tracking UA-123456-12
|
||||
```
|
||||
|
||||
To add a custom user ID to the global configuration using the following command. This
|
||||
should be unique per users to identify unique usage of commands and flags.
|
||||
|
||||
```
|
||||
ng config --global cli.analyticsSharing.user SOME_USER_NAME
|
||||
```
|
||||
|
||||
To generate a new random user ID, run the following command:
|
||||
|
||||
```
|
||||
ng config --global cli.analyticsSharing.user ""
|
||||
```
|
||||
|
||||
To turn off this feature, run the following command:
|
||||
|
||||
```
|
||||
ng config --global --remove cli.analyticsSharing
|
||||
```
|
3
aio/content/examples/.gitignore
vendored
@ -92,3 +92,6 @@ upgrade-phonecat-3-final/tsconfig-aot.json
|
||||
upgrade-phonecat-3-final/rollup-config.js
|
||||
!upgrade-phonecat-*/**/karma.conf.js
|
||||
!upgrade-phonecat-*/**/karma-test-shim.js
|
||||
|
||||
# schematics
|
||||
!schematics-for-libraries/projects/my-lib/package.json
|
@ -0,0 +1,20 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('Built Template Functions Example', function () {
|
||||
beforeAll(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it('should have title Built-in Template Functions', function () {
|
||||
let title = element.all(by.css('h1')).get(0);
|
||||
expect(title.getText()).toEqual('Built-in Template Functions');
|
||||
});
|
||||
|
||||
it('should display $any( ) in h2', function () {
|
||||
let header = element(by.css('h2'));
|
||||
expect(header.getText()).toContain('$any( )');
|
||||
});
|
||||
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
<h1>{{title}}</h1>
|
||||
|
||||
<h2><code>$any( )</code> type cast function and an undeclared member</h2>
|
||||
|
||||
<p>There is no such member as <code>bestByDate</code> in the following two examples, so nothing renders:</p>
|
||||
<!-- #docregion any-type-cast-function-1 -->
|
||||
<p>The item's undeclared best by date is: {{$any(item).bestByDate}}</p>
|
||||
<!-- #enddocregion any-type-cast-function-1 -->
|
||||
|
||||
<h2>using <code>this</code></h2>
|
||||
<!-- #docregion any-type-cast-function-2 -->
|
||||
<p>The item's undeclared best by date is: {{$any(this).bestByDate}}</p>
|
||||
<!-- #enddocregion any-type-cast-function-2 -->
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
import { TestBed, async } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
it('should create the app', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
});
|
@ -0,0 +1,16 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Built-in Template Functions';
|
||||
|
||||
item = {
|
||||
name : 'Telephone',
|
||||
origin : 'Sweden',
|
||||
price: 98
|
||||
};
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Built-in Template Functions Example</title>
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<app-root>Loading...</app-root>
|
||||
</body>
|
||||
</html>
|
11
aio/content/examples/built-in-template-functions/src/main.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"description": "Built-in Template Functions",
|
||||
"files": [
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.[1,2].*"
|
||||
],
|
||||
"file": "src/app/app.component.ts",
|
||||
"tags": ["Built-in Template Functions"]
|
||||
}
|
@ -13,15 +13,4 @@ describe('AppComponent', () => {
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
it(`should have as title 'Featured product:'`, async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('Featured product:');
|
||||
}));
|
||||
it('should render title in a p tag', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('p').textContent).toContain('Featured product:');
|
||||
}));
|
||||
});
|
||||
|
@ -31,6 +31,7 @@ describe('Router', () => {
|
||||
heroDetailTitle: heroDetail.element(by.xpath('*[2]')),
|
||||
|
||||
adminHref: hrefEles.get(2),
|
||||
adminPage: element(by.css('app-root > div > app-admin')),
|
||||
adminPreloadList: element.all(by.css('app-root > div > app-admin > app-admin-dashboard > ul > li')),
|
||||
|
||||
loginHref: hrefEles.get(3),
|
||||
@ -138,6 +139,31 @@ describe('Router', () => {
|
||||
expect(page.secondaryOutlet.count()).toBe(1, 'secondary outlet');
|
||||
});
|
||||
|
||||
it('should redirect with secondary route', async () => {
|
||||
const page = getPageStruct();
|
||||
|
||||
// go to login page and login
|
||||
await browser.get('');
|
||||
await page.loginHref.click();
|
||||
await page.loginButton.click();
|
||||
|
||||
// open secondary outlet
|
||||
await page.contactHref.click();
|
||||
|
||||
// go to login page and logout
|
||||
await page.loginHref.click();
|
||||
await page.loginButton.click();
|
||||
|
||||
// attempt to go to admin page, redirects to login with secondary outlet open
|
||||
await page.adminHref.click();
|
||||
|
||||
// login, get redirected back to admin with outlet still open
|
||||
await page.loginButton.click();
|
||||
|
||||
expect(await page.adminPage.isDisplayed()).toBeTruthy();
|
||||
expect(page.secondaryOutlet.count()).toBeTruthy();
|
||||
});
|
||||
|
||||
async function crisisCenterEdit(index: number, save: boolean) {
|
||||
const page = getPageStruct();
|
||||
await page.crisisHref.click();
|
||||
|
@ -27,10 +27,10 @@ export class LoginComponent {
|
||||
if (this.authService.isLoggedIn) {
|
||||
// Get the redirect URL from our auth service
|
||||
// If no redirect has been set, use the default
|
||||
let redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/crisis-center/admin';
|
||||
let redirect = this.authService.redirectUrl ? this.router.parseUrl(this.authService.redirectUrl) : '/admin';
|
||||
|
||||
// Redirect the user
|
||||
this.router.navigate([redirect]);
|
||||
this.router.navigateByUrl(redirect);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ export class LoginComponent {
|
||||
if (this.authService.isLoggedIn) {
|
||||
// Get the redirect URL from our auth service
|
||||
// If no redirect has been set, use the default
|
||||
let redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/admin';
|
||||
let redirect = this.authService.redirectUrl ? this.router.parseUrl(this.authService.redirectUrl) : '/admin';
|
||||
|
||||
// #docregion preserve
|
||||
// Set our navigation extras object
|
||||
@ -39,7 +39,7 @@ export class LoginComponent {
|
||||
};
|
||||
|
||||
// Redirect the user
|
||||
this.router.navigate([redirect], navigationExtras);
|
||||
this.router.navigateByUrl(redirect, navigationExtras);
|
||||
// #enddocregion preserve
|
||||
}
|
||||
});
|
||||
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"projectType": "schematics"
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../dist/my-lib",
|
||||
"lib": {
|
||||
"entryFile": "src/public_api.ts"
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
// #docplaster
|
||||
// #docregion collection
|
||||
{
|
||||
"name": "my-lib",
|
||||
"version": "0.0.1",
|
||||
// #enddocregion collection
|
||||
"scripts": {
|
||||
"build": "../../node_modules/.bin/tsc -p tsconfig.schematics.json",
|
||||
"copy:schemas": "cp --parents schematics/*/schema.json ../../dist/my-lib/",
|
||||
"copy:files": "cp --parents -p schematics/*/files/** ../../dist/my-lib/",
|
||||
"copy:collection": "cp schematics/collection.json ../../dist/my-lib/schematics/collection.json",
|
||||
"postbuild": "npm run copy:schemas && npm run copy:files && npm run copy:collection"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^7.2.0",
|
||||
"@angular/core": "^7.2.0"
|
||||
},
|
||||
// #docregion collection
|
||||
"schematics": "./schematics/collection.json"
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
|
||||
"schematics": {
|
||||
"ng-add": {
|
||||
"description": "Add my library to the project.",
|
||||
"factory": "./ng-add/index#ngAdd"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
|
||||
"schematics": {
|
||||
"ng-add": {
|
||||
"description": "Add my library to the project.",
|
||||
"factory": "./ng-add/index#ngAdd"
|
||||
},
|
||||
"my-service": {
|
||||
"description": "Generate a service in the project.",
|
||||
"factory": "./my-service/index#myService",
|
||||
"schema": "./my-service/schema.json"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
// #docregion template
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class <%= classify(name) %>Service {
|
||||
constructor(private http: HttpClient) { }
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import { Rule, Tree } from '@angular-devkit/schematics';
|
||||
|
||||
import { Schema as MyServiceSchema } from './schema';
|
||||
|
||||
// #docregion factory
|
||||
export function myService(options: MyServiceSchema): Rule {
|
||||
return (tree: Tree) => {
|
||||
return tree;
|
||||
};
|
||||
}
|
||||
// #enddocregion factory
|
@ -0,0 +1,66 @@
|
||||
// #docplaster
|
||||
// #docregion schematics-imports, schema-imports, workspace
|
||||
import {
|
||||
Rule, Tree, SchematicsException,
|
||||
apply, url, applyTemplates, move,
|
||||
chain, mergeWith
|
||||
} from '@angular-devkit/schematics';
|
||||
|
||||
import { strings, normalize, experimental } from '@angular-devkit/core';
|
||||
// #enddocregion schematics-imports
|
||||
|
||||
import { Schema as MyServiceSchema } from './schema';
|
||||
// #enddocregion schema-imports
|
||||
|
||||
export function myService(options: MyServiceSchema): Rule {
|
||||
return (tree: Tree) => {
|
||||
const workspaceConfig = tree.read('/angular.json');
|
||||
if (!workspaceConfig) {
|
||||
throw new SchematicsException('Could not find Angular workspace configuration');
|
||||
}
|
||||
|
||||
// convert workspace to string
|
||||
const workspaceContent = workspaceConfig.toString();
|
||||
|
||||
// parse workspace string into JSON object
|
||||
const workspace: experimental.workspace.WorkspaceSchema = JSON.parse(workspaceContent);
|
||||
// #enddocregion workspace
|
||||
// #docregion project-fallback
|
||||
if (!options.project) {
|
||||
options.project = workspace.defaultProject;
|
||||
}
|
||||
// #enddocregion project-fallback
|
||||
|
||||
// #docregion project-info
|
||||
const projectName = options.project as string;
|
||||
|
||||
const project = workspace.projects[projectName];
|
||||
|
||||
const projectType = project.projectType === 'application' ? 'app' : 'lib';
|
||||
// #enddocregion project-info
|
||||
|
||||
// #docregion path
|
||||
if (options.path === undefined) {
|
||||
options.path = `${project.sourceRoot}/${projectType}`;
|
||||
}
|
||||
// #enddocregion path
|
||||
|
||||
// #docregion template
|
||||
const templateSource = apply(url('./files'), [
|
||||
applyTemplates({
|
||||
classify: strings.classify,
|
||||
dasherize: strings.dasherize,
|
||||
name: options.name
|
||||
}),
|
||||
move(normalize(options.path as string))
|
||||
]);
|
||||
// #enddocregion template
|
||||
|
||||
// #docregion chain
|
||||
return chain([
|
||||
mergeWith(templateSource)
|
||||
]);
|
||||
// #enddocregion chain
|
||||
// #docregion workspace
|
||||
};
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"id": "SchematicsMyService",
|
||||
"title": "My Service Schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "The name of the service.",
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"description": "The path to create the service.",
|
||||
"visible": false
|
||||
},
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The name of the project.",
|
||||
"$default": {
|
||||
"$source": "projectName"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name"
|
||||
]
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
export interface Schema {
|
||||
// The name of the service.
|
||||
name: string;
|
||||
|
||||
// The path to create the service.
|
||||
path?: string;
|
||||
|
||||
// The name of the project.
|
||||
project?: string;
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
|
||||
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
|
||||
|
||||
// Just return the tree
|
||||
export function ngAdd(_options: any): Rule {
|
||||
return (tree: Tree, _context: SchematicContext) => {
|
||||
_context.addTask(new NodePackageInstallTask());
|
||||
return tree;
|
||||
};
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MyLibComponent } from './my-lib.component';
|
||||
|
||||
describe('MyLibComponent', () => {
|
||||
let component: MyLibComponent;
|
||||
let fixture: ComponentFixture<MyLibComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ MyLibComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MyLibComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,19 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-my-lib',
|
||||
template: `
|
||||
<p>
|
||||
my-lib works!
|
||||
</p>
|
||||
`,
|
||||
styles: []
|
||||
})
|
||||
export class MyLibComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { MyLibComponent } from './my-lib.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [MyLibComponent],
|
||||
imports: [
|
||||
],
|
||||
exports: [MyLibComponent]
|
||||
})
|
||||
export class MyLibModule { }
|
@ -0,0 +1,12 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MyLibService } from './my-lib.service';
|
||||
|
||||
describe('MyLibService', () => {
|
||||
beforeEach(() => TestBed.configureTestingModule({}));
|
||||
|
||||
it('should be created', () => {
|
||||
const service: MyLibService = TestBed.get(MyLibService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MyLibService {
|
||||
|
||||
constructor() { }
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Public API Surface of my-lib
|
||||
*/
|
||||
|
||||
export * from './lib/my-lib.service';
|
||||
export * from './lib/my-lib.component';
|
||||
export * from './lib/my-lib.module';
|
@ -0,0 +1,32 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"importHelpers": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"annotateForClosureCompiler": true,
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
],
|
||||
"declaration": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"noEmitOnError": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedParameters": true,
|
||||
"noUnusedLocals": true,
|
||||
"rootDir": "schematics",
|
||||
"outDir": "../../dist/my-lib/schematics",
|
||||
"skipDefaultLibCheck": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strictNullChecks": true,
|
||||
"target": "es6",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"schematics/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"schematics/*/files/**/*"
|
||||
]
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<h2>Library Schematics</h2>
|
||||
`,
|
||||
styles: []
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'schematics-for-libraries';
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
14
aio/content/examples/schematics-for-libraries/src/index.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>SchematicsForLibraries</title>
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
12
aio/content/examples/schematics-for-libraries/src/main.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch(err => console.error(err));
|
10
aio/content/examples/schematics-for-libraries/zipper.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"description": "Schematics For Libraries",
|
||||
"files": [
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.[1].*",
|
||||
"**/*.template"
|
||||
],
|
||||
"tags": ["Angular", "Libraries", "Schematics"]
|
||||
}
|
@ -6,11 +6,13 @@ import uglify from 'rollup-plugin-uglify'
|
||||
|
||||
//paths are relative to the execution path
|
||||
export default {
|
||||
entry: 'app/main-aot.js',
|
||||
dest: 'aot/dist/build.js', // output a single application bundle
|
||||
sourceMap: true,
|
||||
sourceMapFile: 'aot/dist/build.js.map',
|
||||
format: 'iife',
|
||||
input: 'app/main-aot.js',
|
||||
output: {
|
||||
file: 'aot/dist/build.js', // output a single application bundle
|
||||
format: 'iife',
|
||||
sourcemap: true,
|
||||
sourcemapFile: 'aot/dist/build.js.map'
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve({jsnext: true, module: true}),
|
||||
commonjs({
|
||||
|
59
aio/content/guide/app-shell.md
Normal file
@ -0,0 +1,59 @@
|
||||
# App shell
|
||||
|
||||
App shell is a way to render a portion of your application via a route at build time.
|
||||
It can improve the user experience by quickly launching a static rendered page (a skeleton common to all pages) while the browser downloads the full client version and switches to it automatically after the code loads.
|
||||
|
||||
This gives users a meaningful first paint of your application that appears quickly because the browser can simply render the HTML and CSS without the need to initialize any JavaScript.
|
||||
|
||||
Learn more in [The App Shell Model](https://developers.google.com/web/fundamentals/architecture/app-shell).
|
||||
|
||||
## Step 1: Prepare the application
|
||||
|
||||
You can do this with the following CLI command:
|
||||
<code-example format="." language="bash" linenums="false">
|
||||
ng new my-app --routing
|
||||
</code-example>
|
||||
|
||||
For an existing application, you have to manually add the `RouterModule` and defining a `<router-outlet>` within your application.
|
||||
|
||||
## Step 2: Create the app shell
|
||||
|
||||
Use the CLI to automatically create the app shell.
|
||||
|
||||
<code-example format="." language="bash" linenums="false">
|
||||
ng generate app-shell --client-project my-app --universal-project server-app
|
||||
</code-example>
|
||||
|
||||
* `my-app` takes the name of your client application.
|
||||
* `server-app` takes the name of the Universal (or server) application.
|
||||
|
||||
After running this command you will notice that the `angular.json` configuration file has been updated to add two new targets, with a few other changes.
|
||||
|
||||
<code-example format="." language="none" linenums="false">
|
||||
"server": {
|
||||
"builder": "@angular-devkit/build-angular:server",
|
||||
"options": {
|
||||
"outputPath": "dist/my-app-server",
|
||||
"main": "src/main.server.ts",
|
||||
"tsConfig": "tsconfig.server.json"
|
||||
}
|
||||
},
|
||||
"app-shell": {
|
||||
"builder": "@angular-devkit/build-angular:app-shell",
|
||||
"options": {
|
||||
"browserTarget": "my-app:build",
|
||||
"serverTarget": "my-app:server",
|
||||
"route": "shell"
|
||||
}
|
||||
}
|
||||
</code-example>
|
||||
|
||||
## Step 3: Verify the app is built with the shell content
|
||||
|
||||
Use the CLI to build the `app-shell` target.
|
||||
|
||||
<code-example format="." language="bash" linenums="false">
|
||||
ng run my-app:app-shell
|
||||
</code-example>
|
||||
|
||||
To verify the build output, open `dist/my-app/index.html`. Look for default text `app-shell works!` to show that the app shell route was rendered as part of the output.
|
@ -2,7 +2,7 @@
|
||||
|
||||
You can create and publish new libraries to extend Angular functionality. If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.
|
||||
|
||||
An simple example might be a button that sends users to your company website, that would be included in all apps that your company builds.
|
||||
A simple example might be a button that sends users to your company website, that would be included in all apps that your company builds.
|
||||
|
||||
## Getting started
|
||||
|
||||
|
@ -1,43 +1,54 @@
|
||||
# Workspace and project file structure
|
||||
|
||||
You develop apps in the context of an Angular [workspace](guide/glossary#workspace). A workspace contains the files for one or more [projects](guide/glossary#project). A project is the set of files that comprise a standalone app, a library, or a set of end-to-end (e2e) tests.
|
||||
You develop applications in the context of an Angular [workspace](guide/glossary#workspace). A workspace contains the files for one or more [projects](guide/glossary#project). A project is the set of files that comprise a standalone application or a shareable library.
|
||||
|
||||
The Angular CLI command `ng new <project_name>` gets you started.
|
||||
When you run this command, the CLI installs the necessary Angular npm packages and other dependencies in a new workspace, with a root folder named *project_name*.
|
||||
It also creates the following workspace and starter project files:
|
||||
The Angular CLI `ng new` command creates a workspace.
|
||||
|
||||
* An initial skeleton app project, also called *project_name* (in the `src/` subfolder).
|
||||
* An end-to-end test project (in the `e2e/` subfolder).
|
||||
* Related configuration files.
|
||||
<code-example language="bash" linenums="false">
|
||||
ng new <project_name>
|
||||
</code-example>
|
||||
|
||||
The initial app project contains a simple Welcome app, ready to run.
|
||||
When you run this command, the CLI installs the necessary Angular npm packages and other dependencies in a new workspace, with a root folder named *project_name*.
|
||||
The workspace root folder contains workspace configuration files and a README file with generated descriptive text that you can customize.
|
||||
|
||||
## Workspace files
|
||||
By default, `ng new` also creates an initial skeleton application, along with its end-to-end tests.
|
||||
The skeleton is for a simple Welcome application that is ready to run and easy to modify.
|
||||
This *root application* has the same name as the workspace, and the source files reside in the `src/` subfolder of the workspace.
|
||||
|
||||
The top level of the workspace contains a number of workspace-wide configuration files.
|
||||
This default behavior is suitable for a typical "multi-repo" development style where each application resides in its own workspace.
|
||||
Beginners and intermediate users are encouraged to use `ng new` to create a separate workspace for each application.
|
||||
|
||||
Angular also supports workspaces with [multiple projects](#multiple-projects).
|
||||
This type of development environment is suitable for advanced users who are developing [shareable libraries](guide/glossary#library),
|
||||
and for enterprises that use a "mono-repo" development style, with a single repository and global configuration for all Angular projects.
|
||||
|
||||
To set up a mono-repo workspace, you should skip the creating the root application.
|
||||
See [Setting up for a multi-project workspace](#multiple-projects) below.
|
||||
|
||||
## Workspace configuration files
|
||||
|
||||
All projects within a workspace share a [CLI configuration context](guide/workspace-config).
|
||||
The top level of the workspace contains workspace-wide configuration files.
|
||||
|
||||
| WORKSPACE CONFIG FILES | PURPOSE |
|
||||
| :--------------------- | :------------------------------------------|
|
||||
| `node_modules/` | Provides [npm packages](guide/npm-packages) to the entire workspace. Workspace-wide `node_modules` dependencies are visible to all projects. |
|
||||
| `.editorconfig` | Configuration for code editors. See [EditorConfig](https://editorconfig.org/). |
|
||||
| `.gitignore` | Specifies intentionally untracked files that [Git](https://git-scm.com/) should ignore. |
|
||||
| `angular.json` | CLI configuration defaults for all projects in the workspace, including configuration options for build, serve, and test tools that the CLI uses, such as [TSLint](https://palantir.github.io/tslint/), [Karma](https://karma-runner.github.io/), and [Protractor](http://www.protractortest.org/). For details, see [Angular Workspace Configuration](guide/workspace-config). |
|
||||
| `node_modules` | Provides [npm packages](guide/npm-packages) to the entire workspace. |
|
||||
| `package.json` | Configures [npm package dependencies](guide/npm-packages) that are available to all projects in the workspace. See [npm documentation](https://docs.npmjs.com/files/package.json) for the specific format and contents of this file. |
|
||||
| `package-lock.json` | Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. |
|
||||
| `tsconfig.json` | Default [TypeScript](https://www.typescriptlang.org/) configuration for apps in the workspace, including TypeScript and Angular template compiler options. See [TypeScript Configuration](guide/typescript-configuration). |
|
||||
| `tslint.json` | Default [TSLint](https://palantir.github.io/tslint/) configuration for apps in the workspace. |
|
||||
| `README.md` | Introductory documentation. |
|
||||
| `package.json` | Configures [npm package dependencies](guide/npm-packages) that are available to all projects in the workspace. See [npm documentation](https://docs.npmjs.com/files/package.json) for the specific format and contents of this file. |
|
||||
| `package-lock.json` | Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. |
|
||||
| `README.md` | Introductory documentation for the root app. |
|
||||
| `tsconfig.json` | Default [TypeScript](https://www.typescriptlang.org/) configuration for projects in the workspace. |
|
||||
| `tslint.json` | Default [TSLint](https://palantir.github.io/tslint/) configuration for projects in the workspace. |
|
||||
|
||||
All projects within a workspace share a [CLI configuration context](guide/workspace-config).
|
||||
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.*.json`, and app-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
|
||||
## Application project files
|
||||
|
||||
### Default app project files
|
||||
By default, the CLI command `ng new my-app` creates a workspace folder named "my-app" and generates a new application skeleton for a root application at the top level of the workspace.
|
||||
A newly generated application contains source files for a root module, with a root component and template.
|
||||
|
||||
The CLI command `ng new my-app` creates a workspace folder named "my-app" and generates a new app skeleton.
|
||||
This initial app is the *default app* for CLI commands (unless you change the default after creating additional apps).
|
||||
|
||||
A newly generated app contains the source files for a root module, with a root component and template.
|
||||
When the workspace file structure is in place, you can use the `ng generate` command on the command line to add functionality and data to the initial app.
|
||||
When the workspace file structure is in place, you can use the `ng generate` command on the command line to add functionality and data to the application.
|
||||
This initial starter application is the *default app* for CLI commands (unless you change the default after creating [additional apps](#multiple-projects)).
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
@ -45,69 +56,109 @@ When the workspace file structure is in place, you can use the `ng generate` com
|
||||
|
||||
</div>
|
||||
|
||||
The `src/` subfolder contains the source files (app logic, data, and assets), along with configuration files for the initial app.
|
||||
Workspace-wide `node_modules` dependencies are visible to this project.
|
||||
For a single-application workspace, the `src/` subfolder of the workspace contains the source files (application logic, data, and assets) for the root application.
|
||||
For a multi-project workspace, additional projects in the `projects/` folder contain a `project-name/src/` subfolder with the same structure.
|
||||
|
||||
| APP SOURCE & CONFIG FILES | PURPOSE |
|
||||
### Application source files
|
||||
|
||||
Files at the top level of `src/` support testing and running your application. Subfolders contain the application source and application-specific configuration.
|
||||
|
||||
| APP SUPPORT FILES | PURPOSE |
|
||||
| :--------------------- | :------------------------------------------|
|
||||
| `app/` | Contains the component files in which your app logic and data are defined. See details in [App source folder](#app-src) below. |
|
||||
| `assets/` | Contains image files and other asset files to be copied as-is when you build your application. |
|
||||
| `app/` | Contains the component files in which your application logic and data are defined. See details [below](#app-src). |
|
||||
| `assets/` | Contains image and other asset files to be copied as-is when you build your application. |
|
||||
| `environments/` | Contains build configuration options for particular target environments. By default there is an unnamed standard development environment and a production ("prod") environment. You can define additional target environment configurations. |
|
||||
| `browserslist` | Configures sharing of target browsers and Node.js versions among various front-end tools. See [Browserslist on GitHub](https://github.com/browserslist/browserslist) for more information. |
|
||||
| `favicon.ico` | An icon to use for this app in the bookmark bar. |
|
||||
| `favicon.ico` | An icon to use for this application in the bookmark bar. |
|
||||
| `index.html` | The main HTML page that is served when someone visits your site. The CLI automatically adds all JavaScript and CSS files when building your app, so you typically don't need to add any `<script>` or` <link>` tags here manually. |
|
||||
| `main.ts` | The main entry point for your app. Compiles the application with the [JIT compiler](https://angular.io/guide/glossary#jit) and bootstraps the application's root module (AppModule) to run in the browser. You can also use the [AOT compiler](https://angular.io/guide/aot-compiler) without changing any code by appending the `--aot` flag to the CLI `build` and `serve` commands. |
|
||||
| `main.ts` | The main entry point for your application. Compiles the application with the [JIT compiler](https://angular.io/guide/glossary#jit) and bootstraps the application's root module (AppModule) to run in the browser. You can also use the [AOT compiler](https://angular.io/guide/aot-compiler) without changing any code by appending the `--aot` flag to the CLI `build` and `serve` commands. |
|
||||
| `polyfills.ts` | Provides polyfill scripts for browser support. |
|
||||
| `styles.sass` | Lists CSS files that supply styles for a project. The extension reflects the style preprocessor you have configured for the project. |
|
||||
| `test.ts` | The main entry point for your unit tests, with some Angular-specific configuration. You don't typically need to edit this file. |
|
||||
| `tsconfig.app.json` | Inherits from the workspace-wide `tsconfig.json` file. |
|
||||
| `tsconfig.spec.json` | Inherits from the workspace-wide `tsconfig.json` file. |
|
||||
| `tslint.json` | Inherits from the workspace-wide `tslint.json` file. |
|
||||
|
||||
### Default app project e2e files
|
||||
|
||||
An `e2e/` subfolder contains configuration and source files for a set of end-to-end tests that correspond to the initial app.
|
||||
Workspace-wide `node_modules` dependencies are visible to this project.
|
||||
|
||||
<code-example language="none" linenums="false">
|
||||
my-app/
|
||||
e2e/ (end-to-end test app for my-app)
|
||||
src/ (app source files)
|
||||
protractor.conf.js (test-tool config)
|
||||
tsconfig.e2e.json (TypeScript config inherits from workspace tsconfig.json)
|
||||
</code-example>
|
||||
|
||||
### Project folders for additional apps and libraries
|
||||
|
||||
When you generate new projects in a workspace,
|
||||
the CLI creates a new *workspace*`/projects` folder, and adds the generated files there.
|
||||
|
||||
When you generate an app (`ng generate application my-other-app`), the CLI adds folders under `projects/` for both the app and its corresponding end-to-end tests. Newly generated libraries are also added under `projects/`.
|
||||
|
||||
<code-example language="none" linenums="false">
|
||||
my-app/
|
||||
...
|
||||
projects/ (additional apps and libs)
|
||||
my-other-app/ (a second app)
|
||||
src/
|
||||
(config files)
|
||||
my-other-app-e2e/ (corresponding test app)
|
||||
src/
|
||||
(config files)
|
||||
my-lib/ (a generated library)
|
||||
(config files)
|
||||
</code-example>
|
||||
|
||||
{@a app-src}
|
||||
## App source folder
|
||||
|
||||
Inside the `src/` folder, the `app/` folder contains your app's logic and data. Angular components, templates, and styles go here. An `assets/` subfolder contains images and anything else your app needs. Files at the top level of `src/` support testing and running your app.
|
||||
Inside the `src/` folder, the `app/` folder contains your project's logic and data.
|
||||
Angular components, templates, and styles go here.
|
||||
|
||||
| APP SOURCE FILES | PURPOSE |
|
||||
| `src/app/` FILES | PURPOSE |
|
||||
| :-------------------------- | :------------------------------------------|
|
||||
| `app/app.component.ts` | Defines the logic for the app's root component, named `AppComponent`. The view associated with this root component becomes the root of the [view hierarchy](guide/glossary#view-hierarchy) as you add components and services to your app. |
|
||||
| `app/app.component.ts` | Defines the logic for the app's root component, named `AppComponent`. The view associated with this root component becomes the root of the [view hierarchy](guide/glossary#view-hierarchy) as you add components and services to your application. |
|
||||
| `app/app.component.html` | Defines the HTML template associated with the root `AppComponent`. |
|
||||
| `app/app.component.css` | Defines the base CSS stylesheet for the root `AppComponent`. |
|
||||
| `app/app.component.spec.ts` | Defines a unit test for the root `AppComponent`. |
|
||||
| `app/app.module.ts` | Defines the root module, named `AppModule`, that tells Angular how to assemble the application. Initially declares only the `AppComponent`. As you add more components to the app, they must be declared here. |
|
||||
| `assets/*` | Contains image files and other asset files to be copied as-is when you build your application. |
|
||||
|
||||
### Application configuration files
|
||||
|
||||
The application-specific configuration files for the root application reside at the workspace root level.
|
||||
For a multi-project workspace, project-specific configuration files are in the project root, under `projects/project-name/`.
|
||||
|
||||
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.json`, and project-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
|
||||
|
||||
| APPLICATION-SPECIFIC CONFIG FILES | PURPOSE |
|
||||
| :--------------------- | :------------------------------------------|
|
||||
| `browserslist` | Configures sharing of target browsers and Node.js versions among various front-end tools. See [Browserslist on GitHub](https://github.com/browserslist/browserslist) for more information. |
|
||||
| `karma.conf.js` | Application-specific [Karma](https://karma-runner.github.io/2.0/config/configuration-file.html) configuration. |
|
||||
| `tsconfig.app.json` | Application-specific [TypeScript](https://www.typescriptlang.org/) configuration, including TypeScript and Angular template compiler options. See [TypeScript Configuration](guide/typescript-configuration). |
|
||||
| `tsconfig.spec.json` | [TypeScript](https://www.typescriptlang.org/) configuration for the application tests. See [TypeScript Configuration](guide/typescript-configuration). |
|
||||
| `tslint.json` | Application-specific [TSLint](https://palantir.github.io/tslint/) configuration. |
|
||||
|
||||
### End-to-end test files
|
||||
|
||||
An `e2e/` subfolder contains source files for a set of end-to-end tests that correspond to an application, along with test-specific configuration files.
|
||||
|
||||
<code-example language="none" linenums="false">
|
||||
my-app/
|
||||
e2e/
|
||||
src/ (end-to-end tests for my-app)
|
||||
app.e2e-spec.ts
|
||||
app.po.ts
|
||||
protractor.conf.js (test-tool config)
|
||||
tsconfig.json (TypeScript config inherits from workspace)
|
||||
</code-example>
|
||||
|
||||
{@a multiple-projects}
|
||||
|
||||
## Multiple projects
|
||||
|
||||
A multi-project workspace is suitable for an enterprise that uses a single repository and global configuration for all Angular projects (the "mono-repo" model). A multi-project workspace also supports library development.
|
||||
|
||||
### Setting up for a multi-project workspace
|
||||
|
||||
If you intend to have multiple projects in a workspace, you can skip the initial application generation when you create the workspace, and give the workspace a unique name.
|
||||
The following command creates a workspace with all of the workspace-wide configuration files, but no root application.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
ng new my-workspace --createApplication="false"
|
||||
</code-example>
|
||||
|
||||
You can then generate apps and libraries with names that are unique within the workspace.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
cd my-workspace
|
||||
ng generate application my-first-app
|
||||
</code-example>
|
||||
|
||||
### Multiple project file structure
|
||||
|
||||
The first explicitly generated application goes into the `projects/` folder along with all other projects in the workspace.
|
||||
Newly generated libraries are also added under `projects/`.
|
||||
When you create projects this way, the file structure of the workspace is entirely consistent with the structure of the [workspace configuration file](guide/workspace-config), `angular.json`.
|
||||
|
||||
<code-example language="none" linenums="false">
|
||||
my-workspace/
|
||||
... (workspace-wide config files)
|
||||
projects/ (generated applications and libraries)
|
||||
my-first-app/ --(an explicitly generated application)
|
||||
... --(application-specific config)
|
||||
e2e/ ----(corresponding e2e tests)
|
||||
src/ ----(e2e tests source)
|
||||
... ----(e2e-specific config)
|
||||
src/ --(source and support files for application)
|
||||
my-lib/ --(a generated library)
|
||||
... --(library-specific config)
|
||||
src/ --source and support files for library)
|
||||
</code-example>
|
||||
|
||||
Libraries (unlike applications and their associated e2e projects) have their own `package.json` configuration files.
|
||||
For more information about the library project structure, see [Creating Libraries](https://angular.io/guide/creating-libraries).
|
||||
|
@ -49,18 +49,6 @@ locale id to find the correct corresponding locale data.
|
||||
|
||||
By default, Angular uses the locale `en-US`, which is English as spoken in the United States of America.
|
||||
|
||||
To set your app's locale to another value, use the CLI parameter `--configuration` with the value of the locale id that you want to use:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng serve --configuration=fr
|
||||
</code-example>
|
||||
|
||||
If you use JIT, you also need to define the `LOCALE_ID` provider in your main module:
|
||||
|
||||
<code-example path="i18n/doc-files/app.module.ts" header="src/app/app.module.ts" linenums="false">
|
||||
</code-example>
|
||||
|
||||
|
||||
For more information about Unicode locale identifiers, see the
|
||||
[CLDR core spec](http://cldr.unicode.org/core-spec#Unicode_Language_and_Locale_Identifiers).
|
||||
|
||||
|
@ -158,7 +158,7 @@ You can <a href="generated/zips/cli-quickstart/cli-quickstart.zip" target="_blan
|
||||
</div>
|
||||
|
||||
|
||||
For more information about Angular project files and the file structure, see [Workspace and project file struture](guide/file-structure).
|
||||
For more information about Angular project files and the file structure, see [Workspace and project file structure](guide/file-structure).
|
||||
|
||||
|
||||
|
||||
|
@ -1280,8 +1280,9 @@ The **Routing Module** has several characteristics:
|
||||
### Integrate routing with your app
|
||||
|
||||
The sample routing application does not include routing by default.
|
||||
When you use the [Angular CLI](cli) to create a project that will use routing, set the `--routing` option for the project or app, and for each NgModule.
|
||||
When you create or initialize a new project (using the CLI [`ng new`](cli/new) command) or a new app (using the [`ng generate app`](cli/generate) command), specify the `--routing` option. This tells the CLI to include the `@angular/router` npm package and create a file named `app-routing.module.ts`.
|
||||
When you create a new workspace and initial application, the [Angular CLI](cli) [`ng new`](cli/new) command prompts you to add "Angular routing". Enter `Y`.
|
||||
When you generate a new application using the [`ng generate app`](cli/generate) command, specify the `--routing` option. These options tell the CLI to include the `@angular/router` npm package and create a file named `app-routing.module.ts`.
|
||||
|
||||
You can then use routing in any NgModule that you add to the project or app.
|
||||
|
||||
For example, the following command generates an NgModule that can use routing.
|
||||
@ -3849,7 +3850,7 @@ Update the `AuthGuard` to provide a `session_id` query that will remain after na
|
||||
|
||||
Add an `anchor` element so you can jump to a certain point on the page.
|
||||
|
||||
Add the `NavigationExtras` object to the `router.navigate` method that navigates you to the `/login` route.
|
||||
Add the `NavigationExtras` object to the `router.navigate()` method that navigates you to the `/login` route.
|
||||
|
||||
|
||||
<code-example path="router/src/app/auth/auth.guard.4.ts" linenums="false" header="src/app/auth/auth.guard.ts (v3)">
|
||||
@ -3860,7 +3861,7 @@ Add the `NavigationExtras` object to the `router.navigate` method that navigates
|
||||
|
||||
You can also preserve query parameters and fragments across navigations without having to provide them
|
||||
again when navigating. In the `LoginComponent`, you'll add an *object* as the
|
||||
second argument in the `router.navigate` function
|
||||
second argument in the `router.navigateUrl()` function
|
||||
and provide the `queryParamsHandling` and `preserveFragment` to pass along the current query parameters
|
||||
and fragment to the next route.
|
||||
|
||||
|
194
aio/content/guide/schematics-authoring.md
Normal file
@ -0,0 +1,194 @@
|
||||
# Authoring Schematics
|
||||
|
||||
You can create your own schematics to operate on Angular projects.
|
||||
Library developers typically package schematics with their libraries in order to integrate them with the Angular CLI.
|
||||
You can also create stand-alone schematics to manipulate the files and constructs in Angular applications as a way of customizing them for your development environment and making them conform to your standards and constraints.
|
||||
Schematics can be chained, running other schematics to perform complex operations.
|
||||
|
||||
Manipulating the code in an application has the potential to be both very powerful and correspondingly dangerous.
|
||||
For example, creating a file that already exists would be an error, and if it was applied immediately, it would discard all the other changes applied so far.
|
||||
The Angular Schematics tooling guards against side effects and errors by creating a virtual file system.
|
||||
A schematic describes a pipeline of transformations that can be applied to the virtual file system.
|
||||
When a schematic runs, the transformations are recorded in memory, and only applied in the real file system once they're confirmed to be valid.
|
||||
|
||||
## Schematics concepts
|
||||
|
||||
The public API for schematics defines classes that represent the basic concepts.
|
||||
|
||||
* The virtual file system is represented by a `Tree`. The `Tree` data structure contains a *base* (a set of files that already exists) and a *staging area* (a list of changes to be applied to the base).
|
||||
When making modifications, you don't actually change the base, but add those modifications to the staging area.
|
||||
|
||||
* A `Rule` object defines a function that takes a `Tree`, applies transformations, and returns a new `Tree`. The main file for a schematic, `index.ts`, defines a set of rules that implement the schematic's logic.
|
||||
|
||||
* A transformation is represented by an `Action`. There are four action types: `Create`, `Rename`, `Overwrite`, and `Delete`.
|
||||
|
||||
* Each schematic runs in a context, represented by a `SchematicContext` object.
|
||||
|
||||
The context object passed into a rule provides access to utility functions and metadata that the schematic may need to work with, including a logging API to help with debugging.
|
||||
The context also defines a *merge strategy* that determines how changes are merged from the staged tree into the base tree. A change can be accepted or ignored, or throw an exception.
|
||||
|
||||
### Defining rules and actions
|
||||
|
||||
When you create a new blank schematic with the [Schematics CLI](#cli), the generated entry function is a *rule factory*.
|
||||
A `RuleFactory`object defines a higher-order function that creates a `Rule`.
|
||||
|
||||
<code-example language="TypeScript" linenums="false">
|
||||
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
|
||||
|
||||
// You don't have to export the function as default.
|
||||
// You can also have more than one rule factory per file.
|
||||
export function helloWorld(_options: any): Rule {
|
||||
return (tree: Tree, _context: SchematicContext) => {
|
||||
return tree;
|
||||
};
|
||||
}
|
||||
</code-example>
|
||||
|
||||
Your rules can make changes to your projects by calling external tools and implementing logic.
|
||||
You need a rule, for example, to define how a template in the schematic is to be merged into the hosting project.
|
||||
|
||||
Rules can make use of utilities provided with the `@schematics/angular` package. Look for helper functions for working with modules, dependencies, TypeScript, AST, JSON, Angular CLI workspaces and projects, and more.
|
||||
|
||||
<code-example language="none" linenums="false">
|
||||
|
||||
import {
|
||||
JsonAstObject,
|
||||
JsonObject,
|
||||
JsonValue,
|
||||
Path,
|
||||
normalize,
|
||||
parseJsonAst,
|
||||
strings,
|
||||
} from '@angular-devkit/core';
|
||||
|
||||
</code-example>
|
||||
|
||||
### Defining input options with a schema and interfaces
|
||||
|
||||
Rules can collect option values from the caller and inject them into templates.
|
||||
The options available to your rules, with their allowed values and defaults, are defined in the schematic's JSON schema file, `<schematic>/schema.json`.
|
||||
You can define variable or enumerated data types for the schema using TypeScript interfaces.
|
||||
|
||||
You can see examples of schema files for the Angular CLI command schematics in [`@schematics/angular`](https://github.com/angular/angular-cli/blob/7.0.x/packages/schematics/angular/application/schema.json).
|
||||
|
||||
{@a cli}
|
||||
|
||||
## Schematics CLI
|
||||
|
||||
Schematics come with their own command-line tool.
|
||||
Using Node 6.9 or above, install the Schematics command line tool globally:
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
npm install -g @angular-devkit/schematics-cli
|
||||
</code-example>
|
||||
|
||||
This installs the `schematics` executable, which you can use to create a new schematics collection in its own project folder, add a new schematic to an existing collection, or extend an existing schematic.
|
||||
|
||||
In the following sections, we will create a new schematics collection using the CLI in order to introduce the files and file structure, and some of the basic concepts.
|
||||
|
||||
The most common use of schematics, however, is to integrate an Angular library with the Angular CLI.
|
||||
You can do this by creating the schematic files directly within the library project in an Angular workspace, without using the Schematics CLI.
|
||||
See [Schematics for Libraries](guide/schematics-for-libraries).
|
||||
|
||||
### Creating a schematics collection
|
||||
|
||||
The following command creates a new schematic named `hello-world` in a new project folder of the same name.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
schematics blank --name=hello-world
|
||||
</code-example>
|
||||
|
||||
The `blank` schematic is provided by the Schematics CLI. The command creates a new project folder (the root folder for the collection) and an initial named schematic in the collection.
|
||||
|
||||
Go to the collection folder, install your npm dependencies, and open your new collection in your favorite editor to see the generated files. For example, if you are using VSCode:
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
cd hello-world
|
||||
npm install
|
||||
npm run build
|
||||
code .
|
||||
</code-example>
|
||||
|
||||
The initial schematic gets the same name as the project folder, and is generated in `src/hello-world`.
|
||||
You can add related schematics to this collection, and modify the generated skeleton code to define your schematic's functionality.
|
||||
Each schematic name must be unique within the collection.
|
||||
|
||||
### Running a schematic
|
||||
|
||||
Use the `schematics` command to run a named schematic.
|
||||
Provide the path to the project folder, the schematic name, and any mandatory options, in the following format.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
schematics <path-to-schematics-project>:<schematics-name> --<required-option>=<value>
|
||||
</code-example>
|
||||
|
||||
The path can be absolute or relative to the current working directory where the command is executed.
|
||||
For example, to run the schematic we just generated (which has no required options), use the following command.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
schematics .:hello-world
|
||||
</code-example>
|
||||
|
||||
### Adding a schematic to a collection
|
||||
|
||||
To add a schematic to an existing collection, use the same command you use to start a new schematics project, but run the command inside the project folder.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
cd hello-world
|
||||
schematics blank --name=goodbye-world
|
||||
</code-example>
|
||||
|
||||
The command generates the new named schematic inside your collection, with a main `index.ts` file and its associated test spec.
|
||||
It also adds the name, description, and factory function for the new schematic to the collection's schema in the `collection.json` file.
|
||||
|
||||
## Collection contents
|
||||
|
||||
The top level of the root project folder for a collection contains configuration files, a `node_modules` folder, and a `src/` folder.
|
||||
The `src/` folder contains subfolders for named schematics in the collection, and a schema, `collection.json`, which describes the collected schematics.
|
||||
Each schematic is created with a name, description, and factory function.
|
||||
|
||||
<code-example language="none" linenums="false">
|
||||
{
|
||||
"$schema":
|
||||
"../node_modules/@angular-devkit/schematics/collection-schema.json",
|
||||
"schematics": {
|
||||
"hello-world": {
|
||||
"description": "A blank schematic.",
|
||||
"factory": "./hello-world/index#helloWorld"
|
||||
}
|
||||
}
|
||||
}
|
||||
</code-example>
|
||||
|
||||
* The `$schema` property specifies the schema that the CLI uses for validation.
|
||||
* The `schematics` property lists named schematics that belong to this collection.
|
||||
Each schematic has a plain-text description, and points to the generated entry function in the main file.
|
||||
* The `factory` property points to the generated entry function. In this example, you invoke the `hello-world` schematic by calling the `helloWorld()` factory function.
|
||||
* The optional `schema` property points to a JSON schema file that defines the command-line options available to the schematic.
|
||||
* The optional `aliases` array specifies one or more strings that can be used to invoke the schematic.
|
||||
For example, the schematic for the Angular CLI “generate” command has an alias “g”, allowing you to use the command `ng g`.
|
||||
|
||||
### Named schematics
|
||||
|
||||
When you use the Schematics CLI to create a blank schematics project, the new blank schematic is the first member of the collection, and has the same name as the collection.
|
||||
When you add a new named schematic to this collection, it is automatically added to the `collection.json` schema.
|
||||
|
||||
In addition to the name and description, each schematic has a `factory` property that identifies the schematic’s entry point.
|
||||
In the example, you invoke the schematic's defined functionality by calling the `helloWorld()` function in the main file, `hello-world/index.ts`.
|
||||
|
||||
<figure>
|
||||
<img src="generated/images/guide/schematics/collection-files.gif" alt="overview">
|
||||
</figure>
|
||||
|
||||
Each named schematic in the collection has the following main parts.
|
||||
|
||||
| | |
|
||||
| :------------- | :-------------------------------------------|
|
||||
| `index.ts` | Code that defines the transformation logic for a named schematic. |
|
||||
| `schema.json` | Schematic variable definition. |
|
||||
| `schema.d.ts` | Schematic variables. |
|
||||
| `files/` | Optional component/template files to replicate. |
|
||||
|
||||
It is possible for a schematic to provide all of its logic in the `index.ts` file, without additional templates.
|
||||
You can create dynamic schematics for Angular, however, by providing components and templates in the `files/` folder, like those in standalone Angular projects.
|
||||
The logic in the index file configures these templates by defining rules that inject data and modify variables.
|
320
aio/content/guide/schematics-for-libraries.md
Normal file
@ -0,0 +1,320 @@
|
||||
# Schematics for Libraries
|
||||
|
||||
When you create an Angular library, you can provide and package it with schematics that integrate it with the Angular CLI.
|
||||
With your schematics, your users can use `ng add` to install an initial version of your library,
|
||||
`ng generate` to create artifacts defined in your library, and `ng update` to adjust their project for a new version of your library that introduces breaking changes.
|
||||
|
||||
All three types of schematics can be part of a collection that you package with your library.
|
||||
|
||||
Download the <live-example downloadOnly>library schematics project</live-example> for a completed example of the steps below.
|
||||
|
||||
## Creating a schematics collection
|
||||
|
||||
To start a collection, you need to create the schematic files.
|
||||
The following steps show you how to add initial support without modifying any project files.
|
||||
|
||||
1. In your library's root folder, create a `schematics/` folder.
|
||||
|
||||
1. In the `schematics/` folder, create an `ng-add/` folder for your first schematic.
|
||||
|
||||
1. At the root level of the `schematics/` folder, create a `collection.json` file.
|
||||
|
||||
1. Edit the `collection.json` file to define the initial schema for your collection.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/collection.json (Schematics Collection)" path="schematics-for-libraries/projects/my-lib/schematics/collection.1.json">
|
||||
</code-example>
|
||||
|
||||
* The `$schema` path is relative to the Angular Devkit collection schema.
|
||||
* The `schematics` object describes the named schematics that are part of this collection.
|
||||
* The first entry is for a schematic named `ng-add`. It contains the description, and points to the factory function that is called when your schematic is executed.
|
||||
|
||||
1. In your library project's `package.json` file, add a "schematics" entry with the path to your schema file.
|
||||
The Angular CLI uses this entry to find named schematics in your collection when it runs commands.
|
||||
|
||||
<code-example header="projects/my-lib/package.json (Schematics Collection Reference)" path="schematics-for-libraries/projects/my-lib/package.json" region="collection">
|
||||
</code-example>
|
||||
|
||||
The initial schema that you have created tells the CLI where to find the schematic that supports the `ng add` command.
|
||||
Now you are ready to create that schematic.
|
||||
|
||||
## Providing installation support
|
||||
|
||||
A schematic for the `ng add` command can enhance the initial installation process for your users.
|
||||
The following steps will define this type of schematic.
|
||||
|
||||
1. Go to the <lib-root>/schematics/ng-add/ folder.
|
||||
|
||||
1. Create the main file, `index.ts`.
|
||||
|
||||
1. Open `index.ts` and add the source code for your schematic factory function.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/ng-add/index.ts (ng-add Rule Factory)" path="schematics-for-libraries/projects/my-lib/schematics/ng-add/index.ts">
|
||||
</code-example>
|
||||
|
||||
The only step needed to provide initial `ng add` support is to trigger an installation task using the `SchematicContext`.
|
||||
The task uses the user's preferred package manager to add the library to the project's `package.json` configuration file, and install it in the project’s `node_modules` directory.
|
||||
|
||||
In this example, the function receives the current `Tree` and returns it without any modifications.
|
||||
If you need to, you can do additional setup when your package is installed, such as generating files, updating configuration, or any other initial setup your library requires.
|
||||
|
||||
## Building your schematics
|
||||
|
||||
To bundle your schematics together with your library, you must configure the library to build the schematics separately, then add them to the bundle.
|
||||
You must build your schematics *after* you build your library, so they are placed in the correct directory.
|
||||
|
||||
* Your library needs a custom Typescript configuration file with instructions on how to compile your schematics into your distributed library.
|
||||
|
||||
* To add the schematics to the library bundle, add scripts to the library's `package.json` file.
|
||||
|
||||
Assume you have a library project `my-lib` in your Angular workspace.
|
||||
To tell the library how to build the schematics, add a `tsconfig.schematics.json` file next to the generated `tsconfig.lib.json` file that configures the library build.
|
||||
|
||||
1. Edit the `tsconfig.schematics.json` file to add the following content.
|
||||
|
||||
<code-example header="projects/my-lib/tsconfig.schematics.json (TypeScript Config)" path="schematics-for-libraries/projects/my-lib/tsconfig.schematics.json">
|
||||
</code-example>
|
||||
|
||||
* The `rootDir` specifies that your `schematics/` folder contains the input files to be compiled.
|
||||
|
||||
* The `outDir` maps to the library's output folder. By default, this is the `dist/my-lib` folder at the root of your workspace.
|
||||
|
||||
1. To make sure your schematics source files get compiled into the library bundle, add the following scripts to the `package.json` file in your library project's root folder (`projects/my-lib`).
|
||||
|
||||
<code-example header="projects/my-lib/package.json (Build Scripts)" path="schematics-for-libraries/projects/my-lib/package.json">
|
||||
</code-example>
|
||||
|
||||
* The `build` script compiles your schematic using the custom `tsconfig.schematics.json` file.
|
||||
* The `copy:*` statements copy compiled schematic files into the proper locations in the library output folder in order to preserve the file structure.
|
||||
* The `postbuild` script copies the schematic files after the `build` script completes.
|
||||
|
||||
## Providing generation support
|
||||
|
||||
You can add a named schematic to your collection that lets your users use the `ng generate` command to create an artifact that is defined in your library.
|
||||
|
||||
We'll assume that your library defines a service, `my-service`, that requires some setup. You want your users to be able to generate it using the following CLI command.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
ng generate my-lib:my-service
|
||||
</code-example>
|
||||
|
||||
To begin, create a new subfolder, `my-service`, in the `schematics` folder.
|
||||
|
||||
### Configure the new schematic
|
||||
|
||||
When you add a schematic to the collection, you have to point to it in the collection's schema, and provide configuration files to define options that a user can pass to the command.
|
||||
|
||||
1. Edit the `schematics/collection.json` file to point to the new schematic subfolder, and include a pointer to a schema file that will specify inputs for the new schematic.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/collection.json (Schematics Collection)" path="schematics-for-libraries/projects/my-lib/schematics/collection.json">
|
||||
</code-example>
|
||||
|
||||
1. Go to the `<lib-root>/schematics/my-service/` folder.
|
||||
|
||||
1. Create a `schema.json` file and define the available options for the schematic.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/schema.json (Schematic JSON Schema)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/schema.json">
|
||||
</code-example>
|
||||
|
||||
* *id* : A unique id for the schema in the collection.
|
||||
* *title* : A human-readable description of the schema.
|
||||
* *type* : A descriptor for the type provided by the properties.
|
||||
* *properties* : An object that defines the available options for the schematic.
|
||||
|
||||
Each option associates key with a type, description, and optional alias.
|
||||
The type defines the shape of the value you expect, and the description is displayed when the user requests usage help for your schematic.
|
||||
|
||||
See the workspace schema for additional customizations for schematic options.
|
||||
|
||||
1. Create a `schema.ts` file and define an interface that stores the values of the options defined in the `schema.json` file.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/schema.ts (Schematic Interface)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/schema.ts">
|
||||
</code-example>
|
||||
|
||||
* *name* : The name you want to provide for the created service.
|
||||
* *path* : Overrides the path provided to the schematic. The default path value is based on the current working directory.
|
||||
* *project* : Provides a specific project to run the schematic on. In the schematic, you can provide a default if the option is not provided by the user.
|
||||
|
||||
### Add template files
|
||||
|
||||
To add artifacts to a project, your schematic needs its own template files.
|
||||
Schematic templates support special syntax to execute code and variable substitution.
|
||||
|
||||
1. Create a `files/` folder inside the `schematics/my-service/` folder.
|
||||
|
||||
1. Create a file named `__name@dasherize__.service.ts.template` that defines a template you can use for generating files. This template will generate a service that already has Angular's `HttpClient` injected into its constructor.
|
||||
|
||||
<code-example lang="ts" header="projects/my-lib/schematics/my-service/files/__name@dasherize__.service.ts.template (Schematic Template)">
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class <%= classify(name) %>Service {
|
||||
constructor(private http: HttpClient) { }
|
||||
}
|
||||
|
||||
</code-example>
|
||||
|
||||
* The `classify` and `dasherize` methods are utility functions you schematic will use to transform your source template and filename.
|
||||
|
||||
* The `name` is provided as a property from your factory function. It is the same `name` you defined in the schema.
|
||||
|
||||
### Add the factory function
|
||||
|
||||
Now that you have the infrastructure in place, you can define the main function that performs the modifications you need in the user's project.
|
||||
|
||||
The Schematics framework provides a file templating system, which supports both path and content templates.
|
||||
The system operates on placeholders defined inside files or paths that loaded in the input `Tree`.
|
||||
It fills these in using values passed into the `Rule`.
|
||||
|
||||
For details of these data structure and syntax, see the [Schematics README](https://github.com/angular/angular-cli/blob/master/packages/angular_devkit/schematics/README.md).
|
||||
|
||||
|
||||
1. Create the main file, `index.ts` and add the source code for your schematic factory function.
|
||||
|
||||
1. First, import the schematics definitions you will need. The Schematics framework offers many utility functions to create and use rules when running a schematic.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/index.ts (Imports)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/index.ts" region="schematics-imports">
|
||||
</code-example>
|
||||
|
||||
1. Import the defined schema interface that provides the type information for your schematic's options.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/index.ts (Schema Import)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/index.ts" region="schema-imports">
|
||||
</code-example>
|
||||
|
||||
1. To build up the generation schematic, start with an empty rule factory.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/index.ts (Initial Rule)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/index.1.ts" region="factory">
|
||||
</code-example>
|
||||
|
||||
This simple rule factory returns the tree without modification.
|
||||
The options are the option values passed through from the `ng generate` command.
|
||||
|
||||
## Define a generation rule
|
||||
|
||||
We now have the framework in place for creating the code that actually modifies the user's application to set it up for the service defined in your library.
|
||||
|
||||
The Angular workspace where the user has installed your library contains multiple projects (applications and libraries).
|
||||
The user can specify the project on the command line, or allow it to default.
|
||||
In either case, your code needs to identify the specific project to which this schematic is being applied, so that you can retrieve information from the project configuration.
|
||||
|
||||
You can do this using the `Tree` object that is passed in to the factory function.
|
||||
The `Tree` methods give you access to the complete file tree in your workspace, allowing you to read and write files during the execution of the schematic.
|
||||
|
||||
### Get the project configuration
|
||||
|
||||
1. To determine the destination project, use the `Tree.read()` method to read the contents of the workspace configuration file, `angular.json`, at the root of the workspace.
|
||||
Add the following code to your factory function.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/index.ts (Schema Import)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/index.ts" region="workspace">
|
||||
</code-example>
|
||||
|
||||
* Be sure to check that the context exists and throw the appropriate error.
|
||||
|
||||
* After reading the contents into a string, parse the configuration into a JSON object, typed to the `WorkspaceSchema`.
|
||||
|
||||
1. The `WorkspaceSchema` contains all the properties of the workspace configuration, including a `defaultProject` value for determining which project to use if not provided.
|
||||
We will use that value as a fallback, if no project is explicitly specified in the `ng generate` command.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/index.ts (Default Project)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/index.ts" region="project-fallback">
|
||||
</code-example>
|
||||
|
||||
1. Now that you have the project name, use it to retrieve the project-specific configuration information.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/index.ts (Project)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/index.ts" region="project-info">
|
||||
</code-example>
|
||||
|
||||
The `workspace projects` object contains all the project-specific configuration information.
|
||||
|
||||
1. The `options.path` determines where the schematic template files are moved to once the schematic is applied.
|
||||
|
||||
The `path` option in the schematic's schema is substituted by default with the current working directory.
|
||||
If the `path` is not defined, use the `sourceRoot` from the project configuration along with the `projectType`.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/index.ts (Project Info)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/index.ts" region="path">
|
||||
</code-example>
|
||||
|
||||
### Define the rule
|
||||
|
||||
A `Rule` can use external template files, transform them, and return another `Rule` object with the transformed template. You can use the templating to generate any custom files required for your schematic.
|
||||
|
||||
1. Add the following code to your factory function.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/index.ts (Template transform)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/index.ts" region="template">
|
||||
</code-example>
|
||||
|
||||
* The `apply()` method applies multiple rules to a source and returns the transformed source. It takes 2 arguments, a source and an array of rules.
|
||||
* The `url()` method reads source files from your filesystem, relative to the schematic.
|
||||
* The `applyTemplates()` method receives an argument of methods and properties you want make available to the schematic template and the schematic filenames. It returns a `Rule`. This is where you define the `classify()` and `dasherize()` methods, and the `name` property.
|
||||
* The `classify()` method takes a value and returns the value in title case. For example, if the provided name is `my service`, it is returned as `MyService`
|
||||
* The `dasherize()` method takes a value and returns the value in dashed and lowercase. For example, if the provided name is MyService, it is returned as `my-service.
|
||||
* The `move` method moves the provided source files to their destination when the schematic is applied.
|
||||
|
||||
1. Finally, the rule factory must return a rule.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/index.ts (Chain Rule)" path="schematics-for-libraries/projects/my-lib/schematics/my-service/index.ts" region="chain">
|
||||
</code-example>
|
||||
|
||||
The `chain()` method allows you to combine multiple rules into a single rule, so that you can perform multiple operations in a single schematic.
|
||||
Here you are only merging the template rules with any code executed by the schematic.
|
||||
|
||||
See a complete exampled of the schematic rule function.
|
||||
|
||||
<code-example header="projects/my-lib/schematics/my-service/index.ts" path="schematics-for-libraries/projects/my-lib/schematics/my-service/index.ts">
|
||||
</code-example>
|
||||
|
||||
For more information about rules and utility methods, see [Provided Rules](https://github.com/angular/angular-cli/tree/master/packages/angular_devkit/schematics#provided-rules).
|
||||
|
||||
## Running your library schematic
|
||||
|
||||
After you build your library and schematics, you can install the schematics collection to run against your project. The steps below show you how to generate a service using the schematic you created above.
|
||||
|
||||
|
||||
### Build your library and schematics
|
||||
|
||||
From the root of your workspace, run the `ng build` command for your library.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
|
||||
ng build my-lib
|
||||
|
||||
</code-example>
|
||||
|
||||
Then, you change into your library directory to build the schematic
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
|
||||
cd projects/my-lib
|
||||
npm run build
|
||||
|
||||
</code-example>
|
||||
|
||||
### Link the library
|
||||
|
||||
Your library and schematics are packaged and placed in the `dist/my-lib` folder at the root of your workspace. For running the schematic, you need to link the library into your `node_modules` folder. From the root of your workspace, run the `npm link` command with the path to your distributable library.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
|
||||
npm link dist/my-lib
|
||||
|
||||
</code-example>
|
||||
|
||||
### Run the schematic
|
||||
|
||||
Now that your library is installed, you can run the schematic using the `ng generate` command.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
|
||||
ng generate my-lib:my-service --name my-data
|
||||
|
||||
</code-example>
|
||||
|
||||
In the console, you will see that the schematic was run and the `my-data.service.ts` file was created in your app folder.
|
||||
|
||||
<code-example language="bash" linenums="false" hideCopy="true">
|
||||
|
||||
CREATE src/app/my-data.service.ts (208 bytes)
|
||||
|
||||
</code-example>
|
121
aio/content/guide/schematics.md
Normal file
@ -0,0 +1,121 @@
|
||||
# Schematics
|
||||
|
||||
A schematic is a template-based code generator that supports complex logic.
|
||||
It is a set of instructions for transforming a software project by generating or modifying code.
|
||||
Schematics are packaged into [collections](guide/glossary#collection) and installed with npm.
|
||||
|
||||
The schematic collection can be a powerful tool for creating, modifying, and maintaining any software project, but is particularly useful for customizing Angular projects to suit the particular needs of your own organization.
|
||||
You might use schematics, for example, to generate commonly-used UI patterns or specific components, using predefined templates or layouts.
|
||||
You can use schematics to enforce architectural rules and conventions, making your projects consistent and inter-operative.
|
||||
|
||||
## Schematics for the Angular CLI
|
||||
|
||||
Schematics are part of the Angular ecosystem. The [Angular CLI](guide/glossary#cli) uses schematics to apply transforms to a web-app project.
|
||||
You can modify these schematics, and define new ones to do things like update your code to fix breaking changes in a dependency, for example, or to add a new configuration option or framework to an existing project.
|
||||
|
||||
Schematics that are included in the `@schematics/angular` collection are run by default by the commands `ng generate` and `ng add`.
|
||||
The package contains named schematics that configure the options that are available to the CLI for `ng generate` sub-commands, such as `ng generate component` and `ng generate service`.
|
||||
The subcommands for `ng generate` are shorthand for the corresponding schematic. You can specify a particular schematic (or collection of schematics) to generate, using the long form:
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
ng generate my-schematic-collection:my-schematic-name
|
||||
</code-example>
|
||||
|
||||
—or—
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
ng generate my-schematic-name --collection collection-name
|
||||
</code-example>
|
||||
|
||||
### Configuring CLI schematics
|
||||
|
||||
A JSON schema associated with a schematic tells the Angular CLI what options are available to commands and subcommands, and determines the defaults.
|
||||
These defaults can be overridden by providing a different value for an option on the command line.
|
||||
See [Workspace Configuration](guide/workspace-config) for information about how you can change the generation option defaults for your workspace.
|
||||
|
||||
The JSON schemas for the default schematics used by the CLI to generate projects and parts of projects are collected in the package [`@schematics/angular`](https://raw.githubusercontent.com/angular/angular-cli/v7.0.0/packages/schematics/angular/application/schema.json).
|
||||
The schema describes the options available to the CLI for each of the `ng generate` sub-commands, as shown in the `--help` output.
|
||||
|
||||
## Developing schematics for libraries
|
||||
|
||||
As a library developer, you can create your own collections of custom schematics to integrate your library with the Angular CLI.
|
||||
|
||||
* An *add schematic* allows developers to install your library in an Angular workspace using `ng add`.
|
||||
|
||||
* *Generation schematics* can tell the `ng generate` subcommands how to modify projects, add configurations and scripts, and scaffold artifacts that are defined in your library.
|
||||
|
||||
* An *update schematic* can tell the `ng update` command how to update your library's dependencies and adjust for breaking changes when you release a new version.
|
||||
|
||||
For more details of what these look like and how to create them, see:
|
||||
* [Authoring Schematics](guide/schematics-authoring)
|
||||
* [Schematics for Libraries](guide/schematics-for-libraries)
|
||||
|
||||
### Add schematics
|
||||
|
||||
An add schematic is typically supplied with a library, so that the library can be added to an existing project with `ng add`.
|
||||
The `add` command uses your package manager to download new dependencies, and invokes an installation script that is implemented as a schematic.
|
||||
|
||||
For example, the [`@angular/material`](https://material.angular.io/guide/schematics) schematic tells the `add` command to install and set up Angular Material and theming, and register new starter components that can be created with `ng generate`.
|
||||
You can look at this one as an example and model for your own add schematic.
|
||||
|
||||
Partner and third party libraries also support the Angular CLI with add schematics.
|
||||
For example, `@ng-bootstrap/schematics` adds [ng-bootstrap](https://ng-bootstrap.github.io/) to an app, and `@clr/angular` installs and sets up [Clarity from VMWare](https://vmware.github.io/clarity/documentation/v1.0/get-started).
|
||||
|
||||
An add schematic can also update a project with configuration changes, add additional dependencies (such as polyfills), or scaffold package-specific initialization code.
|
||||
For example, the `@angular/pwa` schematic turns your application into a PWA by adding an app manifest and service worker, and the `@angular/elements` schematic adds the `document-register-element.js` polyfill and dependencies for Angular Elements.
|
||||
|
||||
### Generation schematics
|
||||
|
||||
Generation schematics are instructions for the `ng generate` command.
|
||||
The documented sub-commands use the default Angular generation schematics, but you can specify a different schematic (in place of a sub-command) to generate an artifact defined in your library.
|
||||
|
||||
Angular Material, for example, supplies generation schematics for the UI components that it defines.
|
||||
The following command uses one of these schematics to render an Angular Material `<mat-table>` that is pre-configured with a datasource for sorting and pagination.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
ng generate @angular/material:table <component-name>
|
||||
</code-example>
|
||||
|
||||
### Update schematics
|
||||
|
||||
The `ng update` command can be used to update your workspace's library dependencies. If you supply no options or use the help option, the command examines your workspace and suggests libraries to update.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
ng update
|
||||
We analyzed your package.json, there are some packages to update:
|
||||
|
||||
Name Version Command to update
|
||||
--------------------------------------------------------------------------------
|
||||
@angular/cdk 7.2.2 -> 7.3.1 ng update @angular/cdk
|
||||
@angular/cli 7.2.3 -> 7.3.0 ng update @angular/cli
|
||||
@angular/core 7.2.2 -> 7.2.3 ng update @angular/core
|
||||
@angular/material 7.2.2 -> 7.3.1 ng update @angular/material
|
||||
rxjs 6.3.3 -> 6.4.0 ng update rxjs
|
||||
|
||||
|
||||
There might be additional packages that are outdated.
|
||||
Run "ng update --all" to try to update all at the same time.
|
||||
</code-example>
|
||||
|
||||
If you pass the command a set of libraries to update (or the `--all` flag), it updates those libraries, their peer dependencies, and the peer dependencies that depend on them.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
If there are inconsistencies (for example, if peer dependencies cannot be matched by a simple [semver](https://semver.io/) range), the command generates an error and does not change anything in the workspace.
|
||||
|
||||
We recommend that you do not force an update of all dependencies by default. Try updating specific dependencies first.
|
||||
|
||||
For more about how the `ng update` command works, see [Update Command](https://github.com/angular/angular-cli/blob/master/docs/specifications/update.md).
|
||||
|
||||
</div>
|
||||
|
||||
If you create a new version of your library that introduces potential breaking changes, you can provide an *update schematic* to enable the `ng update` command to automatically resolve any such changes in the project being updated.
|
||||
|
||||
For example, suppose you want to update the Angular Material library.
|
||||
|
||||
<code-example language="bash" linenums="false">
|
||||
ng update @angular/material
|
||||
</code-example>
|
||||
|
||||
This command updates both `@angular/material` and its dependency `@angular/cdk` in your workspace's `package.json`.
|
||||
If either package contains an update schematic that covers migration from the existing version to a new version, the command runs that schematic on your workspace.
|
@ -1749,447 +1749,6 @@ A consistent class and file name convention make these modules easy to spot and
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
|
||||
## Coding conventions
|
||||
|
||||
Have a consistent set of coding, naming, and whitespace conventions.
|
||||
|
||||
|
||||
|
||||
{@a 03-01}
|
||||
|
||||
### Classes
|
||||
|
||||
#### Style 03-01
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** use upper camel case when naming classes.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** Follows conventional thinking for class names.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** Classes can be instantiated and construct an instance.
|
||||
By convention, upper camel case indicates a constructable asset.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/03-01/app/core/exception.service.avoid.ts" region="example" header="app/shared/exception.service.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/03-01/app/core/exception.service.ts" region="example" header="app/shared/exception.service.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
|
||||
{@a 03-02}
|
||||
|
||||
### Constants
|
||||
|
||||
#### Style 03-02
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** declare variables with `const` if their values should not change during the application lifetime.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** Conveys to readers that the value is invariant.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** TypeScript helps enforce that intent by requiring immediate initialization and by
|
||||
preventing subsequent re-assignment.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-rule consider">
|
||||
|
||||
|
||||
|
||||
**Consider** spelling `const` variables in lower camel case.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** Lower camel case variable names (`heroRoutes`) are easier to read and understand
|
||||
than the traditional UPPER_SNAKE_CASE names (`HERO_ROUTES`).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** The tradition of naming constants in UPPER_SNAKE_CASE reflects
|
||||
an era before the modern IDEs that quickly reveal the `const` declaration.
|
||||
TypeScript prevents accidental reassignment.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** tolerate _existing_ `const` variables that are spelled in UPPER_SNAKE_CASE.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** The tradition of UPPER_SNAKE_CASE remains popular and pervasive,
|
||||
especially in third party modules.
|
||||
It is rarely worth the effort to change them at the risk of breaking existing code and documentation.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/03-02/app/core/data.service.ts" header="app/shared/data.service.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
|
||||
{@a 03-03}
|
||||
|
||||
### Interfaces
|
||||
|
||||
#### Style 03-03
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** name an interface using upper camel case.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-rule consider">
|
||||
|
||||
|
||||
|
||||
**Consider** naming an interface without an `I` prefix.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-rule consider">
|
||||
|
||||
|
||||
|
||||
**Consider** using a class instead of an interface for services and declarables (components, directives, and pipes).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-rule consider">
|
||||
|
||||
|
||||
|
||||
**Consider** using an interface for data models.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** <a href="https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines">TypeScript guidelines</a>
|
||||
discourage the `I` prefix.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** A class alone is less code than a _class-plus-interface_.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** A class can act as an interface (use `implements` instead of `extends`).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** An interface-class can be a provider lookup token in Angular dependency injection.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/03-03/app/core/hero-collector.service.avoid.ts" region="example" header="app/shared/hero-collector.service.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/03-03/app/core/hero-collector.service.ts" region="example" header="app/shared/hero-collector.service.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 03-04}
|
||||
|
||||
### Properties and methods
|
||||
|
||||
#### Style 03-04
|
||||
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** use lower camel case to name properties and methods.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-rule avoid">
|
||||
|
||||
|
||||
|
||||
**Avoid** prefixing private properties and methods with an underscore.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** Follows conventional thinking for properties and methods.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** JavaScript lacks a true private property or method.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** TypeScript tooling makes it easy to identify private vs. public properties and methods.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/03-04/app/core/toast.service.avoid.ts" region="example" header="app/shared/toast.service.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/03-04/app/core/toast.service.ts" region="example" header="app/shared/toast.service.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 03-06}
|
||||
|
||||
### Import line spacing
|
||||
|
||||
#### Style 03-06
|
||||
|
||||
|
||||
<div class="s-rule consider">
|
||||
|
||||
|
||||
|
||||
**Consider** leaving one empty line between third party imports and application imports.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-rule consider">
|
||||
|
||||
|
||||
|
||||
**Consider** listing import lines alphabetized by the module.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-rule consider">
|
||||
|
||||
|
||||
|
||||
**Consider** listing destructured imported symbols alphabetically.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** The empty line separates _your_ stuff from _their_ stuff.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** Alphabetizing makes it easier to read and locate symbols.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/03-06/app/heroes/shared/hero.service.avoid.ts" region="example" header="app/heroes/shared/hero.service.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/03-06/app/heroes/shared/hero.service.ts" region="example" header="app/heroes/shared/hero.service.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
|
||||
|
@ -1997,29 +1997,29 @@ You'll need this template operator when you turn on strict null checks. It's opt
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a built-in-template-functions}
|
||||
|
||||
## Built-in template functions
|
||||
|
||||
{@a any-type-cast-function}
|
||||
|
||||
## The `$any` type cast function (`$any( <expression> )`)
|
||||
### The `$any()` type cast function
|
||||
|
||||
Sometimes a binding expression will be reported as a type error and it is not possible or difficult
|
||||
to fully specify the type. To silence the error, you can use the `$any` cast function to cast
|
||||
the expression to [the `any` type](http://www.typescriptlang.org/docs/handbook/basic-types.html#any).
|
||||
Sometimes a binding expression triggers a type error during [AOT compilation](guide/aot-compiler) and it is not possible or difficult
|
||||
to fully specify the type. To silence the error, you can use the `$any()` cast function to cast
|
||||
the expression to [the `any` type](http://www.typescriptlang.org/docs/handbook/basic-types.html#any) as in the following example:
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.html" region="any-type-cast-function-1" header="src/app/app.component.html" linenums="false">
|
||||
<code-example path="built-in-template-functions/src/app/app.component.html" region="any-type-cast-function-1" header="src/app/app.component.html" linenums="false">
|
||||
</code-example>
|
||||
|
||||
In this example, when the Angular compiler turns your template into TypeScript code,
|
||||
it prevents TypeScript from reporting that `marker` is not a member of the `Hero`
|
||||
interface.
|
||||
When the Angular compiler turns this template into TypeScript code,
|
||||
it prevents TypeScript from reporting that `bestByDate` is not a member of the `item`
|
||||
object when it runs type checking on the template.
|
||||
|
||||
The `$any` cast function can be used in conjunction with `this` to allow access to undeclared members of
|
||||
The `$any()` cast function also works with `this` to allow access to undeclared members of
|
||||
the component.
|
||||
|
||||
<code-example path="template-syntax/src/app/app.component.html" region="any-type-cast-function-2" header="src/app/app.component.html" linenums="false">
|
||||
<code-example path="built-in-template-functions/src/app/app.component.html" region="any-type-cast-function-2" header="src/app/app.component.html" linenums="false">
|
||||
</code-example>
|
||||
|
||||
The `$any` cast function can be used anywhere in a binding expression where a method call is valid.
|
||||
|
||||
## Summary
|
||||
You've completed this survey of template syntax.
|
||||
Now it's time to put that knowledge to work on your own components and directives.
|
||||
The `$any()` cast function works anywhere in a binding expression where a method call is valid.
|
||||
|
@ -289,7 +289,7 @@ written without assistance from Angular testing utilities.
|
||||
#### Services with dependencies
|
||||
|
||||
Services often depend on other services that Angular injects into the constructor.
|
||||
In many cases, it easy to create and _inject_ these dependencies by hand while
|
||||
In many cases, it's easy to create and _inject_ these dependencies by hand while
|
||||
calling the service's constructor.
|
||||
|
||||
The `MasterService` is a simple example:
|
||||
@ -318,7 +318,7 @@ Prefer spies as they are usually the easiest way to mock services.
|
||||
|
||||
These standard testing techniques are great for unit testing services in isolation.
|
||||
|
||||
However, you almost always inject service into application classes using Angular
|
||||
However, you almost always inject services into application classes using Angular
|
||||
dependency injection and you should have tests that reflect that usage pattern.
|
||||
Angular testing utilities make it easy to investigate how injected services behave.
|
||||
|
||||
|
@ -44,14 +44,14 @@ src/
|
||||
index.html <i>app web page</i>
|
||||
main.ts <i>bootstrapper for client app</i>
|
||||
main.server.ts <i>* bootstrapper for server app</i>
|
||||
tsconfig.app.json <i>TypeScript client configuration</i>
|
||||
tsconfig.server.json <i>* TypeScript server configuration</i>
|
||||
tsconfig.spec.json <i>TypeScript spec configuration</i>
|
||||
style.css <i>styles for the app</i>
|
||||
app/ ... <i>application code</i>
|
||||
app.server.module.ts <i>* server-side application module</i>
|
||||
server.ts <i>* express web server</i>
|
||||
tsconfig.json <i>TypeScript client configuration</i>
|
||||
tsconfig.app.json <i>TypeScript client configuration</i>
|
||||
tsconfig.server.json <i>* TypeScript server configuration</i>
|
||||
tsconfig.spec.json <i>TypeScript spec configuration</i>
|
||||
package.json <i>npm configuration</i>
|
||||
webpack.server.config.js <i>* webpack server configuration</i>
|
||||
</code-example>
|
||||
|
@ -1,18 +1,18 @@
|
||||
# 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.
|
||||
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.
|
||||
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.
|
||||
* `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:
|
||||
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
|
||||
@ -23,11 +23,11 @@ projects
|
||||
</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.
|
||||
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.
|
||||
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.
|
||||
|
||||
@ -56,14 +56,14 @@ The following top-level configuration properties are available for each project,
|
||||
| `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. |
|
||||
| `schematics` | An object containing configuration defaults that customize the CLI command behavior for this project. See [Schematics Overview](guide/schematics). |
|
||||
| `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.
|
||||
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": {
|
||||
@ -90,11 +90,11 @@ Each target object specifies the `builder` for that target, which is the npm pac
|
||||
|
||||
* 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/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.
|
||||
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}
|
||||
@ -113,15 +113,15 @@ The `architect/build` section configures defaults for options of the `ng build`
|
||||
|
||||
### 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").
|
||||
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).
|
||||
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).
|
||||
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`](cli/config) command.
|
||||
|
||||
|
BIN
aio/content/images/bios/CaerusKaru.jpg
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
aio/content/images/bios/JiaLiPassion.jpg
Normal file
After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 14 KiB |
BIN
aio/content/images/bios/cexbrayat.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
aio/content/images/bios/denny.jpg
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
aio/content/images/bios/jbedard.png
Normal file
After Width: | Height: | Size: 100 KiB |
BIN
aio/content/images/bios/jennifer.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
aio/content/images/bios/judy.png
Normal file
After Width: | Height: | Size: 127 KiB |
BIN
aio/content/images/bios/justinschwartzenberger.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
aio/content/images/bios/kapunahele.jpg
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
aio/content/images/bios/luixaviles.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
aio/content/images/bios/sidd-ajmera.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
aio/content/images/bios/sreevani.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
aio/content/images/guide/schematics/collection-files.gif
Normal file
After Width: | Height: | Size: 38 KiB |
66
aio/content/marketing/analytics.md
Normal file
@ -0,0 +1,66 @@
|
||||
# Usage Metrics Gathering
|
||||
You can help the Angular Team to prioritize features and improvements by permitting the Angular
|
||||
team to send command-line command usage statistics to Google. The Angular Team does not collect
|
||||
usage statistics unless you explicitly opt in during the Angular CLI installation or upgrade.
|
||||
|
||||
## What is collected?
|
||||
Usage analytics include the commands and selected flags for each execution. Usage analytics may
|
||||
include the following information:
|
||||
|
||||
- Your operating system (Mac, Linux distribution, Windows) and its version.
|
||||
- Number of CPUs, amount of RAM.
|
||||
- Node and Angular CLI version (local version only).
|
||||
- How long each command took to initialize and execute.
|
||||
- Command name that was run.
|
||||
- For Schematics commands (add, generate, new and update), a list of whitelisted flags.
|
||||
- For build commands (build, serve), the number and size of bundles (initial and lazy),
|
||||
compilation units, the time it took to build and rebuild, and basic Angular-specific
|
||||
API usage. *This data is collected only if usage analytics gathering is enabled for
|
||||
the project.*
|
||||
- Error code of exceptions and crash data. No stack trace is collected.
|
||||
|
||||
Only Angular owned and developed schematics and builders are reported. Third-party schematics and
|
||||
builders do not send data to the Angular Team.
|
||||
|
||||
## Opting in
|
||||
When installing the Angular CLI or upgrading an existing version, you are prompted to allow global
|
||||
collection of usage statistics. If you say no or skip the prompt, no data is collected.
|
||||
|
||||
The first time a command affecting the project is run, you are prompted to allow collection of data
|
||||
related to the project. If you say no or skip the prompt, no data is collected for that project.
|
||||
|
||||
Starting with version 8, we added the `analytics` command to the CLI. You can change your opt-in
|
||||
decision at any time using this command.
|
||||
|
||||
### Disabling usage analytics
|
||||
To disable analytics gathering, run the following command:
|
||||
|
||||
```bash
|
||||
# Disable all usage analytics.
|
||||
ng analytics off
|
||||
|
||||
# Disable project-specific usage analytics.
|
||||
ng analytics project off
|
||||
```
|
||||
|
||||
### Enabling usage analytics
|
||||
To enable usage analytics, run the following command:
|
||||
|
||||
```bash
|
||||
# Enable all usage analytics.
|
||||
ng analytics on
|
||||
|
||||
# Enable project-specific usage analytics.
|
||||
ng analytics project on
|
||||
```
|
||||
|
||||
### Prompting
|
||||
To prompt the user again about usage analytics, run the following command:
|
||||
|
||||
```bash
|
||||
# Prompt for all usage analytics.
|
||||
ng analytics prompt
|
||||
|
||||
# Prompt for project-specific usage analytics.
|
||||
ng analytics project prompt
|
||||
```
|
@ -659,5 +659,100 @@
|
||||
"website": "http://www.samjulien.com/",
|
||||
"bio": "Sam Julien builds software, articles, video courses, and campfires. A developer, speaker, writer, and GDE in the Pacific Northwest, Sam's favorite thing in the world is changing someone's life by teaching them to code.",
|
||||
"group": "GDE"
|
||||
},
|
||||
"JiaLiPassion": {
|
||||
"name": "JiaLi Passion",
|
||||
"group": "Collaborator",
|
||||
"mentor": "mhevery",
|
||||
"picture": "JiaLiPassion.jpg",
|
||||
"bio": "A programmer with passion, angular/zone.js guy! Web frontend engineer @sylabs"
|
||||
},
|
||||
"cexbrayat": {
|
||||
"name": "Cédric Exbrayat",
|
||||
"mentor": "petebacondarwin",
|
||||
"group": "Collaborator",
|
||||
"picture": "cexbrayat.jpg",
|
||||
"bio": "Author of `Become a ninja with Angular (2+)` https://books.ninja-squad.com/angular - Angular trainer and @Ninja-Squad co-founder"
|
||||
},
|
||||
"CaerusKaru": {
|
||||
"name": "Adam Plumer",
|
||||
"group": "Collaborator",
|
||||
"mentor": "vikerman",
|
||||
"picture": "CaerusKaru.jpg"
|
||||
},
|
||||
"jbedard": {
|
||||
"name": "Jason Bedard",
|
||||
"group": "Collaborator",
|
||||
"mentor": "kyliau",
|
||||
"picture": "jbedard.png"
|
||||
},
|
||||
"jschwarty": {
|
||||
"name": "Justin Schwartzenberger",
|
||||
"picture": "justinschwartzenberger.jpg",
|
||||
"twitter": "schwarty",
|
||||
"website": "https://schwarty.com",
|
||||
"bio": "Justin (aka Schwarty) is a Google Developer Expert in Web Technologies and Angular, the host and maintainer of the weekly AngularAir live video broadcast, educator, writer and content creator. He has Angular courses available on LinkedIn Learning and Pluralsight and loves passing on years of full stack development knowledge to help empower others to find their inner awesomeness!",
|
||||
"group": "GDE"
|
||||
},
|
||||
"brandonroberts": {
|
||||
"name": "Brandon Roberts",
|
||||
"picture": "brandonroberts.jpg",
|
||||
"twitter": "brandontroberts",
|
||||
"website": "https://brandonroberts.dev",
|
||||
"bio": "Brandon is a developer and technical writer working on guides, tutorials, application development, and infrastructure for the Angular docs. He is also a maintainer of the NgRx project, building reactive libraries for Angular.",
|
||||
"group": "Angular",
|
||||
"lead": "dennispbrown"
|
||||
},
|
||||
"chembu": {
|
||||
"name": "Sreevani Sreejith",
|
||||
"picture": "sreevani.jpg",
|
||||
"bio": "Sreevani is a tech writer with prior programming experience. She writes documentation for the Angular framework team. Outside of work, she likes practicing yoga, honing her skills on classical dance forms, and baking cakes.",
|
||||
"group": "Angular",
|
||||
"lead": "dennispbrown"
|
||||
},
|
||||
"dennispbrown": {
|
||||
"name": "Denny Brown",
|
||||
"picture": "denny.jpg",
|
||||
"bio": "Denny is founder of Expert Support, a professional services firm specializing in technical communication, and leads the Angular technical writing team. His lifelong passion has been to reduce the time and effort required to understand complex technical information. Early on, he was Associate Chairman of the Computer Science Department at Stanford, where he taught introductory courses in programming. He also plays old-timers baseball in local leagues and national tournaments.",
|
||||
"group": "Angular",
|
||||
"lead": "bradlygreen"
|
||||
},
|
||||
"jbogarthyde": {
|
||||
"name": "Judy Bogart",
|
||||
"picture": "judy.png",
|
||||
"group": "Angular",
|
||||
"lead": "dennispbrown"
|
||||
},
|
||||
"jenniferfell": {
|
||||
"name": "Jennifer Fell",
|
||||
"picture": "jennifer.jpg",
|
||||
"website": "http://silverpath.org",
|
||||
"bio": "Jennifer is a technical content strategist, architect, designer, and writer. As lead of the Angular docs team, she's always interested in learning more about how developers learn and use Angular. Her offline persona is a horsewoman in Idaho.",
|
||||
"group": "Angular",
|
||||
"lead": "dennispbrown"
|
||||
},
|
||||
"kapunahelewong": {
|
||||
"name": "Kapunahele Wong",
|
||||
"picture": "kapunahele.jpg",
|
||||
"twitter": "kapunahele",
|
||||
"bio": "Kapunahele is a developer and Angular fan who works on the Angular docs writing guides and developing example apps. She also enjoys Native Hawaiian practices, textile arts, and marveling at little, inconspicuous plants growing in forgotten places outdoors.",
|
||||
"group": "Angular",
|
||||
"lead": "dennispbrown"
|
||||
},
|
||||
"luixaviles": {
|
||||
"name": "Luis Aviles",
|
||||
"picture": "luixaviles.jpg",
|
||||
"twitter": "luixaviles",
|
||||
"website": "https://luixaviles.com",
|
||||
"bio": "Luis is an enthusiast of Open Source software and communities, as well as being a public speaker, a technology trainer and an author of courses and technical articles. He is the organizer of the Angular Bolivia community and NG Bolivia conference. When he's not coding, Luis is reading about Astronomy or nerding about outer space, photography or even doing Astrophotography.",
|
||||
"group": "GDE"
|
||||
},
|
||||
"siddajmera": {
|
||||
"name": "Siddharth Ajmera",
|
||||
"picture": "sidd-ajmera.jpg",
|
||||
"twitter": "SiddAjmera",
|
||||
"website": "https://webstackup.com/",
|
||||
"bio": "Siddharth is a Full Stack JavaScript Developer and a GDE in Angular. He's passionate about sharing his knowledge on Angular, Firebase and the Web in general. He's the organizer of WebStack, a local community of developers focused on Web, Mobile, Voice and Server related technologies in general. WebStack hosts free monthly meetups every 2nd or 3rd Saturday of the month. Siddharth is also an avid photographer and loves traveling. Find him anywhere on the Web with `SiddAjmera`.",
|
||||
"group": "GDE"
|
||||
}
|
||||
}
|
||||
}
|
@ -31,6 +31,12 @@
|
||||
<td>London, UK</td>
|
||||
<td>September 19-20, 2019</td>
|
||||
</tr>
|
||||
<!-- NG-DE 2019-->
|
||||
<tr>
|
||||
<th><a href="https://ng-de.org/" title="NG-DE">NG-DE</a></th>
|
||||
<td>Berlin, Germany</td>
|
||||
<td>August 29th workshops, 30-31 conference, 2019</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
@ -439,6 +439,11 @@
|
||||
"title": "Getting Started",
|
||||
"tooltip": "Enabling the service worker in a CLI project and observing behavior in the browser."
|
||||
},
|
||||
{
|
||||
"url": "guide/app-shell",
|
||||
"title": "App Shell",
|
||||
"tooltip": "Enabling the App Shell in a CLI project."
|
||||
},
|
||||
{
|
||||
"url": "guide/service-worker-communications",
|
||||
"title": "Service Worker Communication",
|
||||
@ -503,6 +508,27 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Schematics",
|
||||
"tooltip": "Understanding schematics.",
|
||||
"children": [
|
||||
{
|
||||
"url": "guide/schematics",
|
||||
"title": "Schematics Overview",
|
||||
"tooltip": "Understand how schematics are used in Angular."
|
||||
},
|
||||
{
|
||||
"url": "guide/schematics-authoring",
|
||||
"title": "Authoring Schematics",
|
||||
"tooltip": "Understand the structure of a schematic."
|
||||
},
|
||||
{
|
||||
"url": "guide/schematics-for-libraries",
|
||||
"title": "Schematics for Libraries",
|
||||
"tooltip": "Use schematics to integrate your library with the Angular CLI."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"url": "guide/ivy",
|
||||
"title": "Angular Ivy",
|
||||
@ -629,6 +655,11 @@
|
||||
"title": "Overview",
|
||||
"tooltip": "An introduction to the CLI tool, commands, and syntax.",
|
||||
"url": "cli"
|
||||
},
|
||||
{
|
||||
"title": "Usage Analytics",
|
||||
"tooltip": "For administrators, guide to gathering usage analytics from your users.",
|
||||
"url": "cli/usage-analytics-gathering"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -667,6 +698,11 @@
|
||||
"url": "https://blog.angular.io/",
|
||||
"title": "Blog",
|
||||
"tooltip": "Angular Blog"
|
||||
},
|
||||
{
|
||||
"url": "analytics",
|
||||
"title": "Usage Analytics",
|
||||
"tooltip": "Angular Usage Analytics"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -761,4 +797,4 @@
|
||||
"url": "https://v2.angular.io"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -267,7 +267,7 @@ Use the CLI to create the `MessagesComponent`.
|
||||
ng generate component messages
|
||||
</code-example>
|
||||
|
||||
The CLI creates the component files in the `src/app/messages` folder and declare `MessagesComponent` in `AppModule`.
|
||||
The CLI creates the component files in the `src/app/messages` folder and declares the `MessagesComponent` in `AppModule`.
|
||||
|
||||
Modify the `AppComponent` template to display the generated `MessagesComponent`
|
||||
|
||||
|
@ -17,9 +17,9 @@
|
||||
"build": "yarn ~~build",
|
||||
"prebuild-local": "yarn setup-local",
|
||||
"build-local": "yarn ~~build",
|
||||
"prebuild-with-ivy": "yarn setup-local && yarn ivy-ngcc --formats fesm2015 fesm5",
|
||||
"prebuild-with-ivy": "yarn setup-local && yarn ivy-ngcc --properties module es2015",
|
||||
"build-with-ivy": "node scripts/build-with-ivy",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js c883c3d0b",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 18d979cdc",
|
||||
"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",
|
||||
@ -93,7 +93,6 @@
|
||||
"classlist.js": "^1.1.20150312",
|
||||
"core-js": "^2.4.1",
|
||||
"rxjs": "^6.3.0",
|
||||
"tslib": "^1.9.0",
|
||||
"zone.js": "^0.8.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -156,8 +155,9 @@
|
||||
"shelljs": "^0.7.7",
|
||||
"tree-kill": "^1.1.0",
|
||||
"ts-node": "^3.3.0",
|
||||
"tslib": "^1.9.0",
|
||||
"tslint": "~5.9.1",
|
||||
"typescript": "^3.2.2",
|
||||
"typescript": "~3.3.3333",
|
||||
"uglify-js": "^3.0.15",
|
||||
"unist-util-filter": "^0.2.1",
|
||||
"unist-util-source": "^1.0.1",
|
||||
@ -169,4 +169,4 @@
|
||||
"xregexp": "^4.0.0",
|
||||
"yargs": "^7.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime": 3713,
|
||||
"main": 500343,
|
||||
"main": 509261,
|
||||
"polyfills": 53926
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
{
|
||||
"scripts": [
|
||||
{ "name": "ng", "command": "ng" },
|
||||
{ "name": "build", "command": "ng build --prod" },
|
||||
{ "name": "build:lib", "command": "ng build my-lib" },
|
||||
{ "name": "start", "command": "ng serve" },
|
||||
{ "name": "test", "command": "ng test" },
|
||||
{ "name": "lint", "command": "ng lint" },
|
||||
{ "name": "e2e", "command": "ng e2e" }
|
||||
],
|
||||
"dependencies": [],
|
||||
"devDependencies": [
|
||||
"@angular-devkit/build-angular",
|
||||
"@angular-devkit/build-ng-packagr",
|
||||
"@angular/cli",
|
||||
"@types/jasminewd2",
|
||||
"jasmine-spec-reporter",
|
||||
"karma-coverage-istanbul-reporter",
|
||||
"ng-packagr",
|
||||
"tsickle",
|
||||
"tslib",
|
||||
"ts-node"
|
||||
]
|
||||
}
|
@ -102,7 +102,9 @@ class ExampleZipper {
|
||||
'src/typings.d.ts',
|
||||
'src/environments/**/*',
|
||||
'src/tsconfig.*',
|
||||
'src/tslint.*'
|
||||
'src/tslint.*',
|
||||
// Only ignore root package.json
|
||||
'!package.json'
|
||||
];
|
||||
var alwaysExcludes = [
|
||||
'!**/bs-config.e2e.json',
|
||||
@ -110,7 +112,6 @@ class ExampleZipper {
|
||||
'!**/*zipper.*',
|
||||
'!**/systemjs.config.js',
|
||||
'!**/npm-debug.log',
|
||||
'!**/package.json',
|
||||
'!**/example-config.json',
|
||||
'!**/wallaby.js',
|
||||
// AoT related files
|
||||
|
@ -12,82 +12,43 @@ const EXAMPLES_BASE_PATH = path.resolve(__dirname, '../../content/examples');
|
||||
|
||||
const BOILERPLATE_PATHS = {
|
||||
cli: [
|
||||
'src/environments/environment.prod.ts',
|
||||
'src/environments/environment.ts',
|
||||
'src/assets/.gitkeep',
|
||||
'src/browserslist',
|
||||
'src/favicon.ico',
|
||||
'src/karma.conf.js',
|
||||
'src/polyfills.ts',
|
||||
'src/test.ts',
|
||||
'src/tsconfig.app.json',
|
||||
'src/tsconfig.spec.json',
|
||||
'src/tslint.json',
|
||||
'e2e/src/app.po.ts',
|
||||
'e2e/protractor.conf.js',
|
||||
'e2e/tsconfig.e2e.json',
|
||||
'.editorconfig',
|
||||
'angular.json',
|
||||
'package.json',
|
||||
'tsconfig.json',
|
||||
'tslint.json'
|
||||
'src/environments/environment.prod.ts', 'src/environments/environment.ts',
|
||||
'src/assets/.gitkeep', 'src/browserslist', 'src/favicon.ico', 'src/karma.conf.js',
|
||||
'src/polyfills.ts', 'src/test.ts', 'src/tsconfig.app.json', 'src/tsconfig.spec.json',
|
||||
'src/tslint.json', 'e2e/src/app.po.ts', 'e2e/protractor.conf.js', 'e2e/tsconfig.e2e.json',
|
||||
'.editorconfig', 'angular.json', 'package.json', 'tsconfig.json', 'tslint.json'
|
||||
],
|
||||
systemjs: [
|
||||
'src/systemjs-angular-loader.js',
|
||||
'src/systemjs.config.js',
|
||||
'src/tsconfig.json',
|
||||
'bs-config.json',
|
||||
'bs-config.e2e.json',
|
||||
'package.json',
|
||||
'tslint.json'
|
||||
'src/systemjs-angular-loader.js', 'src/systemjs.config.js', 'src/tsconfig.json',
|
||||
'bs-config.json', 'bs-config.e2e.json', 'package.json', 'tslint.json'
|
||||
],
|
||||
common: [
|
||||
'src/styles.css'
|
||||
]
|
||||
common: ['src/styles.css']
|
||||
};
|
||||
|
||||
// All paths in this tool are relative to the current boilerplate folder, i.e boilerplate/i18n
|
||||
// This maps the CLI files that exists in a parent folder
|
||||
const cliRelativePath = BOILERPLATE_PATHS.cli.map(file => `../cli/${file}`);
|
||||
|
||||
BOILERPLATE_PATHS.elements = [
|
||||
...cliRelativePath,
|
||||
'tsconfig.json'
|
||||
];
|
||||
BOILERPLATE_PATHS.elements = [...cliRelativePath, 'tsconfig.json'];
|
||||
|
||||
BOILERPLATE_PATHS.i18n = [
|
||||
...cliRelativePath,
|
||||
'angular.json',
|
||||
'package.json'
|
||||
];
|
||||
BOILERPLATE_PATHS.i18n = [...cliRelativePath, 'angular.json', 'package.json'];
|
||||
|
||||
BOILERPLATE_PATHS['service-worker'] = [
|
||||
...cliRelativePath,
|
||||
'angular.json',
|
||||
'package.json'
|
||||
];
|
||||
BOILERPLATE_PATHS['service-worker'] = [...cliRelativePath, 'angular.json', 'package.json'];
|
||||
|
||||
BOILERPLATE_PATHS.testing = [
|
||||
BOILERPLATE_PATHS.testing = [...cliRelativePath, 'angular.json'];
|
||||
|
||||
BOILERPLATE_PATHS.universal = [...cliRelativePath, 'angular.json', 'package.json'];
|
||||
|
||||
BOILERPLATE_PATHS.ivy = {
|
||||
systemjs: ['rollup-config.js', 'tsconfig-aot.json'],
|
||||
cli: ['src/tsconfig.app.json']
|
||||
};
|
||||
|
||||
BOILERPLATE_PATHS.schematics = [
|
||||
...cliRelativePath,
|
||||
'angular.json'
|
||||
];
|
||||
|
||||
BOILERPLATE_PATHS.universal = [
|
||||
...cliRelativePath,
|
||||
'angular.json',
|
||||
'package.json'
|
||||
];
|
||||
|
||||
BOILERPLATE_PATHS.ivy = {
|
||||
systemjs: [
|
||||
'rollup-config.js',
|
||||
'tsconfig-aot.json'
|
||||
],
|
||||
cli: [
|
||||
'src/tsconfig.app.json'
|
||||
]
|
||||
};
|
||||
|
||||
const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
|
||||
|
||||
class ExampleBoilerPlate {
|
||||
@ -96,20 +57,19 @@ class ExampleBoilerPlate {
|
||||
*/
|
||||
add(ivy = false) {
|
||||
// Get all the examples folders, indicated by those that contain a `example-config.json` file
|
||||
const exampleFolders = this.getFoldersContaining(EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, 'node_modules');
|
||||
const exampleFolders =
|
||||
this.getFoldersContaining(EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, 'node_modules');
|
||||
|
||||
if (!fs.existsSync(SHARED_NODE_MODULES_PATH)) {
|
||||
throw new Error(`The shared node_modules folder for the examples (${SHARED_NODE_MODULES_PATH}) is missing.\n` +
|
||||
`Perhaps you need to run "yarn example-use-npm" or "yarn example-use-local" to install the dependencies?`);
|
||||
throw new Error(
|
||||
`The shared node_modules folder for the examples (${SHARED_NODE_MODULES_PATH}) is missing.\n` +
|
||||
`Perhaps you need to run "yarn example-use-npm" or "yarn example-use-local" to install the dependencies?`);
|
||||
}
|
||||
|
||||
if (ivy) {
|
||||
// We only need the "fesm5" bundles as the CLI webpack build does not need
|
||||
// any other formats for building and serving. Ngcc currently only updates
|
||||
// the module typings if we specified an "es2015" format. This means that
|
||||
// we also need to build with "fesm2015" in order to get updated typings
|
||||
// which are needed for compilation.
|
||||
shelljs.exec(`yarn --cwd ${SHARED_PATH} ivy-ngcc --formats fesm2015 fesm5`);
|
||||
// any other formats for building and serving.
|
||||
shelljs.exec(`yarn --cwd ${SHARED_PATH} ivy-ngcc --properties module`);
|
||||
}
|
||||
|
||||
exampleFolders.forEach(exampleFolder => {
|
||||
@ -123,16 +83,20 @@ class ExampleBoilerPlate {
|
||||
const boilerPlateBasePath = path.resolve(BOILERPLATE_BASE_PATH, boilerPlateType);
|
||||
|
||||
// Copy the boilerplate specific files
|
||||
BOILERPLATE_PATHS[boilerPlateType].forEach(filePath => this.copyFile(boilerPlateBasePath, exampleFolder, filePath));
|
||||
BOILERPLATE_PATHS[boilerPlateType].forEach(
|
||||
filePath => this.copyFile(boilerPlateBasePath, exampleFolder, filePath));
|
||||
|
||||
// Copy the boilerplate common files
|
||||
BOILERPLATE_PATHS.common.forEach(filePath => this.copyFile(BOILERPLATE_COMMON_BASE_PATH, exampleFolder, filePath));
|
||||
BOILERPLATE_PATHS.common.forEach(
|
||||
filePath => this.copyFile(BOILERPLATE_COMMON_BASE_PATH, exampleFolder, filePath));
|
||||
|
||||
// Copy Ivy specific files
|
||||
if (ivy) {
|
||||
const ivyBoilerPlateType = boilerPlateType === 'systemjs' ? 'systemjs' : 'cli';
|
||||
const ivyBoilerPlateBasePath = path.resolve(BOILERPLATE_BASE_PATH, 'ivy', ivyBoilerPlateType);
|
||||
BOILERPLATE_PATHS.ivy[ivyBoilerPlateType].forEach(filePath => this.copyFile(ivyBoilerPlateBasePath, exampleFolder, filePath));
|
||||
const ivyBoilerPlateBasePath =
|
||||
path.resolve(BOILERPLATE_BASE_PATH, 'ivy', ivyBoilerPlateType);
|
||||
BOILERPLATE_PATHS.ivy[ivyBoilerPlateType].forEach(
|
||||
filePath => this.copyFile(ivyBoilerPlateBasePath, exampleFolder, filePath));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -140,23 +104,20 @@ class ExampleBoilerPlate {
|
||||
/**
|
||||
* Remove all the boilerplate files from all the examples
|
||||
*/
|
||||
remove() {
|
||||
shelljs.exec('git clean -xdfq', { cwd: EXAMPLES_BASE_PATH });
|
||||
}
|
||||
remove() { shelljs.exec('git clean -xdfq', {cwd: EXAMPLES_BASE_PATH}); }
|
||||
|
||||
main() {
|
||||
yargs
|
||||
.usage('$0 <cmd> [args]')
|
||||
.command('add', 'add the boilerplate to each example', (yrgs) => this.add(yrgs.argv.ivy))
|
||||
.command('remove', 'remove the boilerplate from each example', () => this.remove())
|
||||
.demandCommand(1, 'Please supply a command from the list above')
|
||||
.argv;
|
||||
yargs.usage('$0 <cmd> [args]')
|
||||
.command('add', 'add the boilerplate to each example', (yrgs) => this.add(yrgs.argv.ivy))
|
||||
.command('remove', 'remove the boilerplate from each example', () => this.remove())
|
||||
.demandCommand(1, 'Please supply a command from the list above')
|
||||
.argv;
|
||||
}
|
||||
|
||||
getFoldersContaining(basePath, filename, ignore) {
|
||||
const pattern = path.resolve(basePath, '**', filename);
|
||||
const ignorePattern = path.resolve(basePath, '**', ignore, '**');
|
||||
return glob.sync(pattern, { ignore: [ignorePattern] }).map(file => path.dirname(file));
|
||||
return glob.sync(pattern, {ignore: [ignorePattern]}).map(file => path.dirname(file));
|
||||
}
|
||||
|
||||
copyFile(sourceFolder, destinationFolder, filePath) {
|
||||
@ -166,13 +127,11 @@ class ExampleBoilerPlate {
|
||||
filePath = this.normalizePath(filePath);
|
||||
|
||||
const destinationPath = path.resolve(destinationFolder, filePath);
|
||||
fs.copySync(sourcePath, destinationPath, { overwrite: true });
|
||||
fs.copySync(sourcePath, destinationPath, {overwrite: true});
|
||||
fs.chmodSync(destinationPath, 444);
|
||||
}
|
||||
|
||||
loadJsonFile(filePath) {
|
||||
return fs.readJsonSync(filePath, { throws: false }) || {};
|
||||
}
|
||||
loadJsonFile(filePath) { return fs.readJsonSync(filePath, {throws: false}) || {}; }
|
||||
|
||||
normalizePath(filePath) {
|
||||
// transform for example ../cli/src/tsconfig.app.json to src/tsconfig.app.json
|
||||
|
@ -6,11 +6,13 @@ import uglify from 'rollup-plugin-uglify'
|
||||
|
||||
//paths are relative to the execution path
|
||||
export default {
|
||||
entry: 'app/main.js',
|
||||
dest: 'aot/dist/build.js', // output a single application bundle
|
||||
sourceMap: true,
|
||||
sourceMapFile: 'aot/dist/build.js.map',
|
||||
format: 'iife',
|
||||
input: 'app/main.js',
|
||||
output: {
|
||||
file: 'aot/dist/build.js', // output a single application bundle
|
||||
format: 'iife',
|
||||
sourcemap: true,
|
||||
sourcemapFile: 'aot/dist/build.js.map'
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve({ jsnext: true, module: true }),
|
||||
commonjs({
|
||||
|
170
aio/tools/examples/shared/boilerplate/schematics/angular.json
Normal file
@ -0,0 +1,170 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"angular.io-example": {
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"prefix": "app",
|
||||
"schematics": {},
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "angular.io-example:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "angular.io-example:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "angular.io-example:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"karmaConfig": "src/karma.conf.js",
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"angular.io-example-e2e": {
|
||||
"root": "e2e/",
|
||||
"projectType": "application",
|
||||
"prefix": "",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "e2e/protractor.conf.js",
|
||||
"devServerTarget": "angular.io-example:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "angular.io-example:serve:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": "e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"my-lib": {
|
||||
"root": "projects/my-lib",
|
||||
"sourceRoot": "projects/my-lib/src",
|
||||
"projectType": "library",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "projects/my-lib/tsconfig.lib.json",
|
||||
"project": "projects/my-lib/ng-package.json"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/my-lib/src/test.ts",
|
||||
"tsConfig": "projects/my-lib/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/my-lib/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/my-lib/tsconfig.lib.json",
|
||||
"projects/my-lib/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "angular.io-example"
|
||||
}
|
@ -74,9 +74,9 @@
|
||||
"phantomjs-prebuilt": "^2.1.7",
|
||||
"protractor": "~5.4.0",
|
||||
"rimraf": "^2.5.4",
|
||||
"rollup": "^0.41.6",
|
||||
"rollup-plugin-commonjs": "^8.0.2",
|
||||
"rollup-plugin-node-resolve": "2.0.0",
|
||||
"rollup": "^1.1.0",
|
||||
"rollup-plugin-commonjs": "^9.2.1",
|
||||
"rollup-plugin-node-resolve": "^4.0.0",
|
||||
"rollup-plugin-uglify": "^1.0.1",
|
||||
"source-map-explorer": "^1.3.2",
|
||||
"ts-loader": "^4.2.0",
|
||||
|
@ -417,6 +417,11 @@
|
||||
"@types/express" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/estree@0.0.39":
|
||||
version "0.0.39"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
|
||||
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
|
||||
|
||||
"@types/express-serve-static-core@*":
|
||||
version "4.0.55"
|
||||
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.0.55.tgz#f53868838a955f98b380819ec9134f5df7d9482f"
|
||||
@ -457,6 +462,11 @@
|
||||
version "8.0.47"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.47.tgz#968e596f91acd59069054558a00708c445ca30c2"
|
||||
|
||||
"@types/node@^11.9.5":
|
||||
version "11.11.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.3.tgz#7c6b0f8eaf16ae530795de2ad1b85d34bf2f5c58"
|
||||
integrity sha512-wp6IOGu1lxsfnrD+5mX6qwSwWuqsdkKKxTN4aQc4wByHAKZJf9/D4KXPQ1POUjEbnCP5LMggB0OEFNY9OTsMqg==
|
||||
|
||||
"@types/node@^6.0.46":
|
||||
version "6.0.90"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.90.tgz#0ed74833fa1b73dcdb9409dcb1c97ec0a8b13b02"
|
||||
@ -679,7 +689,7 @@ acorn-dynamic-import@^3.0.0:
|
||||
dependencies:
|
||||
acorn "^5.0.0"
|
||||
|
||||
acorn@^5.0.0, acorn@^5.1.2:
|
||||
acorn@^5.0.0:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7"
|
||||
|
||||
@ -687,6 +697,11 @@ acorn@^5.6.2:
|
||||
version "5.7.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.2.tgz#91fa871883485d06708800318404e72bfb26dcc5"
|
||||
|
||||
acorn@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f"
|
||||
integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==
|
||||
|
||||
adm-zip@^0.4.7:
|
||||
version "0.4.7"
|
||||
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.7.tgz#8606c2cbf1c426ce8c8ec00174447fd49b6eafc1"
|
||||
@ -1305,12 +1320,6 @@ brorand@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
||||
|
||||
browser-resolve@^1.11.0:
|
||||
version "1.11.2"
|
||||
resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce"
|
||||
dependencies:
|
||||
resolve "1.1.7"
|
||||
|
||||
browser-sync-client@2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-2.5.1.tgz#ec1ad69a49c2e2d4b645b18b1c06c29b3d9af8eb"
|
||||
@ -1459,10 +1468,15 @@ buffer@^4.3.0:
|
||||
ieee754 "^1.1.4"
|
||||
isarray "^1.0.0"
|
||||
|
||||
builtin-modules@^1.0.0, builtin-modules@^1.1.0, builtin-modules@^1.1.1:
|
||||
builtin-modules@^1.0.0, builtin-modules@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
|
||||
|
||||
builtin-modules@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.0.0.tgz#1e587d44b006620d90286cc7a9238bbc6129cab1"
|
||||
integrity sha512-hMIeU4K2ilbXV6Uv93ZZ0Avg/M91RaKXucQ+4me2Do1txxBDyDZWCBa5bJSLqoNTRpXTLwEzIk1KmloenDDjhg==
|
||||
|
||||
builtin-status-codes@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
|
||||
@ -2705,13 +2719,15 @@ estraverse@^4.1.0, estraverse@^4.1.1:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
|
||||
|
||||
estree-walker@^0.3.0:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa"
|
||||
estree-walker@^0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.2.tgz#d3850be7529c9580d815600b53126515e146dd39"
|
||||
integrity sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==
|
||||
|
||||
estree-walker@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.0.tgz#aae3b57c42deb8010e349c892462f0e71c5dd1aa"
|
||||
estree-walker@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.0.tgz#5d865327c44a618dde5699f763891ae31f257dae"
|
||||
integrity sha512-peq1RfVAVzr3PU/jL31RaOjUKLoZJpObQWJJ+LgfcxDUifyLZ1RjPQZTl0pzj2uJ45b7A7XpyppXvxdEqzo4rw==
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.2"
|
||||
@ -4086,6 +4102,11 @@ is-glob@^4.0.0:
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-module@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
|
||||
integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
|
||||
|
||||
is-number-like@^1.0.3:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/is-number-like/-/is-number-like-1.0.8.tgz#2e129620b50891042e44e9bbbb30593e75cfbbe3"
|
||||
@ -4813,18 +4834,19 @@ lru-cache@^5.1.1:
|
||||
dependencies:
|
||||
yallist "^3.0.2"
|
||||
|
||||
magic-string@^0.22.4:
|
||||
version "0.22.4"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.4.tgz#31039b4e40366395618c1d6cf8193c53917475ff"
|
||||
dependencies:
|
||||
vlq "^0.2.1"
|
||||
|
||||
magic-string@^0.25.0:
|
||||
version "0.25.0"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.0.tgz#1f3696f9931ff0a1ed4c132250529e19cad6759b"
|
||||
dependencies:
|
||||
sourcemap-codec "^1.4.1"
|
||||
|
||||
magic-string@^0.25.1:
|
||||
version "0.25.2"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.2.tgz#139c3a729515ec55e96e69e82a11fe890a293ad9"
|
||||
integrity sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==
|
||||
dependencies:
|
||||
sourcemap-codec "^1.4.4"
|
||||
|
||||
make-dir@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51"
|
||||
@ -4933,7 +4955,7 @@ methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
|
||||
micromatch@2.3.11, micromatch@^2.1.5, micromatch@^2.3.11:
|
||||
micromatch@2.3.11, micromatch@^2.1.5:
|
||||
version "2.3.11"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
|
||||
dependencies:
|
||||
@ -4951,6 +4973,24 @@ micromatch@2.3.11, micromatch@^2.1.5, micromatch@^2.3.11:
|
||||
parse-glob "^3.0.4"
|
||||
regex-cache "^0.4.2"
|
||||
|
||||
micromatch@^3.1.10, micromatch@^3.1.8, micromatch@^3.1.9:
|
||||
version "3.1.10"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
|
||||
dependencies:
|
||||
arr-diff "^4.0.0"
|
||||
array-unique "^0.3.2"
|
||||
braces "^2.3.1"
|
||||
define-property "^2.0.2"
|
||||
extend-shallow "^3.0.2"
|
||||
extglob "^2.0.4"
|
||||
fragment-cache "^0.2.1"
|
||||
kind-of "^6.0.2"
|
||||
nanomatch "^1.2.9"
|
||||
object.pick "^1.3.0"
|
||||
regex-not "^1.0.0"
|
||||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.2"
|
||||
|
||||
micromatch@^3.1.4:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.5.tgz#d05e168c206472dfbca985bfef4f57797b4cd4ba"
|
||||
@ -4969,24 +5009,6 @@ micromatch@^3.1.4:
|
||||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
micromatch@^3.1.8, micromatch@^3.1.9:
|
||||
version "3.1.10"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
|
||||
dependencies:
|
||||
arr-diff "^4.0.0"
|
||||
array-unique "^0.3.2"
|
||||
braces "^2.3.1"
|
||||
define-property "^2.0.2"
|
||||
extend-shallow "^3.0.2"
|
||||
extglob "^2.0.4"
|
||||
fragment-cache "^0.2.1"
|
||||
kind-of "^6.0.2"
|
||||
nanomatch "^1.2.9"
|
||||
object.pick "^1.3.0"
|
||||
regex-not "^1.0.0"
|
||||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.2"
|
||||
|
||||
miller-rabin@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
|
||||
@ -5929,6 +5951,11 @@ path-parse@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
|
||||
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
||||
|
||||
path-to-regexp@0.1.7:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
|
||||
@ -6632,16 +6659,23 @@ resolve-url@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||
|
||||
resolve@1.1.7, resolve@1.1.x:
|
||||
resolve@1.1.x:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
|
||||
|
||||
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.4.0:
|
||||
resolve@^1.1.6, resolve@^1.1.7:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
|
||||
dependencies:
|
||||
path-parse "^1.0.5"
|
||||
|
||||
resolve@^1.10.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba"
|
||||
integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==
|
||||
dependencies:
|
||||
path-parse "^1.0.6"
|
||||
|
||||
resolve@^1.3.2:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3"
|
||||
@ -6697,23 +6731,24 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
hash-base "^2.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
rollup-plugin-commonjs@^8.0.2:
|
||||
version "8.2.5"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.2.5.tgz#924421278a6f879fd976b2ef1a28391b1e4f2a6e"
|
||||
rollup-plugin-commonjs@^9.2.1:
|
||||
version "9.2.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.2.1.tgz#bb151ca8fa23600c7a03e25f9f0a45b1ee922dac"
|
||||
integrity sha512-X0A/Cp/t+zbONFinBhiTZrfuUaVwRIp4xsbKq/2ohA2CDULa/7ONSJTelqxon+Vds2R2t2qJTqJQucKUC8GKkw==
|
||||
dependencies:
|
||||
acorn "^5.1.2"
|
||||
estree-walker "^0.5.0"
|
||||
magic-string "^0.22.4"
|
||||
resolve "^1.4.0"
|
||||
rollup-pluginutils "^2.0.1"
|
||||
estree-walker "^0.5.2"
|
||||
magic-string "^0.25.1"
|
||||
resolve "^1.10.0"
|
||||
rollup-pluginutils "^2.3.3"
|
||||
|
||||
rollup-plugin-node-resolve@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-2.0.0.tgz#07e0ae94ac002a3ea36e8f33ca121d9f836b1309"
|
||||
rollup-plugin-node-resolve@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-4.0.1.tgz#f95765d174e5daeef9ea6268566141f53aa9d422"
|
||||
integrity sha512-fSS7YDuCe0gYqKsr5OvxMloeZYUSgN43Ypi1WeRZzQcWtHgFayV5tUSPYpxuaioIIWaBXl6NrVk0T2/sKwueLg==
|
||||
dependencies:
|
||||
browser-resolve "^1.11.0"
|
||||
builtin-modules "^1.1.0"
|
||||
resolve "^1.1.6"
|
||||
builtin-modules "^3.0.0"
|
||||
is-module "^1.0.0"
|
||||
resolve "^1.10.0"
|
||||
|
||||
rollup-plugin-uglify@^1.0.1:
|
||||
version "1.0.2"
|
||||
@ -6721,18 +6756,22 @@ rollup-plugin-uglify@^1.0.1:
|
||||
dependencies:
|
||||
uglify-js "^2.6.1"
|
||||
|
||||
rollup-pluginutils@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz#7ec95b3573f6543a46a6461bd9a7c544525d0fc0"
|
||||
rollup-pluginutils@^2.3.3:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.4.1.tgz#de43ab54965bbf47843599a7f3adceb723de38db"
|
||||
integrity sha512-wesMQ9/172IJDIW/lYWm0vW0LiKe5Ekjws481R7z9WTRtmO59cqyM/2uUlxvf6yzm/fElFmHUobeQOYz46dZJw==
|
||||
dependencies:
|
||||
estree-walker "^0.3.0"
|
||||
micromatch "^2.3.11"
|
||||
estree-walker "^0.6.0"
|
||||
micromatch "^3.1.10"
|
||||
|
||||
rollup@^0.41.6:
|
||||
version "0.41.6"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.6.tgz#e0d05497877a398c104d816d2733a718a7a94e2a"
|
||||
rollup@^1.1.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.6.0.tgz#4329f4634718197c678d18491724d50d8b7ee76c"
|
||||
integrity sha512-qu9iWyuiOxAuBM8cAwLuqPclYdarIpayrkfQB7aTGTiyYPbvx+qVF33sIznfq4bxZCiytQux/FvZieUBAXivCw==
|
||||
dependencies:
|
||||
source-map-support "^0.4.0"
|
||||
"@types/estree" "0.0.39"
|
||||
"@types/node" "^11.9.5"
|
||||
acorn "^6.1.1"
|
||||
|
||||
run-async@^2.2.0:
|
||||
version "2.3.0"
|
||||
@ -7304,7 +7343,7 @@ source-map-support@0.5.9, source-map-support@^0.5.5, source-map-support@^0.5.6,
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map-support@^0.4.0, source-map-support@~0.4.0:
|
||||
source-map-support@~0.4.0:
|
||||
version "0.4.18"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
|
||||
dependencies:
|
||||
@ -7352,6 +7391,11 @@ sourcemap-codec@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.1.tgz#c8fd92d91889e902a07aee392bdd2c5863958ba2"
|
||||
|
||||
sourcemap-codec@^1.4.4:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz#c63ea927c029dd6bd9a2b7fa03b3fec02ad56e9f"
|
||||
integrity sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==
|
||||
|
||||
spawn-command@^0.0.2-1:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e"
|
||||
@ -8208,10 +8252,6 @@ verror@1.10.0:
|
||||
core-util-is "1.0.2"
|
||||
extsprintf "^1.2.0"
|
||||
|
||||
vlq@^0.2.1:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26"
|
||||
|
||||
vm-browserify@0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
|
||||
|
3778
aio/yarn.lock
@ -1,7 +1,7 @@
|
||||
# Building and Testing Angular
|
||||
|
||||
This document describes how to set up your development environment to build and test Angular.
|
||||
It also explains the basic mechanics of using `git`, `node`, and `npm`.
|
||||
It also explains the basic mechanics of using `git`, `node`, and `yarn`.
|
||||
|
||||
* [Prerequisite Software](#prerequisite-software)
|
||||
* [Getting the Sources](#getting-the-sources)
|
||||
@ -59,12 +59,6 @@ Next, install the JavaScript modules needed to build and test Angular:
|
||||
yarn install
|
||||
```
|
||||
|
||||
**Optional**: In this document, we make use of installed npm package scripts and binaries
|
||||
(stored under `./node_modules/.bin`) by prefixing these command invocations with `$(yarn bin)`; in
|
||||
particular `gulp` and `protractor` commands.
|
||||
|
||||
|
||||
|
||||
## Windows only
|
||||
|
||||
In order to create the right symlinks, run **as administrator**:
|
||||
@ -91,40 +85,46 @@ To build Angular run:
|
||||
|
||||
Bazel is used as the primary tool for building and testing Angular. Building and testing is
|
||||
incremental with Bazel, and it's possible to only run tests for an individual package instead
|
||||
of for all packages.
|
||||
of for all packages. Read more about this in the [BAZEL.md](./BAZEL.md) document.
|
||||
|
||||
Read more about this in the [BAZEL.md](./BAZEL.md) document. You should execute all test suites
|
||||
before submitting a PR to Github.
|
||||
You should execute all test suites before submitting a PR to GitHub:
|
||||
- `yarn bazel test packages/...`
|
||||
|
||||
All the tests are executed on our Continuous Integration infrastructure and a PR could only be
|
||||
**Note**: The first test run will be much slower than future runs. This is because future runs will
|
||||
benefit from Bazel's capability to do incremental builds.
|
||||
|
||||
All the tests are executed on our Continuous Integration infrastructure. PRs can only be
|
||||
merged if the code is formatted properly and all tests are passing.
|
||||
|
||||
## <a name="clang-format"></a> Formatting your source code
|
||||
|
||||
Angular uses [clang-format](http://clang.llvm.org/docs/ClangFormat.html) to format the source code.
|
||||
If the source code is not properly formatted, the CI will fail and the PR can not be merged.
|
||||
If the source code is not properly formatted, the CI will fail and the PR cannot be merged.
|
||||
|
||||
You can automatically format your code by running:
|
||||
- `gulp format`: re-format only edited source code.
|
||||
- `gulp format:all`: format _all_ source code
|
||||
- `yarn gulp format`: re-format only edited source code.
|
||||
- `yarn gulp format:all`: format _all_ source code
|
||||
|
||||
A better way is to set up your IDE to format the changed file on each file save.
|
||||
|
||||
### VS Code
|
||||
1. Install [Clang-Format](https://marketplace.visualstudio.com/items?itemName=xaver.clang-format) extension for VS Code.
|
||||
2. Open `settings.json` in your workspace and add these lines:
|
||||
```json
|
||||
"files.autoSave": "onFocusChange",
|
||||
"editor.formatOnSave": true,
|
||||
"clang-format.executable": "PATH_TO_YOUR_WORKSPACE/angular/node_modules/.bin/clang-format",
|
||||
```
|
||||
|
||||
It will automatically pick up the settings from Angular's [settings.json](../.vscode/settings.json).
|
||||
|
||||
### WebStorm / IntelliJ
|
||||
1. Install the [ClangFormatIJ](https://plugins.jetbrains.com/plugin/8396-clangformatij) plugin
|
||||
1. Open `Preferences->Tools->clang-format`
|
||||
1. Find the field named "PATH"
|
||||
1. Add `<PATH_TO_YOUR_WORKSPACE>/angular/node_modules/clang-format/bin/<OS>/`
|
||||
where the OS options are: `darwin_x64`, `linux_x64`, and `win32`.
|
||||
|
||||
## Linting/verifying your source code
|
||||
|
||||
You can check that your code is properly formatted and adheres to coding style by running:
|
||||
|
||||
``` shell
|
||||
$ gulp lint
|
||||
$ yarn gulp lint
|
||||
```
|
||||
|
||||
## Publishing snapshot builds
|
||||
@ -138,17 +138,17 @@ You may find that your un-merged change needs some validation from external part
|
||||
Rather than requiring them to pull your Pull Request and build Angular locally, you can
|
||||
publish the `*-builds` snapshots just like our CircleCI build does.
|
||||
|
||||
First time, you need to create the github repositories:
|
||||
First time, you need to create the GitHub repositories:
|
||||
|
||||
``` shell
|
||||
$ export TOKEN=[get one from https://github.com/settings/tokens]
|
||||
$ CREATE_REPOS=1 ./scripts/ci/publish-build-artifacts.sh [github username]
|
||||
$ CREATE_REPOS=1 ./scripts/ci/publish-build-artifacts.sh [GitHub username]
|
||||
```
|
||||
|
||||
For subsequent snapshots, just run
|
||||
|
||||
``` shell
|
||||
$ ./scripts/publish/publish-build-artifacts.sh [github username]
|
||||
$ ./scripts/ci/publish-build-artifacts.sh [GitHub username]
|
||||
```
|
||||
|
||||
The script will publish the build snapshot to a branch with the same name as your current branch,
|
||||
@ -158,27 +158,9 @@ and create it if it doesn't exist.
|
||||
### VS Code
|
||||
|
||||
1. Install [Bazel](https://marketplace.visualstudio.com/items?itemName=DevonDCarew.bazel-code) extension for VS Code.
|
||||
2. Open `settings.json` in your workspace and add these lines:
|
||||
```json
|
||||
"files.associations": {
|
||||
"*.bazel": "bazel"
|
||||
},
|
||||
```
|
||||
|
||||
## General IDE settings
|
||||
### VS Code
|
||||
### WebStorm / IntelliJ
|
||||
1. Install the [Bazel](https://plugins.jetbrains.com/plugin/8609-bazel) plugin
|
||||
1. You can find the settings under `Preferences->Other Settings->Bazel Settings`
|
||||
|
||||
1. Open `settings.json` in your workspace and add these lines:
|
||||
```json
|
||||
"editor.tabSize": 2,
|
||||
"files.exclude": {
|
||||
"bazel-out": true,
|
||||
".idea": true,
|
||||
".circleci": true,
|
||||
".github": true,
|
||||
"dist/**": true,
|
||||
"node_modules/**": true,
|
||||
".rpt2_cache": true,
|
||||
".vscode": true
|
||||
},
|
||||
```
|
||||
It will automatically recognize `*.bazel` and `*.bzl` files.
|
||||
|