Compare commits
173 Commits
ivy-svg-sy
...
6.1.0-beta
Author | SHA1 | Date | |
---|---|---|---|
def354de16 | |||
9782736e00 | |||
e8354edcd2 | |||
5b76f04b7f | |||
a57825acf3 | |||
efc7639352 | |||
3e26cabe02 | |||
9d114c052a | |||
43e61c25e1 | |||
4e1493a1d6 | |||
794584e353 | |||
45862d0812 | |||
f3625e424b | |||
ccbda9de65 | |||
27bc7dcb43 | |||
0f7e4fae20 | |||
a45fad3dd9 | |||
f00ae516eb | |||
6d246d6c72 | |||
7c8159b3e2 | |||
5aa12c73ae | |||
d8f7b293d7 | |||
39af314e29 | |||
8daadf360c | |||
859a3d5784 | |||
66f6a48210 | |||
8a4c577917 | |||
2b15108f7e | |||
bc4f10ca20 | |||
e6516b0229 | |||
77309e2ea4 | |||
e371b226fa | |||
ccb19fea68 | |||
38a0d1fac5 | |||
e7b392bf3a | |||
8977b9690e | |||
d4d8125b2d | |||
62443b04a0 | |||
3c1eb9413f | |||
4168c946c6 | |||
293ec78069 | |||
131d0d8e8a | |||
5fb0b567ce | |||
03f93b3772 | |||
3ccb4490a4 | |||
2ea197b99f | |||
503a524d27 | |||
a577c9e1f4 | |||
52ce9d5dcb | |||
2b49bf77af | |||
92b278c097 | |||
513f645894 | |||
0bd2d7bac6 | |||
82c5313740 | |||
c8e865ac8e | |||
d9bf6e37ae | |||
e3c54e4465 | |||
153ba4dff3 | |||
5731d0741a | |||
70ef061fa6 | |||
c2b5ebfa24 | |||
0d07d273dc | |||
131602474d | |||
282d3510cf | |||
3ed2d75336 | |||
4d55dfd9d9 | |||
86bf5f3912 | |||
dbfb6b9d45 | |||
8dd99ac550 | |||
014949f74c | |||
5e8bf2f88d | |||
ea143e7498 | |||
29eb24b142 | |||
dc4a3d00d0 | |||
8aa70c2477 | |||
49c5234c68 | |||
1b253e14ff | |||
8c1ac28275 | |||
5ef7a07c4b | |||
113556357a | |||
7983f0a69b | |||
8be6892777 | |||
9f877f4416 | |||
4664226b97 | |||
d4c66d5edb | |||
ce1543fcde | |||
a6e797b8f5 | |||
ca79e11bfa | |||
f781f741ea | |||
bd02b27ee1 | |||
e3759f7a73 | |||
7de2ba0e22 | |||
07b4c8be42 | |||
3128b26e5c | |||
4f5b01a98a | |||
c151f9cdc8 | |||
24ab0a7db0 | |||
31988a6ff9 | |||
8ac74da016 | |||
355e0b0587 | |||
d96ae123b2 | |||
7e73287676 | |||
9dd647b087 | |||
47814b4cdf | |||
700e55ce14 | |||
68d37ef0c1 | |||
acf270d724 | |||
1007d1ad27 | |||
51e9e64c5a | |||
1915e47d11 | |||
e994b11105 | |||
856ee73464 | |||
0d06c866c6 | |||
1208a35373 | |||
b415010222 | |||
d6989c80d3 | |||
81e4b2a4bf | |||
c494d3cf60 | |||
22b58a717a | |||
86b13ccf80 | |||
8db928df9d | |||
9367e91402 | |||
87b16710e7 | |||
20c463e97c | |||
57eacf4b5a | |||
d814eaad95 | |||
678fd32406 | |||
3e938279d0 | |||
d700a409da | |||
b750919ce0 | |||
9c403753e2 | |||
83a06863f9 | |||
08a18b82de | |||
255463ed48 | |||
b4bbdb4ce2 | |||
7623d74607 | |||
ccaa199366 | |||
069062236c | |||
5794506c64 | |||
cb65724761 | |||
44856bfc2f | |||
5db4f1a5ba | |||
0561b66a2b | |||
5cbcb5680b | |||
6948ef125c | |||
08f943a1f3 | |||
f69ac670ee | |||
60aa943e2d | |||
68a799e950 | |||
5f178f3a5a | |||
81c13e2f86 | |||
2d9111bfb6 | |||
a5c47d0045 | |||
7e3f8f77a9 | |||
6a663a4073 | |||
ec57133b61 | |||
3647cb7f3b | |||
49d5de68f6 | |||
4ab70fb93d | |||
5d6074eaff | |||
b86d4dee4d | |||
9add50129d | |||
9d364203a6 | |||
4247176b6e | |||
3b9c5c849c | |||
e79b845a45 | |||
b492b9e12b | |||
b99ef2b80a | |||
27d811a7ce | |||
accda00190 | |||
c25e6142d2 | |||
b96a3c8def | |||
c917e5b5bb |
@ -12,8 +12,8 @@
|
||||
## IMPORTANT
|
||||
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
|
||||
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
|
||||
var_1: &docker_image angular/ngcontainer:0.3.0
|
||||
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.0
|
||||
var_1: &docker_image angular/ngcontainer:0.3.2
|
||||
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.2
|
||||
|
||||
# Define common ENV vars
|
||||
var_3: &define_env_vars
|
||||
@ -80,7 +80,7 @@ jobs:
|
||||
|
||||
- run: ls /home/circleci/bazel_repository_cache || true
|
||||
- run: bazel info release
|
||||
- run: bazel run @yarn//:yarn
|
||||
- run: bazel run @nodejs//:yarn
|
||||
# Use bazel query so that we explicitly ask for all buildable targets to be built as well
|
||||
# This avoids waiting for the slowest build target to finish before running the first test
|
||||
# See https://github.com/bazelbuild/bazel/issues/4257
|
||||
@ -111,6 +111,42 @@ jobs:
|
||||
paths:
|
||||
- "node_modules"
|
||||
- "~/bazel_repository_cache"
|
||||
# Temporary job to test what will happen when we flip the Ivy flag to true
|
||||
test_ivy_jit:
|
||||
<<: *job_defaults
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- *define_env_vars
|
||||
- checkout:
|
||||
<<: *post_checkout
|
||||
# See remote cache documentation in /docs/BAZEL.md
|
||||
- run: .circleci/setup_cache.sh
|
||||
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
||||
- *setup-bazel-remote-cache
|
||||
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
|
||||
- run: bazel run @yarn//:yarn
|
||||
- run: bazel query --output=label //... | xargs bazel test --define=compile=jit --build_tag_filters=ivy-jit --test_tag_filters=-manual,ivy-jit
|
||||
|
||||
test_ivy_aot:
|
||||
<<: *job_defaults
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- *define_env_vars
|
||||
- checkout:
|
||||
<<: *post_checkout
|
||||
# See remote cache documentation in /docs/BAZEL.md
|
||||
- run: .circleci/setup_cache.sh
|
||||
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
||||
- *setup-bazel-remote-cache
|
||||
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
|
||||
- run: bazel run @yarn//:yarn
|
||||
- run: bazel query --output=label //... | xargs bazel test --define=compile=local --build_tag_filters=ivy-local --test_tag_filters=-manual,ivy-local
|
||||
|
||||
# This job exists only for backwards-compatibility with old scripts and tests
|
||||
# that rely on the pre-Bazel dist/packages-dist layout.
|
||||
@ -131,7 +167,7 @@ jobs:
|
||||
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
||||
- *setup-bazel-remote-cache
|
||||
|
||||
- run: bazel run @yarn//:yarn
|
||||
- run: bazel run @nodejs//:yarn
|
||||
- run: scripts/build-packages-dist.sh
|
||||
|
||||
# Save the npm packages from //packages/... for other workflow jobs to read
|
||||
@ -140,6 +176,8 @@ jobs:
|
||||
root: dist
|
||||
paths:
|
||||
- packages-dist
|
||||
- packages-dist-ivy-jit
|
||||
- packages-dist-ivy-local
|
||||
|
||||
# We run the integration tests outside of Bazel for now.
|
||||
# They are a separate workflow job so that they can be easily re-run.
|
||||
@ -149,6 +187,10 @@ jobs:
|
||||
# See comments inside the integration/run_tests.sh script.
|
||||
integration_test:
|
||||
<<: *job_defaults
|
||||
# Note: we run Bazel in one of the integration tests, and it can consume >2G
|
||||
# of memory. Together with the system under test, this can exhaust the RAM
|
||||
# on a 4G worker so we use a larger machine here too.
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- *define_env_vars
|
||||
- checkout:
|
||||
@ -200,6 +242,8 @@ workflows:
|
||||
jobs:
|
||||
- lint
|
||||
- test
|
||||
- test_ivy_jit
|
||||
- test_ivy_aot
|
||||
- build-packages-dist
|
||||
- integration_test:
|
||||
requires:
|
||||
@ -212,6 +256,8 @@ workflows:
|
||||
requires:
|
||||
# Only publish if tests and integration tests pass
|
||||
- test
|
||||
- test_ivy_jit
|
||||
- test_ivy_aot
|
||||
- integration_test
|
||||
# Get the artifacts to publish from the build-packages-dist job
|
||||
# since the publishing script expects the legacy outputs layout.
|
||||
|
2
.github/angular-robot.yml
vendored
2
.github/angular-robot.yml
vendored
@ -45,10 +45,12 @@ merge:
|
||||
- "packages/language-service/**"
|
||||
- "**/.gitignore"
|
||||
- "**/.gitkeep"
|
||||
- "**/package.json"
|
||||
- "**/tsconfig-build.json"
|
||||
- "**/tsconfig.json"
|
||||
- "**/rollup.config.js"
|
||||
- "**/BUILD.bazel"
|
||||
- "packages/**/integrationtest/**"
|
||||
- "packages/**/test/**"
|
||||
|
||||
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
|
||||
|
10
BUILD.bazel
10
BUILD.bazel
@ -11,7 +11,7 @@ exports_files([
|
||||
# This ensures that package.json in subdirectories get installed as well.
|
||||
alias(
|
||||
name = "install",
|
||||
actual = "@yarn//:yarn",
|
||||
actual = "@nodejs//:yarn",
|
||||
)
|
||||
|
||||
node_modules_filegroup(
|
||||
@ -44,14 +44,16 @@ filegroup(
|
||||
"//:node_modules/zone.js/dist/zone.js",
|
||||
"//:node_modules/zone.js/dist/zone-testing.js",
|
||||
"//:node_modules/zone.js/dist/task-tracking.js",
|
||||
"//:test-events.js",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "angularjs",
|
||||
# do not sort
|
||||
name = "angularjs_scripts",
|
||||
srcs = [
|
||||
"//:node_modules/angular/angular.js",
|
||||
"//:node_modules/angular-1.5/angular.js",
|
||||
"//:node_modules/angular-mocks-1.5/angular-mocks.js",
|
||||
"//:node_modules/angular-mocks/angular-mocks.js",
|
||||
"//:node_modules/angular/angular.js",
|
||||
],
|
||||
)
|
||||
|
156
CHANGELOG.md
156
CHANGELOG.md
@ -1,3 +1,131 @@
|
||||
<a name="6.1.0-beta.2"></a>
|
||||
# [6.1.0-beta.2](https://github.com/angular/angular/compare/6.1.0-beta.1...6.1.0-beta.2) (2018-06-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([d8f7b29](https://github.com/angular/angular/commit/d8f7b29)), closes [#20363](https://github.com/angular/angular/issues/20363)
|
||||
* **core:** Injector correctly honors the @Self flag ([#24520](https://github.com/angular/angular/issues/24520)) ([ccbda9d](https://github.com/angular/angular/commit/ccbda9d))
|
||||
|
||||
|
||||
|
||||
<a name="6.0.6"></a>
|
||||
## [6.0.6](https://github.com/angular/angular/compare/6.0.5...6.0.6) (2018-06-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([e543c73](https://github.com/angular/angular/commit/e543c73)), closes [#20363](https://github.com/angular/angular/issues/20363)
|
||||
* **core:** Injector correctly honors the @Self flag ([#24520](https://github.com/angular/angular/issues/24520)) ([f5b3661](https://github.com/angular/angular/commit/f5b3661))
|
||||
|
||||
|
||||
|
||||
<a name="6.0.5"></a>
|
||||
## [6.0.5](https://github.com/angular/angular/compare/6.0.4...6.0.5) (2018-06-13)
|
||||
|
||||
|
||||
<a name="6.1.0-beta.1"></a>
|
||||
# [6.1.0-beta.1](https://github.com/angular/angular/compare/6.1.0-beta.0...6.1.0-beta.1) (2018-06-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([dc4a3d0](https://github.com/angular/angular/commit/dc4a3d0))
|
||||
* **bazel:** Allow ng_module to depend on targets w no deps ([#24446](https://github.com/angular/angular/issues/24446)) ([282d351](https://github.com/angular/angular/commit/282d351))
|
||||
* **docs-infra:** use script nomodule to load IE polyfills, skip other polyfills ([#24317](https://github.com/angular/angular/issues/24317)) ([8be6892](https://github.com/angular/angular/commit/8be6892)), closes [#23647](https://github.com/angular/angular/issues/23647)
|
||||
* **ivy:** compute transitive scopes from NgModuleDef only ([#24334](https://github.com/angular/angular/issues/24334)) ([1135563](https://github.com/angular/angular/commit/1135563))
|
||||
* **ivy:** correctly handle queries with embedded views ([#24418](https://github.com/angular/angular/issues/24418)) ([014949f](https://github.com/angular/angular/commit/014949f))
|
||||
* **ivy:** remove debugger statement ([#24480](https://github.com/angular/angular/issues/24480)) ([70ef061](https://github.com/angular/angular/commit/70ef061))
|
||||
* **ivy:** special case [style] and [class] bindings for future use ([#23232](https://github.com/angular/angular/issues/23232)) ([1b253e1](https://github.com/angular/angular/commit/1b253e1))
|
||||
* **router:** fix lazy loading of aux routes ([#23459](https://github.com/angular/angular/issues/23459)) ([5731d07](https://github.com/angular/angular/commit/5731d07)), closes [#10981](https://github.com/angular/angular/issues/10981)
|
||||
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([3ed2d75](https://github.com/angular/angular/commit/3ed2d75)), closes [#24095](https://github.com/angular/angular/issues/24095)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **common:** introduce KeyValuePipe ([#24319](https://github.com/angular/angular/issues/24319)) ([2b49bf7](https://github.com/angular/angular/commit/2b49bf7))
|
||||
* **core:** export defaultKeyValueDiffers to private api ([#24319](https://github.com/angular/angular/issues/24319)) ([92b278c](https://github.com/angular/angular/commit/92b278c))
|
||||
* **core:** expose a Compiler API for accessing module ids from NgModule types ([#24258](https://github.com/angular/angular/issues/24258)) ([bd02b27](https://github.com/angular/angular/commit/bd02b27))
|
||||
* **core:** KeyValueDiffer#diff allows null values ([#24319](https://github.com/angular/angular/issues/24319)) ([52ce9d5](https://github.com/angular/angular/commit/52ce9d5))
|
||||
* **ivy:** a generic visitor which allows prefixing nodes for ngtsc ([#24230](https://github.com/angular/angular/issues/24230)) ([ca79e11](https://github.com/angular/angular/commit/ca79e11))
|
||||
* **ivy:** add support of ApplicationRef.bootstrapModuleFactory ([#23811](https://github.com/angular/angular/issues/23811)) ([e3759f7](https://github.com/angular/angular/commit/e3759f7))
|
||||
* **ivy:** namespaced attributes added to output instructions ([#24386](https://github.com/angular/angular/issues/24386)) ([82c5313](https://github.com/angular/angular/commit/82c5313))
|
||||
* **ivy:** now supports SVG and MathML elements ([#24377](https://github.com/angular/angular/issues/24377)) ([8c1ac28](https://github.com/angular/angular/commit/8c1ac28))
|
||||
* **router:** implement scrolling restoration service ([#20030](https://github.com/angular/angular/issues/20030)) ([49c5234](https://github.com/angular/angular/commit/49c5234)), closes [#13636](https://github.com/angular/angular/issues/13636) [#10929](https://github.com/angular/angular/issues/10929) [#7791](https://github.com/angular/angular/issues/7791) [#6595](https://github.com/angular/angular/issues/6595)
|
||||
|
||||
|
||||
|
||||
<a name="6.0.5"></a>
|
||||
## [6.0.5](https://github.com/angular/angular/compare/6.0.4...6.0.5) (2018-06-13)
|
||||
|
||||
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([0139173](https://github.com/angular/angular/commit/0139173))
|
||||
* **bazel:** Allow ng_module to depend on targets w no deps ([#24446](https://github.com/angular/angular/issues/24446)) ([ea3669e](https://github.com/angular/angular/commit/ea3669e))
|
||||
* **docs-infra:** use script nomodule to load IE polyfills, skip other polyfills ([#24317](https://github.com/angular/angular/issues/24317)) ([e876535](https://github.com/angular/angular/commit/e876535)), closes [#23647](https://github.com/angular/angular/issues/23647)
|
||||
* **router:** fix lazy loading of aux routes ([#23459](https://github.com/angular/angular/issues/23459)) ([d20877b](https://github.com/angular/angular/commit/d20877b)), closes [#10981](https://github.com/angular/angular/issues/10981)
|
||||
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([ea2987c](https://github.com/angular/angular/commit/ea2987c)), closes [#24095](https://github.com/angular/angular/issues/24095)
|
||||
|
||||
|
||||
|
||||
<a name="6.1.0-beta.0"></a>
|
||||
## [6.1.0-beta.0](https://github.com/angular/angular/compare/6.0.0-rc.5...6.1.0-beta.0) (2018-06-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** do not throw errors when a destroyed component is animated ([#23836](https://github.com/angular/angular/issues/23836)) ([d2a8687](https://github.com/angular/angular/commit/d2a8687))
|
||||
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([b492b9e](https://github.com/angular/angular/commit/b492b9e))
|
||||
* **animations:** properly clean up queried element styles in safari/edge ([#23633](https://github.com/angular/angular/issues/23633)) ([da9ff25](https://github.com/angular/angular/commit/da9ff25))
|
||||
* **animations:** retain state styling for nodes that are moved around ([#23534](https://github.com/angular/angular/issues/23534)) ([65211f4](https://github.com/angular/angular/commit/65211f4))
|
||||
* **animations:** retain trigger-state for nodes that are moved around ([#24238](https://github.com/angular/angular/issues/24238)) ([8db928d](https://github.com/angular/angular/commit/8db928d))
|
||||
* **benchpress:** Fix promise chain in chrome_driver_extension. ([#23458](https://github.com/angular/angular/issues/23458)) ([d4b6c41](https://github.com/angular/angular/commit/d4b6c41))
|
||||
* **compiler:** avoid a crash in ngc-wrapped. ([#23468](https://github.com/angular/angular/issues/23468)) ([e1c4930](https://github.com/angular/angular/commit/e1c4930))
|
||||
* **compiler:** generate constant array for i18n attributes ([#23837](https://github.com/angular/angular/issues/23837)) ([cfde36d](https://github.com/angular/angular/commit/cfde36d))
|
||||
* **compiler:** generate core-compliant hostBindings property ([#24087](https://github.com/angular/angular/issues/24087)) ([01b5acd](https://github.com/angular/angular/commit/01b5acd)), closes [#24013](https://github.com/angular/angular/issues/24013)
|
||||
* **compiler:** handle undefined annotation metadata ([#23349](https://github.com/angular/angular/issues/23349)) ([ca776c5](https://github.com/angular/angular/commit/ca776c5))
|
||||
* **compiler-cli:** don't rely on incompatible TS method ([#23550](https://github.com/angular/angular/issues/23550)) ([b1f040f](https://github.com/angular/angular/commit/b1f040f))
|
||||
* **core:** avoid eager providers re-initialization ([#23559](https://github.com/angular/angular/issues/23559)) ([0c6dc45](https://github.com/angular/angular/commit/0c6dc45))
|
||||
* **core:** call ngOnDestroy on all services that have it ([#23755](https://github.com/angular/angular/issues/23755)) ([fc03427](https://github.com/angular/angular/commit/fc03427)), closes [#22466](https://github.com/angular/angular/issues/22466) [#22240](https://github.com/angular/angular/issues/22240) [#14818](https://github.com/angular/angular/issues/14818)
|
||||
* **elements:** always check to create strategy ([#23825](https://github.com/angular/angular/issues/23825)) ([b1cda36](https://github.com/angular/angular/commit/b1cda36))
|
||||
* **elements:** prevent closure renaming of platform properties ([#23843](https://github.com/angular/angular/issues/23843)) ([d4b8b24](https://github.com/angular/angular/commit/d4b8b24))
|
||||
* **forms:** properly handle special properties in FormGroup.get ([#22249](https://github.com/angular/angular/issues/22249)) ([9367e91](https://github.com/angular/angular/commit/9367e91)), closes [#17195](https://github.com/angular/angular/issues/17195)
|
||||
* **platform-server:** avoid clash between server and client style encapsulation attributes ([#24158](https://github.com/angular/angular/issues/24158)) ([b96a3c8](https://github.com/angular/angular/commit/b96a3c8))
|
||||
* **platform-server:** avoid dependency cycle when using http interceptor ([#24229](https://github.com/angular/angular/issues/24229)) ([60aa943](https://github.com/angular/angular/commit/60aa943)), closes [#23023](https://github.com/angular/angular/issues/23023)
|
||||
* **platform-server:** don't reflect innerHTML property to attibute ([#24213](https://github.com/angular/angular/issues/24213)) ([6a663a4](https://github.com/angular/angular/commit/6a663a4)), closes [#19278](https://github.com/angular/angular/issues/19278)
|
||||
* **platform-server:** provide Domino DOM types globally ([#24116](https://github.com/angular/angular/issues/24116)) ([c73196e](https://github.com/angular/angular/commit/c73196e)), closes [#23280](https://github.com/angular/angular/issues/23280) [#23133](https://github.com/angular/angular/issues/23133)
|
||||
* **router:** avoid freezing queryParams in-place ([#22663](https://github.com/angular/angular/issues/22663)) ([89f64e5](https://github.com/angular/angular/commit/89f64e5)), closes [#22617](https://github.com/angular/angular/issues/22617)
|
||||
* **router:** cache route handle if found ([#22475](https://github.com/angular/angular/issues/22475)) ([4cfa571](https://github.com/angular/angular/commit/4cfa571)), closes [#22474](https://github.com/angular/angular/issues/22474)
|
||||
* **router:** correct the segment parsing so it won't break on ampersand ([#23684](https://github.com/angular/angular/issues/23684)) ([553a680](https://github.com/angular/angular/commit/553a680))
|
||||
* **service-worker:** add badge to NOTIFICATION_OPTION_NAMES ([#23241](https://github.com/angular/angular/issues/23241)) ([fb59b2d](https://github.com/angular/angular/commit/fb59b2d)), closes [#23196](https://github.com/angular/angular/issues/23196)
|
||||
* **service-worker:** check platformBrowser before accessing navigator.serviceWorker ([#21231](https://github.com/angular/angular/issues/21231)) ([0bdd30e](https://github.com/angular/angular/commit/0bdd30e))
|
||||
* **service-worker:** correctly handle requests with empty `clientId` ([#23625](https://github.com/angular/angular/issues/23625)) ([e0ed59e](https://github.com/angular/angular/commit/e0ed59e)), closes [#23526](https://github.com/angular/angular/issues/23526)
|
||||
* **service-worker:** deprecate `versionedFiles` in asset-group resources ([#23584](https://github.com/angular/angular/issues/23584)) ([1d378e2](https://github.com/angular/angular/commit/1d378e2))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **compiler:** support `// ...` and `// TODO` in mock compiler expectations ([#23441](https://github.com/angular/angular/issues/23441)) ([c6b206e](https://github.com/angular/angular/commit/c6b206e))
|
||||
* **compiler-cli:** update `tsickle` to `0.29.x` ([#24233](https://github.com/angular/angular/issues/24233)) ([f69ac67](https://github.com/angular/angular/commit/f69ac67))
|
||||
* **platform-browser:** add HammerJS lazy-loader symbols to public API ([#23943](https://github.com/angular/angular/issues/23943)) ([26fbf1d](https://github.com/angular/angular/commit/26fbf1d))
|
||||
* **platform-browser:** allow lazy-loading HammerJS ([#23906](https://github.com/angular/angular/issues/23906)) ([313bdce](https://github.com/angular/angular/commit/313bdce))
|
||||
* **platform-server:** use EventManagerPlugin on the server ([#24132](https://github.com/angular/angular/issues/24132)) ([d6595eb](https://github.com/angular/angular/commit/d6595eb))
|
||||
* **router:** add navigation execution context info to activation hooks ([#24204](https://github.com/angular/angular/issues/24204)) ([20c463e](https://github.com/angular/angular/commit/20c463e)), closes [#24202](https://github.com/angular/angular/issues/24202)
|
||||
|
||||
|
||||
<a name="6.0.4"></a>
|
||||
## [6.0.4](https://github.com/angular/angular/compare/6.0.3...6.0.4) (2018-06-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([c9eb491](https://github.com/angular/angular/commit/c9eb491))
|
||||
* **animations:** retain trigger-state for nodes that are moved around ([#24238](https://github.com/angular/angular/issues/24238)) ([19deca1](https://github.com/angular/angular/commit/19deca1))
|
||||
* **forms:** properly handle special properties in FormGroup.get ([#22249](https://github.com/angular/angular/issues/22249)) ([dc3e8aa](https://github.com/angular/angular/commit/dc3e8aa)), closes [#17195](https://github.com/angular/angular/issues/17195)
|
||||
* **platform-server:** avoid clash between server and client style encapsulation attributes ([#24158](https://github.com/angular/angular/issues/24158)) ([e9f2203](https://github.com/angular/angular/commit/e9f2203))
|
||||
* **platform-server:** avoid dependency cycle when using http interceptor ([#24229](https://github.com/angular/angular/issues/24229)) ([2991b1b](https://github.com/angular/angular/commit/2991b1b)), closes [#23023](https://github.com/angular/angular/issues/23023)
|
||||
* **platform-server:** don't reflect innerHTML property to attibute ([#24213](https://github.com/angular/angular/issues/24213)) ([c17098d](https://github.com/angular/angular/commit/c17098d)), closes [#19278](https://github.com/angular/angular/issues/19278)
|
||||
* **platform-server:** provide Domino DOM types globally ([#24116](https://github.com/angular/angular/issues/24116)) ([906b3ec](https://github.com/angular/angular/commit/906b3ec)), closes [#23280](https://github.com/angular/angular/issues/23280) [#23133](https://github.com/angular/angular/issues/23133)
|
||||
|
||||
|
||||
<a name="6.0.3"></a>
|
||||
## [6.0.3](https://github.com/angular/angular/compare/6.0.2...6.0.3) (2018-05-22)
|
||||
|
||||
@ -42,7 +170,7 @@
|
||||
|
||||
Angular v6 is the first release of Angular that unifies the Framework, Material and CLI.
|
||||
|
||||
To learn about the release highlights and our new CLI-powered update workflow for your projects please check out the [v6 release announcement](https://blog.angular.io/version-6-0-0-of-angular-now-available-cc56b0efa7a4).
|
||||
To learn about the release highlights and our new CLI-powered update workflow for your projects please check out the [v6 release announcement](https://blog.angular.io/version-6-0-0-of-angular-now-available-cc56b0efa7a4).
|
||||
|
||||
|
||||
|
||||
@ -193,10 +321,10 @@ To learn about the release highlights and our new CLI-powered update workflow fo
|
||||
This change removes support for `<template>`. `<ng-template>` should be used instead.
|
||||
|
||||
BEFORE:
|
||||
|
||||
|
||||
<!-- html template -->
|
||||
<template>some template content</template>
|
||||
|
||||
|
||||
# tsconfig.json
|
||||
{
|
||||
# ...
|
||||
@ -206,12 +334,12 @@ To learn about the release highlights and our new CLI-powered update workflow fo
|
||||
"enableLegacyTemplate": [true|false]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AFTER:
|
||||
|
||||
|
||||
<!-- html template -->
|
||||
<ng-template>some template content</ng-template>
|
||||
|
||||
|
||||
* **core:** it is no longer possible to import animation-related functions from @angular/core. All animation symbols must now be imported from @angular/animations.
|
||||
|
||||
|
||||
@ -224,35 +352,35 @@ To learn about the release highlights and our new CLI-powered update workflow fo
|
||||
|
||||
Previously, ngModelChange was emitted before its underlying control was updated.
|
||||
This was fine if you passed through the value directly through the $event keyword, e.g.
|
||||
|
||||
|
||||
```
|
||||
<input [(ngModel)]="name" (ngModelChange)="onChange($event)">
|
||||
|
||||
|
||||
onChange(value) {
|
||||
console.log(value); // would log updated value
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
However, if you had a handler for the ngModelChange event that checked the value through the control,
|
||||
you would get the old value rather than the updated value. e.g:
|
||||
|
||||
|
||||
```
|
||||
<input #modelDir="ngModel" [(ngModel)]="name" (ngModelChange)="onChange(modelDir)">
|
||||
|
||||
|
||||
onChange(ngModel: NgModel) {
|
||||
console.log(ngModel.value); // would log old value, not updated value
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Now the value and validity will be updated before the ngModelChange event is emitted,
|
||||
so the same setup will log the updated value.
|
||||
|
||||
|
||||
```
|
||||
onChange(ngModel: NgModel) {
|
||||
console.log(ngModel.value); // will log updated value
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
We think this order will be less confusing when the control is checked directly.
|
||||
You will only need to update your app if it has relied on this bug to keep track of the old control value.
|
||||
If that is the case, you should be able to track the old value directly by saving it on your component.
|
||||
|
@ -227,10 +227,15 @@ The following is the list of supported scopes:
|
||||
|
||||
There are currently a few exceptions to the "use package name" rule:
|
||||
|
||||
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
|
||||
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g.
|
||||
public path changes, package.json changes done to all packages, d.ts file/format changes, changes
|
||||
to bundles, etc.
|
||||
* **changelog**: used for updating the release notes in CHANGELOG.md
|
||||
* **aio**: used for docs-app (angular.io) related changes within the /aio directory of the repo
|
||||
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`)
|
||||
* **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the
|
||||
repo
|
||||
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all
|
||||
packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a
|
||||
specific package (e.g. `docs: fix typo in tutorial`).
|
||||
|
||||
### Subject
|
||||
The subject contains a succinct description of the change:
|
||||
@ -269,7 +274,7 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise
|
||||
* https://help.github.com/articles/about-commit-email-addresses/
|
||||
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
|
||||
|
||||
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.
|
||||
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.
|
||||
|
||||
<hr>
|
||||
|
||||
|
18
WORKSPACE
18
WORKSPACE
@ -6,9 +6,9 @@ workspace(name = "angular")
|
||||
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.8.0.zip",
|
||||
strip_prefix = "rules_nodejs-0.8.0",
|
||||
sha256 = "4e40dd49ae7668d245c3107645f2a138660fcfd975b9310b91eda13f0c973953",
|
||||
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.9.1.zip",
|
||||
strip_prefix = "rules_nodejs-0.9.1",
|
||||
sha256 = "6139762b62b37c1fd171d7f22aa39566cb7dc2916f0f801d505a9aaf118c117f",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
@ -20,9 +20,9 @@ http_archive(
|
||||
|
||||
http_archive(
|
||||
name = "build_bazel_rules_typescript",
|
||||
url = "https://github.com/bazelbuild/rules_typescript/archive/3b86d6d46269fb52d4c6f1416868869e847feac2.zip",
|
||||
strip_prefix = "rules_typescript-3b86d6d46269fb52d4c6f1416868869e847feac2",
|
||||
sha256 = "f67e5fbe4a2b34b3ead9fe56f22b713540c23b501bd24d661d3fb047071dc2c1",
|
||||
url = "https://github.com/bazelbuild/rules_typescript/archive/0.15.0.zip",
|
||||
strip_prefix = "rules_typescript-0.15.0",
|
||||
sha256 = "1aa75917330b820cb239b3c10a936a10f0a46fe215063d4492dd76dc6e1616f4",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
@ -34,13 +34,13 @@ http_archive(
|
||||
# This commit matches the version of buildifier in angular/ngcontainer
|
||||
# If you change this, also check if it matches the version in the angular/ngcontainer
|
||||
# version in /.circleci/config.yml
|
||||
BAZEL_BUILDTOOLS_VERSION = "fd9878fd5de921e0bbab3dcdcb932c2627812ee1"
|
||||
BAZEL_BUILDTOOLS_VERSION = "82b21607e00913b16fe1c51bec80232d9d6de31c"
|
||||
|
||||
http_archive(
|
||||
name = "com_github_bazelbuild_buildtools",
|
||||
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
|
||||
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
|
||||
sha256 = "27bb461ade23fd44ba98723ad98f84ee9c83cd3540b773b186a1bc5037f3d862",
|
||||
sha256 = "edb24c2f9c55b10a820ec74db0564415c0cf553fa55e9fc709a6332fb6685eff",
|
||||
)
|
||||
|
||||
# Fetching the Bazel source code allows us to compile the Skylark linter
|
||||
@ -77,7 +77,7 @@ http_archive(
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
|
||||
|
||||
check_bazel_version("0.13.0")
|
||||
check_bazel_version("0.14.0")
|
||||
node_repositories(package_json = ["//:package.json"])
|
||||
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
||||
|
@ -52,8 +52,7 @@ export class BuildCleaner {
|
||||
protected removeDir(dir: string) {
|
||||
try {
|
||||
if (shell.test('-d', dir)) {
|
||||
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
|
||||
(shell as any).chmod('-R', 'a+w', dir);
|
||||
shell.chmod('-R', 'a+w', dir);
|
||||
shell.rm('-rf', dir);
|
||||
}
|
||||
} catch (err) {
|
||||
|
@ -106,8 +106,7 @@ export class BuildCreator extends EventEmitter {
|
||||
}
|
||||
|
||||
try {
|
||||
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
|
||||
(shell as any).chmod('-R', 'a-w', outputDir);
|
||||
shell.chmod('-R', 'a-w', outputDir);
|
||||
shell.rm('-f', inputFile);
|
||||
resolve();
|
||||
} catch (err) {
|
||||
|
@ -98,8 +98,7 @@ class Helper {
|
||||
const prDir = this.getPrDir(pr, isPublic);
|
||||
|
||||
if (fs.existsSync(prDir)) {
|
||||
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
|
||||
(shell as any).chmod('-R', 'a+w', prDir);
|
||||
shell.chmod('-R', 'a+w', prDir);
|
||||
shell.rm('-rf', prDir);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
"scripts": {
|
||||
"prebuild": "yarn clean-dist",
|
||||
"build": "tsc",
|
||||
"build-watch": "yarn tsc --watch",
|
||||
"build-watch": "yarn build --watch",
|
||||
"clean-dist": "node --eval \"require('shelljs').rm('-rf', 'dist')\"",
|
||||
"dev": "concurrently --kill-others --raw --success first \"yarn build-watch\" \"yarn test-watch\"",
|
||||
"lint": "tslint --project tsconfig.json",
|
||||
@ -33,7 +33,7 @@
|
||||
"@types/jasmine": "^2.6.0",
|
||||
"@types/jsonwebtoken": "^7.2.3",
|
||||
"@types/node": "^8.0.30",
|
||||
"@types/shelljs": "^0.7.4",
|
||||
"@types/shelljs": "^0.8.0",
|
||||
"@types/supertest": "^2.0.3",
|
||||
"concurrently": "^3.5.0",
|
||||
"nodemon": "^1.12.1",
|
||||
|
@ -69,9 +69,9 @@
|
||||
"@types/express-serve-static-core" "*"
|
||||
"@types/mime" "*"
|
||||
|
||||
"@types/shelljs@^0.7.4":
|
||||
version "0.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.4.tgz#137b5f31306eaff4de120ffe5b9d74b297809cfc"
|
||||
"@types/shelljs@^0.8.0":
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.0.tgz#0caa56b68baae4f68f44e0dd666ab30b098e3632"
|
||||
dependencies:
|
||||
"@types/glob" "*"
|
||||
"@types/node" "*"
|
||||
|
@ -5,7 +5,7 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { HttpModule } from '@angular/http';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
// #docregion directive-import
|
||||
@ -24,7 +24,7 @@ import { ItemDirective } from './item.directive';
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpClientModule
|
||||
HttpModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
|
@ -1,7 +1,7 @@
|
||||
// #docregion
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { HttpModule } from '@angular/http';
|
||||
|
||||
// import { AppRoutingModule } from './app-routing.module';
|
||||
import { LocationStrategy,
|
||||
@ -54,7 +54,7 @@ const c_components = [
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpClientModule,
|
||||
HttpModule,
|
||||
InMemoryWebApiModule.forRoot(HeroData)
|
||||
// AppRoutingModule TODO: add routes
|
||||
],
|
||||
|
@ -3,7 +3,7 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { HttpModule } from '@angular/http';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
// import the feature module here so you can add it to the imports array below
|
||||
@ -17,7 +17,7 @@ import { CustomerDashboardModule } from './customer-dashboard/customer-dashboard
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpClientModule,
|
||||
HttpModule,
|
||||
CustomerDashboardModule // add the feature module here
|
||||
],
|
||||
providers: [],
|
||||
|
@ -5,7 +5,7 @@ import { AbstractControl, NG_VALIDATORS, Validator, ValidatorFn, Validators } fr
|
||||
// #docregion custom-validator
|
||||
/** A hero's name can't match the given regular expression */
|
||||
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
|
||||
return (control: AbstractControl): {[key: string]: any} => {
|
||||
return (control: AbstractControl): {[key: string]: any} | null => {
|
||||
const forbidden = nameRe.test(control.value);
|
||||
return forbidden ? {'forbiddenName': {value: control.value}} : null;
|
||||
};
|
||||
@ -22,7 +22,7 @@ export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
|
||||
export class ForbiddenValidatorDirective implements Validator {
|
||||
@Input('appForbiddenName') forbiddenName: string;
|
||||
|
||||
validate(control: AbstractControl): {[key: string]: any} {
|
||||
validate(control: AbstractControl): {[key: string]: any} | null {
|
||||
return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control)
|
||||
: null;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { HttpModule } from '@angular/http';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
@ -13,7 +13,7 @@ import { AppComponent } from './app.component';
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpClientModule,
|
||||
HttpModule,
|
||||
AppRoutingModule
|
||||
],
|
||||
providers: [],
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { HttpModule } from '@angular/http';
|
||||
|
||||
/* App Root */
|
||||
import { AppComponent } from './app.component';
|
||||
|
@ -15,6 +15,7 @@ export class ComposeMessageComponent {
|
||||
@HostBinding('style.position') position = 'absolute';
|
||||
|
||||
details: string;
|
||||
message: string;
|
||||
sending = false;
|
||||
|
||||
constructor(private router: Router) {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { HttpModule } from '@angular/http';
|
||||
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
|
||||
|
||||
import { RouterModule } from '@angular/router';
|
||||
@ -44,7 +44,7 @@ import * as s0901 from '../09-01/app/app.module';
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
HttpClientModule,
|
||||
HttpModule,
|
||||
InMemoryWebApiModule.forRoot(HeroData),
|
||||
|
||||
s0101.AppModule,
|
||||
|
@ -18,11 +18,11 @@ nav a {
|
||||
border-radius: 4px;
|
||||
}
|
||||
nav a:visited, a:link {
|
||||
color: #607D8B;
|
||||
color: #607d8b;
|
||||
}
|
||||
nav a:hover {
|
||||
color: #039be5;
|
||||
background-color: #CFD8DC;
|
||||
background-color: #cfd8dc;
|
||||
}
|
||||
nav a.active {
|
||||
color: #039be5;
|
||||
|
@ -33,11 +33,11 @@ h4 {
|
||||
color: #eee;
|
||||
max-height: 120px;
|
||||
min-width: 120px;
|
||||
background-color: #607D8B;
|
||||
background-color: #607d8b;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.module:hover {
|
||||
background-color: #EEE;
|
||||
background-color: #eee;
|
||||
cursor: pointer;
|
||||
color: #607d8b;
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
// #docregion
|
||||
var path = require('path');
|
||||
|
||||
var _root = path.resolve(__dirname, '..');
|
||||
|
||||
function root(args) {
|
||||
args = Array.prototype.slice.call(arguments, 0);
|
||||
return path.join.apply(path, [_root].concat(args));
|
||||
}
|
||||
|
||||
exports.root = root;
|
||||
// #enddocregion
|
@ -1,17 +0,0 @@
|
||||
// #docregion
|
||||
Error.stackTraceLimit = Infinity;
|
||||
|
||||
require('core-js/es6');
|
||||
require('core-js/es7/reflect');
|
||||
|
||||
require('zone.js/dist/zone');
|
||||
require('zone.js/dist/zone-testing');
|
||||
|
||||
var appContext = require.context('../src', true, /\.spec\.ts/);
|
||||
|
||||
appContext.keys().forEach(appContext);
|
||||
|
||||
var testing = require('@angular/core/testing');
|
||||
var browser = require('@angular/platform-browser-dynamic/testing');
|
||||
|
||||
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
|
@ -1,39 +0,0 @@
|
||||
// #docregion
|
||||
var webpackConfig = require('./webpack.test');
|
||||
|
||||
module.exports = function (config) {
|
||||
var _config = {
|
||||
basePath: '',
|
||||
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
files: [
|
||||
{pattern: './config/karma-test-shim.js', watched: false}
|
||||
],
|
||||
|
||||
preprocessors: {
|
||||
'./config/karma-test-shim.js': ['webpack', 'sourcemap']
|
||||
},
|
||||
|
||||
webpack: webpackConfig,
|
||||
|
||||
webpackMiddleware: {
|
||||
stats: 'errors-only'
|
||||
},
|
||||
|
||||
webpackServer: {
|
||||
noInfo: true
|
||||
},
|
||||
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: false,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: true
|
||||
};
|
||||
|
||||
config.set(_config);
|
||||
};
|
||||
// #enddocregion
|
@ -1,81 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
var webpack = require('webpack');
|
||||
var HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
module.exports = {
|
||||
// #docregion entries, one-entry, two-entries
|
||||
entry: {
|
||||
// #enddocregion one-entry, two-entries
|
||||
'polyfills': './src/polyfills.ts',
|
||||
// #docregion two-entries
|
||||
'vendor': './src/vendor.ts',
|
||||
// #docregion one-entry
|
||||
'app': './src/main.ts'
|
||||
},
|
||||
// #enddocregion entries, one-entry, two-entries
|
||||
|
||||
// #docregion resolve
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
// #enddocregion resolve
|
||||
|
||||
// #docregion loaders
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loaders: [
|
||||
{
|
||||
loader: 'awesome-typescript-loader',
|
||||
options: { configFileName: helpers.root('src', 'tsconfig.json') }
|
||||
} , 'angular2-template-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.html$/,
|
||||
loader: 'html-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
|
||||
loader: 'file-loader?name=assets/[name].[hash].[ext]'
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: helpers.root('src', 'app'),
|
||||
loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader?sourceMap' })
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
include: helpers.root('src', 'app'),
|
||||
loader: 'raw-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
// #enddocregion loaders
|
||||
|
||||
// #docregion plugins
|
||||
plugins: [
|
||||
// Workaround for angular/angular#11580
|
||||
new webpack.ContextReplacementPlugin(
|
||||
// The (\\|\/) piece accounts for path separators in *nix and Windows
|
||||
/angular(\\|\/)core(\\|\/)@angular/,
|
||||
helpers.root('./src'), // location of your src
|
||||
{} // a map of your routes
|
||||
),
|
||||
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: ['app', 'vendor', 'polyfills']
|
||||
}),
|
||||
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'src/index.html'
|
||||
})
|
||||
]
|
||||
// #enddocregion plugins
|
||||
};
|
||||
// #enddocregion
|
||||
|
@ -1,26 +0,0 @@
|
||||
// #docregion
|
||||
var webpackMerge = require('webpack-merge');
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
var commonConfig = require('./webpack.common.js');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
module.exports = webpackMerge(commonConfig, {
|
||||
devtool: 'cheap-module-eval-source-map',
|
||||
|
||||
output: {
|
||||
path: helpers.root('dist'),
|
||||
publicPath: '/',
|
||||
filename: '[name].js',
|
||||
chunkFilename: '[id].chunk.js'
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new ExtractTextPlugin('[name].css')
|
||||
],
|
||||
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
stats: 'minimal'
|
||||
}
|
||||
});
|
||||
// #enddocregion
|
@ -1,41 +0,0 @@
|
||||
// #docregion
|
||||
var webpack = require('webpack');
|
||||
var webpackMerge = require('webpack-merge');
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
var commonConfig = require('./webpack.common.js');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
|
||||
|
||||
module.exports = webpackMerge(commonConfig, {
|
||||
devtool: 'source-map',
|
||||
|
||||
output: {
|
||||
path: helpers.root('dist'),
|
||||
publicPath: '/',
|
||||
filename: '[name].[hash].js',
|
||||
chunkFilename: '[id].[hash].chunk.js'
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
|
||||
mangle: {
|
||||
keep_fnames: true
|
||||
}
|
||||
}),
|
||||
new ExtractTextPlugin('[name].[hash].css'),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
'ENV': JSON.stringify(ENV)
|
||||
}
|
||||
}),
|
||||
new webpack.LoaderOptionsPlugin({
|
||||
htmlLoader: {
|
||||
minimize: false // workaround for ng2
|
||||
}
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
// #enddocregion
|
@ -1,55 +0,0 @@
|
||||
// #docregion
|
||||
var webpack = require('webpack');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
module.exports = {
|
||||
devtool: 'inline-source-map',
|
||||
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loaders: [
|
||||
{
|
||||
loader: 'awesome-typescript-loader',
|
||||
options: { configFileName: helpers.root('src', 'tsconfig.json') }
|
||||
} , 'angular2-template-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.html$/,
|
||||
loader: 'html-loader'
|
||||
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
|
||||
loader: 'null-loader'
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: helpers.root('src', 'app'),
|
||||
loader: 'null-loader'
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
include: helpers.root('src', 'app'),
|
||||
loader: 'raw-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new webpack.ContextReplacementPlugin(
|
||||
// The (\\|\/) piece accounts for path separators in *nix and Windows
|
||||
/angular(\\|\/)core(\\|\/)@angular/,
|
||||
helpers.root('./src'), // location of your src
|
||||
{} // a map of your routes
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
// #enddocregion
|
@ -1,21 +0,0 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('QuickStart E2E Tests', function () {
|
||||
|
||||
let expectedMsg = 'Hello from Angular App with Webpack';
|
||||
|
||||
beforeEach(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it(`should display: ${expectedMsg}`, function () {
|
||||
expect(element(by.css('h1')).getText()).toEqual(expectedMsg);
|
||||
});
|
||||
|
||||
it('should display an image', function () {
|
||||
expect(element(by.css('img')).isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
});
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"build": "build:webpack",
|
||||
"run": "serve:cli",
|
||||
"projectType": "systemjs"
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
// #docregion
|
||||
module.exports = require('./config/karma.conf.js');
|
@ -1,49 +0,0 @@
|
||||
{
|
||||
"name": "angular2-webpack",
|
||||
"version": "1.0.0",
|
||||
"description": "A webpack starter for Angular",
|
||||
"scripts": {
|
||||
"start": "webpack-dev-server --inline --progress --port 8080",
|
||||
"test": "karma start",
|
||||
"build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@angular/common": "~4.2.0",
|
||||
"@angular/compiler": "~4.2.0",
|
||||
"@angular/core": "~4.2.0",
|
||||
"@angular/forms": "~4.2.0",
|
||||
"@angular/http": "~4.2.0",
|
||||
"@angular/platform-browser": "~4.2.0",
|
||||
"@angular/platform-browser-dynamic": "~4.2.0",
|
||||
"@angular/router": "~4.2.0",
|
||||
"core-js": "^2.4.1",
|
||||
"rxjs": "5.0.1",
|
||||
"zone.js": "^0.8.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^6.0.45",
|
||||
"@types/jasmine": "2.5.36",
|
||||
"angular2-template-loader": "^0.6.0",
|
||||
"awesome-typescript-loader": "^3.0.4",
|
||||
"css-loader": "^0.26.1",
|
||||
"extract-text-webpack-plugin": "2.0.0-beta.5",
|
||||
"file-loader": "^0.9.0",
|
||||
"html-loader": "^0.4.3",
|
||||
"html-webpack-plugin": "^2.16.1",
|
||||
"jasmine-core": "^2.4.1",
|
||||
"karma": "^1.2.0",
|
||||
"karma-chrome-launcher": "^2.0.0",
|
||||
"karma-jasmine": "^1.0.2",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^2.0.1",
|
||||
"null-loader": "^0.1.1",
|
||||
"raw-loader": "^0.5.1",
|
||||
"rimraf": "^2.5.2",
|
||||
"style-loader": "^0.13.1",
|
||||
"typescript": "~2.3.1",
|
||||
"webpack": "2.2.1",
|
||||
"webpack-dev-server": "2.4.1",
|
||||
"webpack-merge": "^3.0.0"
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
/* #docregion */
|
||||
main {
|
||||
padding: 1em;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
text-align: center;
|
||||
margin-top: 50px;
|
||||
display: block;
|
||||
}
|
||||
/* #enddocregion */
|
@ -1,7 +0,0 @@
|
||||
<!-- #docregion -->
|
||||
<main>
|
||||
<h1>Hello from Angular App with Webpack</h1>
|
||||
|
||||
<img src="../assets/images/angular.png">
|
||||
</main>
|
||||
<!-- #enddocregion -->
|
@ -1,16 +0,0 @@
|
||||
// #docregion
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('App', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({ declarations: [AppComponent]});
|
||||
});
|
||||
|
||||
it ('should work', () => {
|
||||
let fixture = TestBed.createComponent(AppComponent);
|
||||
expect(fixture.componentInstance instanceof AppComponent).toBe(true, 'should create AppComponent');
|
||||
});
|
||||
});
|
||||
// #enddocregion
|
@ -1,16 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
// #docregion component
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #enddocregion component
|
||||
import '../assets/css/styles.css';
|
||||
|
||||
// #docregion component
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent { }
|
||||
// #enddocregion
|
@ -1,16 +0,0 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
@ -1,6 +0,0 @@
|
||||
/* #docregion */
|
||||
body {
|
||||
background: #0147A7;
|
||||
color: #fff;
|
||||
}
|
||||
/* #enddocregion */
|
Binary file not shown.
Before Width: | Height: | Size: 2.3 KiB |
@ -1,14 +0,0 @@
|
||||
<!-- #docregion -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>Angular With Webpack</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
</html>
|
||||
<!-- #enddocregion -->
|
@ -1,14 +0,0 @@
|
||||
// #docregion
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { enableProdMode } from '@angular/core';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
|
||||
// #docregion enable-prod
|
||||
if (process.env.ENV === 'production') {
|
||||
enableProdMode();
|
||||
}
|
||||
// #enddocregion enable-prod
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
// #enddocregion
|
@ -1,12 +0,0 @@
|
||||
// #docregion
|
||||
import 'core-js/es6';
|
||||
import 'core-js/es7/reflect';
|
||||
require('zone.js/dist/zone');
|
||||
|
||||
if (process.env.ENV === 'production') {
|
||||
// Production
|
||||
} else {
|
||||
// Development and test
|
||||
Error['stackTraceLimit'] = Infinity;
|
||||
require('zone.js/dist/long-stack-trace-zone');
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": ["es2015", "dom"],
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
// TODO(i): this no longer works. we need to review this example and if absolutely necessary rewrite it to use the
|
||||
// rxjs-compat package
|
||||
|
||||
// #docregion
|
||||
// Angular
|
||||
import '@angular/platform-browser';
|
||||
import '@angular/platform-browser-dynamic';
|
||||
import '@angular/core';
|
||||
import '@angular/common';
|
||||
import '@angular/http';
|
||||
import '@angular/router';
|
||||
|
||||
// RxJS
|
||||
import 'rxjs';
|
||||
|
||||
// Other vendors for example jQuery, Lodash or Bootstrap
|
||||
// You can import js, ts, css, sass, ...
|
||||
// #enddocregion
|
@ -1,3 +0,0 @@
|
||||
// #docregion
|
||||
module.exports = require('./config/webpack.dev.js');
|
||||
// #enddocregion
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"files":[
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.[0-9].*",
|
||||
"config/**/*",
|
||||
"webpack.config.js",
|
||||
"karma.webpack.conf.js"
|
||||
],
|
||||
"removeSystemJsConfig": true,
|
||||
"type": "webpack"
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
<div class="breadcrumb">
|
||||
<a href="#">API<a> / <a href="#">@core<a>
|
||||
</div>
|
||||
<header class="api-header">
|
||||
<h1><label class="api-status-label experimental">experimental</label><label class="api-type-label class">class</label>Class Name</h1>
|
||||
</header>
|
||||
<div class="page-actions">
|
||||
<a href="#"><label class="raised page-label"><i class="material-icons">mode_edit</i>suggest edits</label></a>
|
||||
<a href="#"><label class="raised page-label"><i class="material-icons">code</i>view source</label></a>
|
||||
</div>
|
||||
<p>Class description goes here. This is a short and to the point one or two sentence description that easily introduces the reader to the class.</p>
|
||||
<div class="api-body">
|
||||
<section>
|
||||
<h2>Overview</h2>
|
||||
<code-example language="ts" hidecopy="true" ng-version="5.2.0"><aio-code class="simple-code" ng-reflect-ng-class="[object Object]" ng-reflect-code="
|
||||
class <a href="api/core/Compi" ng-reflect-hide-copy="true" ng-reflect-language="ts" ng-reflect-linenums="" ng-reflect-path="" ng-reflect-region="" ng-reflect-title=""><pre class="prettyprint lang-ts">
|
||||
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/core/Compiler" class="code-anchor"><span class="typ">Compiler</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleSync"><span class="pln">compileModuleSync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">NgModuleFactory</span><span class="pun"><</span><span class="pln">T</span><span class="pun">></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAsync"><span class="pln">compileModuleAsync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun"><</span><span class="typ">NgModuleFactory</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsSync"><span class="pln">compileModuleAndAllComponentsSync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">ModuleWithComponentFactories</span><span class="pun"><</span><span class="pln">T</span><span class="pun">></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsAsync"><span class="pln">compileModuleAndAllComponentsAsync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun"><</span><span class="typ">ModuleWithComponentFactories</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#clearCache"><span class="pln">clearCache</span><span class="pun">():</span><span class="pln"> </span><span class="kwd">void</span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#clearCacheFor"><span class="pln">clearCacheFor</span><span class="pun">(</span><span class="pln">type</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">any</span><span class="pun">>)</span></a><span class="pln">
|
||||
</span><span class="pun">}</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Description</h2>
|
||||
<p>The longer class description goes here which can include multiple paragraphs.</p>
|
||||
</p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
|
||||
<h3>Subclasses</h3>
|
||||
<ul>
|
||||
<li><a href="#">Subclass1</a></li>
|
||||
<li><a href="#">Subclass2</a></li>
|
||||
<li><a href="#">Subclass3</a></li>
|
||||
</ul>
|
||||
<h3>See Also</h3>
|
||||
<ul>
|
||||
<li><a href="#">Link1</a></li>
|
||||
<li><a href="#">Link2</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Constructor</h2>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Properties</h2>
|
||||
<table class="is-full-width list-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Property</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code><strong>Property1</strong></code>
|
||||
</td>
|
||||
<td><label class="property-type-label type">Type</label></td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code><strong>Property2</strong></code>
|
||||
</td>
|
||||
<td>Type</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code><strong>Property3</strong></code>
|
||||
</td>
|
||||
<td>Type</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<section class="api-method">
|
||||
<h2>Methods</h2>
|
||||
<table class="is-full-width item-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method1Name( )</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Description goes here</p>
|
||||
<br>
|
||||
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="is-full-width api-method item-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method2Name( )</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Description goes here</p>
|
||||
<hr>
|
||||
<h5>Declaration</h5>
|
||||
<code-example language="ts" hidecopy="true" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-ts">
|
||||
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/animations/AnimationBuilder" class="code-anchor"><span class="typ">AnimationBuilder</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln"></span><a class="code-anchor" href="api/animations/AnimationBuilder#build"><span class="pln">build</span><span class="pun">(</span><span class="pln">animation</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pun">[]):</span><span class="pln"> </span><span class="typ">AnimationFactory</span></a><span class="pln"></span><span class="pun">}</span></code></pre>
|
||||
</aio-code>
|
||||
</code-example>
|
||||
<h6>Parameters</h6>
|
||||
<h6>Returns</h6>
|
||||
<p>Returns information and results goes here.</p>
|
||||
<h6>Errors</h6>
|
||||
<p>Error information goes here</p>
|
||||
<hr>
|
||||
<p>Further details provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p><hr>
|
||||
<h6>Overloads</h6>
|
||||
<table class="is-full-width">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr>
|
||||
<h5>Example: Descriptive Title of Method Example</h5>
|
||||
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Example: Descriptive Title of Combined Example Goes Here</h2>
|
||||
<p>Intro description text about what the example is and how it can be used.</p>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
<p>Further explanation provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p>
|
||||
</section>
|
||||
</div>
|
@ -18,7 +18,8 @@ If you use the CLI to generate an app, the default `AppModule` is as follows:
|
||||
/* JavaScript imports */
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpModule } from '@angular/http';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@ -28,7 +29,9 @@ import { AppComponent } from './app.component';
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
@ -134,8 +137,8 @@ It tells Angular about other NgModules that this particular module needs to func
|
||||
|
||||
This list of modules are those that export components, directives, or pipes
|
||||
that the component templates in this module reference. In this case, the component is
|
||||
`AppComponent`, which references components, directives, or pipes in `BrowserModule`.
|
||||
Other common components in the examples are `FormsModule` and `HttpClientModule`.
|
||||
`AppComponent`, which references components, directives, or pipes in `BrowserModule`,
|
||||
`FormsModule`, or `HttpModule`.
|
||||
A component template can reference another component, directive,
|
||||
or pipe when the referenced class is declared in this module or
|
||||
the class was imported from another module.
|
||||
|
@ -32,7 +32,7 @@ from the [The Tour of Heroes](tutorial/).
|
||||
</code-tabs>
|
||||
|
||||
The `HeroesComponent` is the top-level heroes component.
|
||||
It's only purpose is to display the `HeroListComponent`
|
||||
Its only purpose is to display the `HeroListComponent`
|
||||
which displays a list of hero names.
|
||||
|
||||
This version of the `HeroListComponent` gets its `heroes` from the `HEROES` array, an in-memory collection
|
||||
|
@ -36,7 +36,7 @@ The following is an example of specifying a bootstrapped component,
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpClientModule,
|
||||
HttpModule,
|
||||
AppRoutingModule
|
||||
],
|
||||
providers: [],
|
||||
|
@ -44,25 +44,25 @@ of some of the things they contain:
|
||||
<tr>
|
||||
<td><code>FormsModule</code></td>
|
||||
<td><code>@angular/forms</code></td>
|
||||
<td>When you build template driven forms (includes <code>NgModel</code>)</td>
|
||||
<td>When you want to build template driven forms (includes <code>NgModel</code>)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>ReactiveFormsModule</code></td>
|
||||
<td><code>@angular/forms</code></td>
|
||||
<td>When building reactive forms</td>
|
||||
<td>When you want to build reactive forms</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>RouterModule</code></td>
|
||||
<td><code>@angular/router</code></td>
|
||||
<td>For Routing and when you want to use <code>RouterLink</code>,<code>.forRoot()</code>, and <code>.forChild()</code></td>
|
||||
<td>When you want to use <code>RouterLink</code>, <code>.forRoot()</code>, and <code>.forChild()</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>HttpClientModule</code></td>
|
||||
<td><code>@angular/common/http</code></td>
|
||||
<td>When you to talk to a server</td>
|
||||
<td>When you want to talk to a server</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
@ -142,7 +142,7 @@ To make these transitions as easy as possible, we make two commitments to you:
|
||||
|
||||
To help ensure that you have sufficient time and a clear path to update, this is our deprecation policy:
|
||||
|
||||
* When announce deprecated features in the [change log](https://github.com/angular/angular/blob/master/CHANGELOG.md "Angular change log").
|
||||
* We announce deprecated features in the [change log](https://github.com/angular/angular/blob/master/CHANGELOG.md "Angular change log").
|
||||
|
||||
* When we announce a deprecation, we also announce a recommended update path.
|
||||
|
||||
|
@ -933,29 +933,18 @@ As always, strive for consistency.
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 02-06}
|
||||
{@a 05-02}
|
||||
|
||||
### Directive selectors
|
||||
### Component selectors
|
||||
|
||||
#### Style 02-06
|
||||
#### Style 05-02
|
||||
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** Use lower camel case for naming the selectors of directives.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** Keeps the names of the properties defined in the directives that are bound to the view consistent with the attribute names.
|
||||
**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.
|
||||
|
||||
|
||||
</div>
|
||||
@ -966,16 +955,40 @@ As always, strive for consistency.
|
||||
|
||||
|
||||
|
||||
**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.
|
||||
**Why?** Keeps the element names consistent with the specification for [Custom Elements](https://www.w3.org/TR/custom-elements/).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts" region="example" title="app/heroes/shared/hero-button/hero-button.component.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="app/heroes/shared/hero-button/hero-button.component.ts" path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts" region="example">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="app/app.component.html" path="styleguide/src/05-02/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 02-07}
|
||||
|
||||
### Custom prefix for components
|
||||
### Component custom prefix
|
||||
|
||||
#### Style 02-07
|
||||
|
||||
@ -1078,11 +1091,51 @@ For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 02-06}
|
||||
|
||||
### Directive selectors
|
||||
|
||||
#### Style 02-06
|
||||
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** Use lower camel case for naming the selectors of directives.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** Keeps the names of the properties defined in the directives that are bound to the view consistent with the attribute names.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 02-08}
|
||||
|
||||
### Custom prefix for directives
|
||||
### Directive custom prefix
|
||||
|
||||
#### Style 02-08
|
||||
|
||||
@ -3056,9 +3109,9 @@ module are referenced across the entire application.
|
||||
|
||||
|
||||
|
||||
**Avoid** providing services in shared modules. Services are usually
|
||||
**Consider** _not_ providing services in shared modules. Services are usually
|
||||
singletons that are provided once for the entire application or
|
||||
in a particular feature module.
|
||||
in a particular feature module. There are exceptions, however. For example, in the sample code that follows, notice that the `SharedModule` provides `FilterTextService`. This is acceptable here because the service is stateless;that is, the consumers of the service aren't impacted by new instances.
|
||||
|
||||
|
||||
</div>
|
||||
@ -3710,59 +3763,6 @@ A typical *lazy loaded folder* contains a *routing component*, its child compone
|
||||
|
||||
## Components
|
||||
|
||||
{@a 05-02}
|
||||
|
||||
### Component selector names
|
||||
|
||||
#### Style 05-02
|
||||
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** Keeps the element names consistent with the specification for [Custom Elements](https://www.w3.org/TR/custom-elements/).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts" region="example" title="app/heroes/shared/hero-button/hero-button.component.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="app/heroes/shared/hero-button/hero-button.component.ts" path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts" region="example">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="app/app.component.html" path="styleguide/src/05-02/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 05-03}
|
||||
|
||||
### Components as elements
|
||||
|
@ -1,3 +0,0 @@
|
||||
# Testing
|
||||
|
||||
TBD. Original content [here](https://docs.google.com/document/d/1gGP5sqWNCHAWWV_GLdZQ1XyMO4K-CHksUxux0BFtVxk/edit#heading=h.ohqykkhzdhb2).
|
@ -346,7 +346,7 @@ It appears within the template of a parent component,
|
||||
which binds a _hero_ to the `@Input` property and
|
||||
listens for an event raised through the _selected_ `@Output` property.
|
||||
|
||||
You can test that the class code works without creating the the `DashboardHeroComponent`
|
||||
You can test that the class code works without creating the `DashboardHeroComponent`
|
||||
or its parent component.
|
||||
|
||||
<code-example
|
||||
@ -398,7 +398,7 @@ But a component is more than just its class.
|
||||
A component interacts with the DOM and with other components.
|
||||
The _class-only_ tests can tell you about class behavior.
|
||||
They cannot tell you if the component is going to render properly,
|
||||
respond to user input and gestures, or integrate with its parent and and child components.
|
||||
respond to user input and gestures, or integrate with its parent and child components.
|
||||
|
||||
None of the _class-only_ tests above can answer key questions about how the
|
||||
components actually behave on screen.
|
||||
@ -3378,11 +3378,11 @@ next to their corresponding helper files.
|
||||
{@a q-e2e}
|
||||
#### Why not rely on E2E tests of DOM integration?
|
||||
|
||||
The component DOM tests describe in this guide often require extensive setup and
|
||||
advanced techniques where as the [class-only test](#component-class-testing)
|
||||
were comparatively simple.
|
||||
The component DOM tests described in this guide often require extensive setup and
|
||||
advanced techniques whereas the [unit tests](#component-class-testing)
|
||||
are comparatively simple.
|
||||
|
||||
Why not defer DOM integration tests to end-to-end (E2E) testing?
|
||||
#### Why not defer DOM integration tests to end-to-end (E2E) testing?
|
||||
|
||||
E2E tests are great for high-level validation of the entire system.
|
||||
But they can't give you the comprehensive test coverage that you'd expect from unit tests.
|
||||
|
@ -132,7 +132,7 @@ QuickStart identifies two *typings*, or `d.ts`, files:
|
||||
* [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework.
|
||||
|
||||
* [node](https://www.npmjs.com/package/@types/node) for code that references objects in the *Node.js®* environment;
|
||||
you can view an example in the [webpack](guide/webpack) page.
|
||||
|
||||
|
||||
QuickStart doesn't require these typings but many of the samples do.
|
||||
|
||||
|
@ -1,801 +0,0 @@
|
||||
# Webpack: An Introduction
|
||||
|
||||
<style>
|
||||
h4 {font-size: 17px !important; text-transform: none !important;}
|
||||
.syntax { font-family: Consolas, 'Lucida Sans', Courier, sans-serif; color: black; font-size: 85%; }
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
[**Webpack**](https://webpack.github.io/) is a popular module bundler,
|
||||
a tool for bundling application source code in convenient _chunks_
|
||||
and for loading that code from a server into a browser.
|
||||
|
||||
It's an excellent alternative to the *SystemJS* approach used elsewhere in the documentation.
|
||||
This guide offers a taste of Webpack and explains how to use it with Angular applications.
|
||||
|
||||
|
||||
{@a top}
|
||||
|
||||
<!--
|
||||
|
||||
|
||||
# Contents
|
||||
|
||||
* [What is Webpack?](guide/webpack#what-is-webpack)
|
||||
|
||||
* [Entries and outputs](guide/webpack#entries-outputs)
|
||||
* [Multiple bundles](guide/webpack#multiple-bundles)
|
||||
* [Loaders](guide/webpack#loaders)
|
||||
* [Plugins](guide/webpack#plugins)
|
||||
|
||||
* [Configuring Webpack](guide/webpack#configure-webpack)
|
||||
|
||||
* [Polyfills](guide/webpack#polyfills)
|
||||
* [Common configuration](guide/webpack#common-configuration)
|
||||
* [Inside `webpack.common.js`](guide/webpack#inside-webpack-commonjs)
|
||||
|
||||
* [entry](guide/webpack#common-entries)
|
||||
* [resolve extension-less imports](guide/webpack#common-resolves)
|
||||
* [`module.rules`](guide/webpack#common-rules)
|
||||
* [Plugins](guide/webpack#plugins)
|
||||
* [`CommonsChunkPlugin`](guide/webpack#commons-chunk-plugin)
|
||||
* [`HtmlWebpackPlugin`](guide/webpack#html-webpack-plugin)
|
||||
|
||||
* [Environment specific configuration](guide/webpack#environment-configuration)
|
||||
* [Development configuration](guide/webpack#development-configuration)
|
||||
* [Production configuration](guide/webpack#production-configuration)
|
||||
* [Test configuration](guide/webpack#test-configuration)
|
||||
|
||||
* [Trying it out](guide/webpack#try)
|
||||
* [Highlights](guide/webpack#highlights)
|
||||
* [Conclusion](guide/webpack#conclusion)
|
||||
|
||||
-->
|
||||
|
||||
You can also <a href="generated/zips/webpack/webpack.zip" target="_blank">download the final result.</a>
|
||||
|
||||
{@a what-is-webpack}
|
||||
|
||||
## What is Webpack?
|
||||
|
||||
Webpack is a powerful module bundler.
|
||||
A _bundle_ is a JavaScript file that incorporates _assets_ that *belong* together and
|
||||
should be served to the client in a response to a single file request.
|
||||
A bundle can include JavaScript, CSS styles, HTML, and almost any other kind of file.
|
||||
|
||||
Webpack roams over your application source code,
|
||||
looking for `import` statements, building a dependency graph, and emitting one or more _bundles_.
|
||||
With plugins and rules, Webpack can preprocess and minify different non-JavaScript files such as TypeScript, SASS, and LESS files.
|
||||
|
||||
You determine what Webpack does and how it does it with a JavaScript configuration file, `webpack.config.js`.
|
||||
|
||||
|
||||
{@a entries-outputs}
|
||||
|
||||
|
||||
|
||||
### Entries and outputs
|
||||
|
||||
You supply Webpack with one or more *entry* files and let it find and incorporate the dependencies that radiate from those entries.
|
||||
The one entry point file in this example is the application's root file, `src/main.ts`:
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" region="one-entry" title="webpack.config.js (single entry)" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Webpack inspects that file and traverses its `import` dependencies recursively.
|
||||
|
||||
|
||||
<code-example path="webpack/src/app/app.component.ts" region="component" title="src/main.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
It sees that you're importing `@angular/core` so it adds that to its dependency list for potential inclusion in the bundle.
|
||||
It opens the `@angular/core` file and follows _its_ network of `import` statements until it has built the complete dependency graph from `main.ts` down.
|
||||
|
||||
Then it **outputs** these files to the `app.js` _bundle file_ designated in configuration:
|
||||
|
||||
<code-example name="webpack.config.js (single output)" language="javascript">
|
||||
output: {
|
||||
filename: 'app.js'
|
||||
}
|
||||
|
||||
</code-example>
|
||||
|
||||
This `app.js` output bundle is a single JavaScript file that contains the application source and its dependencies.
|
||||
You'll load it later with a `<script>` tag in the `index.html`.
|
||||
|
||||
|
||||
{@a multiple-bundles}
|
||||
|
||||
|
||||
#### Multiple bundles
|
||||
You probably don't want one giant bundle of everything.
|
||||
It's preferable to separate the volatile application app code from comparatively stable vendor code modules.
|
||||
|
||||
Change the configuration so that it has two entry points, `main.ts` and `vendor.ts`:
|
||||
|
||||
|
||||
<code-example language="javascript">
|
||||
entry: {
|
||||
app: 'src/app.ts',
|
||||
vendor: 'src/vendor.ts'
|
||||
},
|
||||
|
||||
output: {
|
||||
filename: '[name].js'
|
||||
}
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
Webpack constructs two separate dependency graphs
|
||||
and emits *two* bundle files, one called `app.js` containing only the application code and
|
||||
another called `vendor.js` with all the vendor dependencies.
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
The `[name]` in the output name is a *placeholder* that a Webpack plugin replaces with the entry names,
|
||||
`app` and `vendor`. Plugins are [covered later](guide/webpack#commons-chunk-plugin) in the guide.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
To tell Webpack what belongs in the vendor bundle,
|
||||
add a `vendor.ts` file that only imports the application's third-party modules:
|
||||
|
||||
<code-example path="webpack/src/vendor.ts" title="src/vendor.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a loaders}
|
||||
|
||||
|
||||
|
||||
### Loaders
|
||||
|
||||
Webpack can bundle any kind of file: JavaScript, TypeScript, CSS, SASS, LESS, images, HTML, fonts, whatever.
|
||||
Webpack _itself_ only understands JavaScript files.
|
||||
Teach it to transform non-JavaScript file into their JavaScript equivalents with *loaders*.
|
||||
Configure loaders for TypeScript and CSS as follows.
|
||||
|
||||
|
||||
<code-example language="javascript">
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loader: 'awesome-typescript-loader'
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
loaders: 'style-loader!css-loader'
|
||||
}
|
||||
]
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
When Webpack encounters `import` statements like the following,
|
||||
it applies the `test` RegEx patterns.
|
||||
|
||||
|
||||
<code-example language="typescript">
|
||||
import { AppComponent } from './app.component.ts';
|
||||
|
||||
import 'uiframework/dist/uiframework.css';
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
When a pattern matches the filename, Webpack processes the file with the associated loader.
|
||||
|
||||
The first `import` file matches the `.ts` pattern so Webpack processes it with the `awesome-typescript-loader`.
|
||||
The imported file doesn't match the second pattern so its loader is ignored.
|
||||
|
||||
The second `import` matches the second `.css` pattern for which you have *two* loaders chained by the (!) character.
|
||||
Webpack applies chained loaders *right to left*. So it applies
|
||||
the `css` loader first to flatten CSS `@import` and `url(...)` statements.
|
||||
Then it applies the `style` loader to append the css inside `<style>` elements on the page.
|
||||
|
||||
|
||||
{@a plugins}
|
||||
|
||||
|
||||
|
||||
### Plugins
|
||||
|
||||
Webpack has a build pipeline with well-defined phases.
|
||||
Tap into that pipeline with plugins such as the `uglify` minification plugin:
|
||||
|
||||
<code-example language="javascript">
|
||||
plugins: [
|
||||
new webpack.optimize.UglifyJsPlugin()
|
||||
]
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a configure-webpack}
|
||||
|
||||
|
||||
|
||||
## Configuring Webpack
|
||||
|
||||
After that brief orientation, you are ready to build your own Webpack configuration for Angular apps.
|
||||
|
||||
Begin by setting up the development environment.
|
||||
|
||||
Create a new project folder.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
mkdir angular-webpack
|
||||
cd angular-webpack
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Add these files:
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="package.json" path="webpack/package.webpack.json">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/tsconfig.json" path="webpack/src/tsconfig.1.json">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="webpack.config.js" path="webpack/webpack.config.js">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="karma.conf.js" path="webpack/karma.webpack.conf.js">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="config/helpers.js" path="webpack/config/helpers.js">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Many of these files should be familiar from other Angular documentation guides,
|
||||
especially the [Typescript configuration](guide/typescript-configuration) and
|
||||
[npm packages](guide/npm-packages) guides.
|
||||
|
||||
Webpack, the plugins, and the loaders are also installed as packages.
|
||||
They are listed in the updated `packages.json`.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Open a terminal window and install the npm packages.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm install
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a polyfills}
|
||||
|
||||
|
||||
|
||||
### Polyfills
|
||||
|
||||
You'll need polyfills to run an Angular application in most browsers as explained
|
||||
in the [Browser Support](guide/browser-support) guide.
|
||||
|
||||
Polyfills should be bundled separately from the application and vendor bundles.
|
||||
Add a `polyfills.ts` like this one to the `src/` folder.
|
||||
|
||||
|
||||
<code-example path="webpack/src/polyfills.ts" title="src/polyfills.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<div class="callout is-critical">
|
||||
|
||||
|
||||
|
||||
<header>
|
||||
Loading polyfills
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
Load `zone.js` early within `polyfills.ts`, immediately after the other ES6 and metadata shims.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Because this bundle file will load first, `polyfills.ts` is also a good place to configure the browser environment
|
||||
for production or development.
|
||||
|
||||
|
||||
{@a common-configuration}
|
||||
|
||||
|
||||
|
||||
### Common configuration
|
||||
|
||||
Developers typically have separate configurations for development, production, and test environments.
|
||||
All three have a lot of configuration in common.
|
||||
|
||||
Gather the common configuration in a file called `webpack.common.js`.
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" title="config/webpack.common.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a inside-webpack-commonjs}
|
||||
|
||||
|
||||
### Inside _webpack.common.js_
|
||||
Webpack is a NodeJS-based tool that reads configuration from a JavaScript commonjs module file.
|
||||
|
||||
The configuration imports dependencies with `require` statements
|
||||
and exports several objects as properties of a `module.exports` object.
|
||||
|
||||
* [`entry`](guide/webpack#common-entries)—the entry-point files that define the bundles.
|
||||
* [`resolve`](guide/webpack#common-resolves)—how to resolve file names when they lack extensions.
|
||||
* [`module.rules`](guide/webpack#common-rules)— `module` is an object with `rules` for deciding how files are loaded.
|
||||
* [`plugins`](guide/webpack#common-plugins)—creates instances of the plugins.
|
||||
|
||||
|
||||
{@a common-entries}
|
||||
|
||||
|
||||
#### _entry_
|
||||
|
||||
The first export is the `entry` object:
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" region="entries" title="config/webpack.common.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
This `entry` object defines the three bundles:
|
||||
|
||||
* `polyfills`—the polyfills needed to run Angular applications in most modern browsers.
|
||||
* `vendor`—the third-party dependencies such as Angular, lodash, and bootstrap.css.
|
||||
* `app`—the application code.
|
||||
|
||||
|
||||
{@a common-resolves}
|
||||
|
||||
|
||||
#### _resolve_ extension-less imports
|
||||
|
||||
The app will `import` dozens if not hundreds of JavaScript and TypeScript files.
|
||||
You could write `import` statements with explicit extensions like this example:
|
||||
|
||||
<code-example language="typescript">
|
||||
import { AppComponent } from './app.component.ts';
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
But most `import` statements don't mention the extension at all.
|
||||
Tell Webpack to resolve extension-less file requests by looking for matching files with
|
||||
`.ts` extension or `.js` extension (for regular JavaScript files and pre-compiled TypeScript files).
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" region="resolve" title="config/webpack.common.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
If Webpack should resolve extension-less files for styles and HTML,
|
||||
add `.css` and `.html` to the list.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a common-rules}
|
||||
|
||||
|
||||
|
||||
|
||||
#### _module.rules_
|
||||
Rules tell Webpack which loaders to use for each file, or module:
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" region="loaders" title="config/webpack.common.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
* `awesome-typescript-loader`—a loader to transpile the Typescript code to ES5, guided by the `tsconfig.json` file.
|
||||
* `angular2-template-loader`—loads angular components' template and styles.
|
||||
* `html-loader`—for component templates.
|
||||
* images/fonts—Images and fonts are bundled as well.
|
||||
* CSS—the first pattern matches application-wide styles; the second handles
|
||||
component-scoped styles (the ones specified in a component's `styleUrls` metadata property).
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
The first pattern is for the application-wide styles. It excludes `.css` files within the `src/app` directory
|
||||
where the component-scoped styles sit. The `ExtractTextPlugin` (described below) applies the `style` and `css`
|
||||
loaders to these files.
|
||||
|
||||
The second pattern filters for component-scoped styles and loads them as strings via the `raw-loader`,
|
||||
which is what Angular expects to do with styles specified in a `styleUrls` metadata property.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Multiple loaders can be chained using the array notation.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a common-plugins}
|
||||
|
||||
|
||||
|
||||
|
||||
#### _plugins_
|
||||
Finally, create instances of three plugins:
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" region="plugins" title="config/webpack.common.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a commons-chunk-plugin}
|
||||
|
||||
|
||||
#### *CommonsChunkPlugin*
|
||||
|
||||
The `app.js` bundle should contain only application code. All vendor code belongs in the `vendor.js` bundle.
|
||||
|
||||
Of course the application code imports vendor code.
|
||||
On its own, Webpack is not smart enough to keep the vendor code out of the `app.js` bundle.
|
||||
The `CommonsChunkPlugin` does that job.
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
The `CommonsChunkPlugin` identifies the hierarchy among three _chunks_: `app` -> `vendor` -> `polyfills`.
|
||||
Where Webpack finds that `app` has shared dependencies with `vendor`, it removes them from `app`.
|
||||
It would remove `polyfills` from `vendor` if they shared dependencies, which they don't.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a html-webpack-plugin}
|
||||
|
||||
|
||||
#### _HtmlWebpackPlugin_
|
||||
|
||||
Webpack generates a number of js and CSS files.
|
||||
You _could_ insert them into the `index.html` _manually_. That would be tedious and error-prone.
|
||||
Webpack can inject those scripts and links for you with the `HtmlWebpackPlugin`.
|
||||
|
||||
|
||||
{@a environment-configuration}
|
||||
|
||||
|
||||
|
||||
### Environment-specific configuration
|
||||
|
||||
The `webpack.common.js` configuration file does most of the heavy lifting.
|
||||
Create separate, environment-specific configuration files that build on `webpack.common`
|
||||
by merging into it the peculiarities particular to the target environments.
|
||||
|
||||
These files tend to be short and simple.
|
||||
|
||||
|
||||
{@a development-configuration}
|
||||
|
||||
|
||||
|
||||
### Development configuration
|
||||
|
||||
Here is the `webpack.dev.js` development configuration file.
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.dev.js" title="config/webpack.dev.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
The development build relies on the Webpack development server, configured near the bottom of the file.
|
||||
|
||||
Although you tell Webpack to put output bundles in the `dist` folder,
|
||||
the dev server keeps all bundles in memory; it doesn't write them to disk.
|
||||
You won't find any files in the `dist` folder, at least not any generated from *this development build*.
|
||||
|
||||
|
||||
The `HtmlWebpackPlugin`, added in `webpack.common.js`, uses the `publicPath` and the `filename` settings to generate
|
||||
appropriate `<script>` and `<link>` tags into the `index.html`.
|
||||
|
||||
The CSS styles are buried inside the Javascript bundles by default. The `ExtractTextPlugin` extracts them into
|
||||
external `.css` files that the `HtmlWebpackPlugin` inscribes as `<link>` tags into the `index.html`.
|
||||
|
||||
Refer to the [Webpack documentation](https://webpack.github.io/docs/) for details on these and
|
||||
other configuration options in this file.
|
||||
|
||||
Grab the app code at the end of this guide and try:
|
||||
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm start
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a production-configuration}
|
||||
|
||||
|
||||
|
||||
### Production configuration
|
||||
|
||||
Configuration of a *production* build resembles *development* configuration with a few key changes.
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.prod.js" title="config/webpack.prod.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
You'll deploy the application and its dependencies to a real production server.
|
||||
You won't deploy the artifacts needed only in development.
|
||||
|
||||
Put the production output bundle files in the `dist` folder.
|
||||
|
||||
Webpack generates file names with cache-busting hash.
|
||||
Thanks to the `HtmlWebpackPlugin`, you don't have to update the `index.html` file when the hash changes.
|
||||
|
||||
There are additional plugins:
|
||||
|
||||
* *`NoEmitOnErrorsPlugin`—stops the build if there is an error.
|
||||
* *`UglifyJsPlugin`—minifies the bundles.
|
||||
* *`ExtractTextPlugin`—extracts embedded css as external files, adding cache-busting hash to the filename.
|
||||
* *`DefinePlugin`—use to define environment variables that you can reference within the application.
|
||||
* *`LoaderOptionsPlugins`—to override options of certain loaders.
|
||||
|
||||
Thanks to the `DefinePlugin` and the `ENV` variable defined at top, you can enable Angular production mode like this:
|
||||
|
||||
|
||||
<code-example path="webpack/src/main.ts" region="enable-prod" title="src/main.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Grab the app code at the end of this guide and try:
|
||||
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm run build
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a test-configuration}
|
||||
|
||||
|
||||
|
||||
### Test configuration
|
||||
|
||||
You don't need much configuration to run unit tests.
|
||||
You don't need the loaders and plugins that you declared for your development and production builds.
|
||||
You probably don't need to load and process the application-wide styles files for unit tests and doing so would slow you down;
|
||||
you'll use the `null` loader for those CSS files.
|
||||
|
||||
You could merge the test configuration into the `webpack.common` configuration and override the parts you don't want or need.
|
||||
But it might be simpler to start over with a completely fresh configuration.
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.test.js" title="config/webpack.test.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Reconfigure [Karma](https://karma-runner.github.io/1.0/index.html) to use Webpack to run the tests:
|
||||
|
||||
|
||||
<code-example path="webpack/config/karma.conf.js" title="config/karma.conf.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
You don't precompile the TypeScript; Webpack transpiles the Typescript files on the fly, in memory, and feeds the emitted JS directly to Karma.
|
||||
There are no temporary files on disk.
|
||||
|
||||
The `karma-test-shim` tells Karma what files to pre-load and
|
||||
primes the Angular test framework with test versions of the providers that every app expects to be pre-loaded.
|
||||
|
||||
|
||||
<code-example path="webpack/config/karma-test-shim.js" title="config/karma-test-shim.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Notice that you do _not_ load the application code explicitly.
|
||||
You tell Webpack to find and load the test files (the files ending in `.spec.ts`).
|
||||
Each spec file imports all—and only—the application source code that it tests.
|
||||
Webpack loads just _those_ specific application files and ignores the other files that you aren't testing.
|
||||
|
||||
|
||||
Grab the app code at the end of this guide and try:
|
||||
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm test
|
||||
|
||||
</code-example>
|
||||
|
||||
{@a try}
|
||||
|
||||
## Trying it out
|
||||
|
||||
Here is the source code for a small application that bundles with the
|
||||
Webpack techniques covered in this guide.
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/index.html" path="webpack/src/index.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/main.ts" path="webpack/src/main.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/assets/css/styles.css" path="webpack/src/assets/css/styles.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/app/app.component.ts" path="webpack/src/app/app.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.html" path="webpack/src/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.css" path="webpack/src/app/app.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.spec.ts" path="webpack/src/app/app.component.spec.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.module.ts" path="webpack/src/app/app.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
The <code>app.component.html</code> displays this downloadable Angular logo
|
||||
<a href="assets/images/logos/angular/angular.png">
|
||||
<img src="assets/images/logos/angular/angular.png" height="40px" title="download Angular logo"></a>.
|
||||
Create a folder called `images` under the project's `assets` folder, then right-click (Cmd+click on Mac)
|
||||
on the image and download it to that folder.
|
||||
|
||||
|
||||
{@a bundle-ts}
|
||||
|
||||
|
||||
Here again are the TypeScript entry-point files that define the `polyfills` and `vendor` bundles.
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/polyfills.ts" path="webpack/src/polyfills.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/vendor.ts" path="webpack/src/vendor.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
{@a highlights}
|
||||
|
||||
<h3 class="no-toc">Highlights</h3>
|
||||
|
||||
* There are no `<script>` or `<link>` tags in the `index.html`.
|
||||
The `HtmlWebpackPlugin` inserts them dynamically at runtime.
|
||||
|
||||
* The `AppComponent` in `app.component.ts` imports the application-wide css with a simple `import` statement.
|
||||
|
||||
* The `AppComponent` itself has its own html template and css file. WebPack loads them with calls to `require()`.
|
||||
Webpack stashes those component-scoped files in the `app.js` bundle too.
|
||||
You don't see those calls in the source code;
|
||||
they're added behind the scenes by the `angular2-template-loader` plug-in.
|
||||
|
||||
* The `vendor.ts` consists of vendor dependency `import` statements that drive the `vendor.js` bundle.
|
||||
The application imports these modules too; they'd be duplicated in the `app.js` bundle
|
||||
if the `CommonsChunkPlugin` hadn't detected the overlap and removed them from `app.js`.
|
||||
{@a conclusion}
|
||||
|
||||
## Conclusion
|
||||
|
||||
You've learned just enough Webpack to configurate development, test and production builds
|
||||
for a small Angular application.
|
||||
|
||||
_You could always do more_. Search the web for expert advice and expand your Webpack knowledge.
|
||||
|
||||
[Back to top](guide/webpack#top)
|
BIN
aio/content/images/bios/kimmaida.jpg
Normal file
BIN
aio/content/images/bios/kimmaida.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
@ -12,5 +12,19 @@
|
||||
"message": "Watch ng-conf live stream <br/>Apr 18th-20th, 2018",
|
||||
"imageUrl": "generated/images/marketing/home/ng-conf.png",
|
||||
"linkUrl": "https://www.ng-conf.org/livestream/"
|
||||
},
|
||||
{
|
||||
"startDate": "2018-06-01",
|
||||
"endDate": "2018-08-15",
|
||||
"message": "Join us for Angular Mix<br/>October 10th-12th, 2018",
|
||||
"imageUrl": "generated/images/marketing/home/angular-mix.png",
|
||||
"linkUrl": "https://angularmix.com/"
|
||||
},
|
||||
{
|
||||
"startDate": "2018-08-15",
|
||||
"endDate": "2018-11-06",
|
||||
"message": "Join us for Angular Connect<br/>November 6th-7th, 2018",
|
||||
"imageUrl": "generated/images/marketing/home/angular-connect.png",
|
||||
"linkUrl": "https://angularconnect.com/"
|
||||
}
|
||||
]
|
||||
|
@ -636,5 +636,14 @@
|
||||
"website": "http://imars.info/",
|
||||
"bio": "Mashhood is the principal technical consultant at Recurship and a Google Developer Expert. He works with different startups in US and EU to helps them crawl through the technical maze and quickly build amazing products focused around the problems they are trying to solve. He specializes in using the latest web technologies available to execute the best possible solutions.",
|
||||
"group": "GDE"
|
||||
},
|
||||
|
||||
"kimmaida": {
|
||||
"name": "Kim Maida",
|
||||
"picture": "kimmaida.jpg",
|
||||
"twitter": "KimMaida",
|
||||
"website": "https://kmaida.io/",
|
||||
"bio": "Kim is an an Angular consultant, developer, speaker, writer, and Google Developer Expert. She is passionate about learning from and sharing knowledge with other developers through blogging, speaking, workshops, and open source.",
|
||||
"group": "GDE"
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,7 @@
|
||||
"desc": "Lightweight yet powerful IDE, perfectly equipped for complex client-side development and server-side development with Node.js",
|
||||
"logo": "",
|
||||
"rev": true,
|
||||
"title": "Webstorm",
|
||||
"title": "WebStorm",
|
||||
"url": "https://www.jetbrains.com/webstorm/"
|
||||
},
|
||||
"ab3": {
|
||||
@ -175,7 +175,13 @@
|
||||
"rev": true,
|
||||
"title": "Angular IDE by Webclipse",
|
||||
"url": "https://www.genuitec.com/products/angular-ide"
|
||||
}
|
||||
},
|
||||
"amexio-canvas": {
|
||||
"desc": "Amexio Canvas is Drag and Drop Environment to create Fully Responsive Web and Smart Device HTML5/Angular Apps. Code will be auto generated and hot deployed by the Canvas for live testing. Out of the box 50+ Material Design Theme support. Commit your code to GitHub public or private repository.",
|
||||
"rev": true,
|
||||
"title": "Amexio Canvas Web Based Drag and Drop IDE by MetaMagic",
|
||||
"url": "https://amexio.tech/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Tooling": {
|
||||
|
@ -61,12 +61,6 @@
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
{
|
||||
"url": "guide/webpack",
|
||||
"title": "Webpack: An Introduction",
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
{
|
||||
"url": "guide/quickstart",
|
||||
"title": "Getting Started",
|
||||
|
@ -112,7 +112,7 @@
|
||||
"cross-spawn": "^5.1.0",
|
||||
"css-selector-parser": "^1.3.0",
|
||||
"dgeni": "^0.4.7",
|
||||
"dgeni-packages": "^0.26.1",
|
||||
"dgeni-packages": "^0.26.2",
|
||||
"entities": "^1.1.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-plugin-jasmine": "^2.2.0",
|
||||
|
@ -82,31 +82,7 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
if (window.document.documentMode) {
|
||||
// polyfill IE11 in a blocking way
|
||||
var s = document.createElement('script');
|
||||
s.src = 'generated/ie-polyfills.min.js';
|
||||
document.head.appendChild(s);
|
||||
} else if (!Object.assign) {
|
||||
// polyfill other non-evergreen browsers in a blocking way
|
||||
var polyfillUrl = "https://cdn.polyfill.io/v2/polyfill.min.js?features=default,Array.prototype.find&flags=gated&unknown=polyfill";
|
||||
|
||||
// send a blocking XHR to fetch the polyfill
|
||||
// then append it to the document so that its eval-ed synchronously
|
||||
// this is required because the method used for IE is not reliable with other non-evergreen browsers
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.addEventListener("load", function() {
|
||||
var s = document.createElement('script');
|
||||
s.type = 'text/javascript';
|
||||
var code = this.responseText;
|
||||
s.appendChild(document.createTextNode(code));
|
||||
document.head.appendChild(s);
|
||||
});
|
||||
xhr.open("GET", polyfillUrl, false);
|
||||
xhr.send();
|
||||
}
|
||||
</script>
|
||||
<script nomodule src="generated/ie-polyfills.min.js"></script>
|
||||
|
||||
<script>
|
||||
//load CE polyfill
|
||||
|
@ -1,79 +0,0 @@
|
||||
.api-section {
|
||||
position: relative;
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
table.api-table {
|
||||
min-width: 680px;
|
||||
|
||||
thead th {
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
background-color: $blue;
|
||||
border-radius: 4px 4px 0 0;
|
||||
text-transform: none;
|
||||
padding: 8px 24px;
|
||||
}
|
||||
|
||||
tbody {
|
||||
pre {
|
||||
white-space: normal;
|
||||
margin: 4px;
|
||||
padding: 4px 16px;
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
th {
|
||||
max-width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.api-body {
|
||||
|
||||
max-width: 1200px;
|
||||
|
||||
table {
|
||||
|
||||
th {
|
||||
text-transform: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
tr {
|
||||
border-bottom: 1px solid $lightgray;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.item-table {
|
||||
td {
|
||||
padding: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
&.list-table {
|
||||
td {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
aio/src/styles/1-layouts/_api-pages.scss
Normal file
41
aio/src/styles/1-layouts/_api-pages.scss
Normal file
@ -0,0 +1,41 @@
|
||||
.api-body {
|
||||
|
||||
max-width: 1200px;
|
||||
|
||||
table {
|
||||
|
||||
th {
|
||||
text-transform: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
tr {
|
||||
border-bottom: 1px solid $lightgray;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.item-table {
|
||||
td {
|
||||
padding: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
&.list-table {
|
||||
td {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ aio-shell.page-docs {
|
||||
}
|
||||
|
||||
.sidenav-content button {
|
||||
min-width: 50px;
|
||||
min-width: 24px;
|
||||
}
|
||||
|
||||
#guide-change-log h2::before {
|
||||
|
@ -2,7 +2,7 @@
|
||||
LAYOUT STYLES
|
||||
============================== */
|
||||
|
||||
@import 'api-page';
|
||||
@import 'api-pages';
|
||||
@import 'content-layout';
|
||||
@import 'doc-viewer';
|
||||
@import 'footer';
|
||||
|
@ -93,15 +93,21 @@ aio-shell.folder-tutorial mat-toolbar.mat-toolbar {
|
||||
|
||||
|
||||
// HOME NAV-LINK
|
||||
.nav-link.home img {
|
||||
position: relative;
|
||||
margin-top: -21px;
|
||||
top: 12px;
|
||||
height: 40px;
|
||||
.nav-link.home {
|
||||
cursor: pointer;
|
||||
margin: 0 16px 0 0;
|
||||
padding: 21px 0;
|
||||
|
||||
@media(max-width: 992px) {
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
img {
|
||||
position: relative;
|
||||
margin-top: -21px;
|
||||
top: 12px;
|
||||
height: 40px;
|
||||
|
||||
@media(max-width: 992px) {
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -143,10 +149,6 @@ aio-top-menu {
|
||||
padding: 24px 16px;
|
||||
cursor: pointer;
|
||||
|
||||
&.home{
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: rgba($white, 0.15);
|
||||
border-radius: 4px;
|
||||
|
@ -280,6 +280,7 @@ p {
|
||||
.code-anchor {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
|
@ -1,4 +1,4 @@
|
||||
.page-actions {
|
||||
.github-links {
|
||||
float: right;
|
||||
.material-icons {
|
||||
border-radius: 4px;
|
||||
@ -30,10 +30,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
.method-table {
|
||||
.method-table, .option-table {
|
||||
th {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
h3 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.github-links {
|
||||
a {
|
||||
color: $mediumgray;
|
||||
.material-icons:hover {
|
||||
background: none;
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 6px 0;
|
||||
font-weight: bold;
|
||||
clear: left;
|
||||
}
|
||||
|
||||
h4 {
|
||||
@ -87,10 +107,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.api-section aio-code {
|
||||
background-color: rgba(241, 241, 241, 0.2);
|
||||
}
|
||||
|
||||
.from-constructor, .read-only-property {
|
||||
font-style: italic;
|
||||
color: $blue;
|
||||
|
@ -97,8 +97,9 @@ aio-code pre {
|
||||
|
||||
.copy-button {
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
right: -32px;
|
||||
top: -7px;
|
||||
right: -19px;
|
||||
padding: 0;
|
||||
|
||||
color: $blue-grey-200;
|
||||
background-color: transparent;
|
||||
|
@ -25,7 +25,7 @@ The zipper will use this information for creating new zips.
|
||||
|
||||
## Three kinds of examples
|
||||
|
||||
The majority of examples in AIO use `System.js` but there are also `CLI` and `Webpack` projects. This
|
||||
The majority of examples in AIO use `CLI`, with some additionally using `Webpack` and upgrade usiing `SystemJS`. This
|
||||
tool is able to differentiate between them.
|
||||
|
||||
The boilerplate uses a `package.json` that contains packages and scripts to run any kind of example.
|
||||
@ -44,7 +44,6 @@ Here you find a:
|
||||
|
||||
* **base.json** - All the common scripts and packages
|
||||
* **cli.json** - Extra scripts and packages for the CLI
|
||||
* **webpack.json** - Extra scripts and packages for Webpack
|
||||
* **universal.json** - Extra scripts and packages for universal
|
||||
* **i18n.json** - Extra scripts and packages for i18n
|
||||
* **systemjs.json** - All the System.js related packages but it also contains the remainder scripts
|
||||
@ -68,11 +67,11 @@ In both `stackblitz.json` and `zipper.json` you can use two extra properties for
|
||||
{
|
||||
...
|
||||
"removeSystemJsConfig": true,
|
||||
"type": "webpack"
|
||||
"type": "testing"
|
||||
}
|
||||
```
|
||||
|
||||
This would generate a zip for a webpack application and it will also remove everything related with
|
||||
This would generate a zip for a testing application and it will also remove everything related with
|
||||
SystemJS.
|
||||
|
||||
## Executing the zip generation
|
||||
|
@ -1,26 +0,0 @@
|
||||
{
|
||||
"scripts": [
|
||||
{ "name": "start:webpack", "rename": "start" },
|
||||
{ "name": "test:webpack", "rename": "test" },
|
||||
{ "name": "build:webpack", "rename": "build" }
|
||||
],
|
||||
"dependencies": [],
|
||||
"devDependencies": [
|
||||
"angular2-template-loader",
|
||||
"awesome-typescript-loader",
|
||||
"css-loader",
|
||||
"extract-text-webpack-plugin",
|
||||
"file-loader",
|
||||
"html-loader",
|
||||
"html-webpack-plugin",
|
||||
"karma-sourcemap-loader",
|
||||
"karma-webpack",
|
||||
"null-loader",
|
||||
"raw-loader",
|
||||
"rimraf",
|
||||
"style-loader",
|
||||
"webpack",
|
||||
"webpack-dev-server",
|
||||
"webpack-merge"
|
||||
]
|
||||
}
|
@ -113,7 +113,6 @@ class ExampleZipper {
|
||||
'!**/package.json',
|
||||
'!**/example-config.json',
|
||||
'!**/wallaby.js',
|
||||
'!**/package.webpack.json',
|
||||
// AoT related files
|
||||
'!**/aot/**/*.*',
|
||||
'!**/*-aot.*'
|
||||
|
@ -18,7 +18,6 @@ const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
|
||||
const IGNORED_EXAMPLES = [ // temporary ignores
|
||||
'quickstart',
|
||||
'setup',
|
||||
'webpack',
|
||||
'upgrade-p'
|
||||
];
|
||||
|
||||
|
@ -26,13 +26,7 @@
|
||||
"serve:cli": "http-server dist/",
|
||||
"build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup-config.js",
|
||||
"serve:aot": "lite-server -c bs-config.aot.json",
|
||||
"start:webpack": "webpack-dev-server --inline --progress --port 8080",
|
||||
"test:webpack": "karma start karma.webpack.conf.js",
|
||||
"build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --bail",
|
||||
"build:babel": "babel src -d src --extensions \".es6\" --source-maps",
|
||||
"build:uni-client": "webpack --config webpack.config.client.js",
|
||||
"build:uni": "webpack --config webpack.config.universal.js",
|
||||
"serve:uni": "node dist/server.js",
|
||||
|
||||
"clean": "rimraf src/dist && rimraf src/app/*.js* && rimraf src/universal/*.js* && rimraf src/main.js*",
|
||||
"copy-dist-files": "node ./copy-dist-files.js",
|
||||
|
@ -58,12 +58,6 @@
|
||||
"@types/node": "^6.0.45",
|
||||
"canonical-path": "0.0.2",
|
||||
"concurrently": "^3.0.0",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.26.1",
|
||||
"extract-text-webpack-plugin": "2.0.0-beta.5",
|
||||
"file-loader": "^0.9.0",
|
||||
"html-loader": "^0.4.3",
|
||||
"html-webpack-plugin": "^2.16.1",
|
||||
"http-server": "^0.9.0",
|
||||
"jasmine-core": "~2.99.1",
|
||||
"jasmine-marbles": "^0.3.1",
|
||||
@ -74,7 +68,6 @@
|
||||
"karma-jasmine": "~1.1.1",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"karma-phantomjs-launcher": "^1.0.2",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"lite-server": "^2.2.2",
|
||||
"lodash": "^4.16.2",
|
||||
"phantomjs-prebuilt": "^2.1.7",
|
||||
@ -85,7 +78,6 @@
|
||||
"rollup-plugin-node-resolve": "2.0.0",
|
||||
"rollup-plugin-uglify": "^1.0.1",
|
||||
"source-map-explorer": "^1.3.2",
|
||||
"ts-loader": "^4.2.0",
|
||||
"ts-node": "^5.0.1",
|
||||
"tslint": "^5.9.1",
|
||||
"typescript": "2.7.2",
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,12 +42,19 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
return EXPORT_DOC_TYPES.concat(['decorator', 'directive', 'pipe', 'module']);
|
||||
})
|
||||
|
||||
/**
|
||||
* These are the doc types that are contained within other docs
|
||||
*/
|
||||
.factory(function API_CONTAINED_DOC_TYPES() {
|
||||
return ['member', 'function-overload', 'get-accessor-info', 'set-accessor-info', 'parameter'];
|
||||
})
|
||||
|
||||
/**
|
||||
* These are the doc types that are API docs, including ones that will be merged into container docs,
|
||||
* such as members and overloads.
|
||||
*/
|
||||
.factory(function API_DOC_TYPES(API_DOC_TYPES_TO_RENDER) {
|
||||
return API_DOC_TYPES_TO_RENDER.concat(['member', 'function-overload']);
|
||||
.factory(function API_DOC_TYPES(API_DOC_TYPES_TO_RENDER, API_CONTAINED_DOC_TYPES) {
|
||||
return API_DOC_TYPES_TO_RENDER.concat(API_CONTAINED_DOC_TYPES);
|
||||
})
|
||||
|
||||
// Where do we get the source files?
|
||||
@ -112,13 +119,24 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
parseTagsProcessor.tagDefinitions.concat(getInjectables(requireFolder(__dirname, './tag-defs')));
|
||||
})
|
||||
|
||||
.config(function(computeStability, splitDescription, addNotYetDocumentedProperty, EXPORT_DOC_TYPES, API_DOC_TYPES) {
|
||||
computeStability.docTypes = EXPORT_DOC_TYPES;
|
||||
.config(function(computeStability, splitDescription, addNotYetDocumentedProperty, API_DOC_TYPES_TO_RENDER, API_DOC_TYPES) {
|
||||
computeStability.docTypes = API_DOC_TYPES_TO_RENDER;
|
||||
// Only split the description on the API docs
|
||||
splitDescription.docTypes = API_DOC_TYPES;
|
||||
addNotYetDocumentedProperty.docTypes = API_DOC_TYPES;
|
||||
})
|
||||
|
||||
.config(function(mergeDecoratorDocs) {
|
||||
mergeDecoratorDocs.propertiesToMerge = [
|
||||
'shortDescription',
|
||||
'description',
|
||||
'security',
|
||||
'deprecated',
|
||||
'see',
|
||||
'usageNotes',
|
||||
];
|
||||
})
|
||||
|
||||
.config(function(checkContentRules, EXPORT_DOC_TYPES) {
|
||||
// Min length rules
|
||||
const createMinLengthRule = require('./content-rules/minLength');
|
||||
@ -144,6 +162,16 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
});
|
||||
})
|
||||
|
||||
.config(function(filterContainedDocs, API_CONTAINED_DOC_TYPES) {
|
||||
filterContainedDocs.docTypes = API_CONTAINED_DOC_TYPES;
|
||||
})
|
||||
|
||||
.config(function(checkContentRules, API_DOC_TYPES, API_CONTAINED_DOC_TYPES) {
|
||||
addMinLengthRules(checkContentRules);
|
||||
addHeadingRules(checkContentRules, API_DOC_TYPES);
|
||||
addAllowedPropertiesRules(checkContentRules, API_CONTAINED_DOC_TYPES);
|
||||
})
|
||||
|
||||
.config(function(computePathsProcessor, EXPORT_DOC_TYPES, generateApiListDoc) {
|
||||
|
||||
const API_SEGMENT = 'api';
|
||||
@ -177,3 +205,45 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
autoLinkCode.docTypes = API_DOC_TYPES;
|
||||
autoLinkCode.codeElements = ['code', 'code-example', 'code-pane'];
|
||||
});
|
||||
|
||||
|
||||
function addMinLengthRules(checkContentRules) {
|
||||
const createMinLengthRule = require('./content-rules/minLength');
|
||||
const paramRuleSet = checkContentRules.docTypeRules['parameter'] = checkContentRules.docTypeRules['parameter'] || {};
|
||||
const paramRules = paramRuleSet['name'] = paramRuleSet['name'] || [];
|
||||
paramRules.push(createMinLengthRule());
|
||||
}
|
||||
|
||||
function addHeadingRules(checkContentRules, API_DOC_TYPES) {
|
||||
const createNoMarkdownHeadingsRule = require('./content-rules/noMarkdownHeadings');
|
||||
const noMarkdownHeadings = createNoMarkdownHeadingsRule();
|
||||
const allowOnlyLevel3Headings = createNoMarkdownHeadingsRule(1, 2, '4,');
|
||||
|
||||
API_DOC_TYPES.forEach(docType => {
|
||||
let rules;
|
||||
const ruleSet = checkContentRules.docTypeRules[docType] = checkContentRules.docTypeRules[docType] || {};
|
||||
|
||||
rules = ruleSet['description'] = ruleSet['description'] || [];
|
||||
rules.push(noMarkdownHeadings);
|
||||
|
||||
rules = ruleSet['shortDescription'] = ruleSet['shortDescription'] || [];
|
||||
rules.push(noMarkdownHeadings);
|
||||
|
||||
rules = ruleSet['usageNotes'] = ruleSet['usageNotes'] || [];
|
||||
rules.push(allowOnlyLevel3Headings);
|
||||
});
|
||||
}
|
||||
|
||||
function addAllowedPropertiesRules(checkContentRules, API_CONTAINED_DOC_TYPES) {
|
||||
API_CONTAINED_DOC_TYPES.forEach(docType => {
|
||||
const ruleSet = checkContentRules.docTypeRules[docType] = checkContentRules.docTypeRules[docType] || {};
|
||||
|
||||
const rules = ruleSet['usageNotes'] = ruleSet['usageNotes'] || [];
|
||||
rules.push((doc, prop, value) => value && !isMethod(doc) &&
|
||||
`Invalid property: "${prop}" is not allowed on "${doc.docType}" docs.`);
|
||||
});
|
||||
}
|
||||
|
||||
function isMethod(doc) {
|
||||
return doc.hasOwnProperty('parameters') && !doc.isGetAccessor && !doc.isSetAccessor;
|
||||
}
|
||||
|
@ -1,16 +1,15 @@
|
||||
module.exports = function computeApiBreadCrumbs(EXPORT_DOC_TYPES) {
|
||||
module.exports = function computeApiBreadCrumbs(API_DOC_TYPES_TO_RENDER) {
|
||||
return {
|
||||
$runAfter: ['paths-computed'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process(docs) {
|
||||
// Compute the breadcrumb for each doc by processing its containers
|
||||
docs.forEach(doc => {
|
||||
if (EXPORT_DOC_TYPES.indexOf(doc.docType) !== -1) {
|
||||
doc.breadCrumbs = [
|
||||
{ text: 'API', path: '/api' },
|
||||
{ text: '@angular/' + doc.moduleDoc.id, path: doc.moduleDoc.path },
|
||||
{ text: doc.name, path: doc.path }
|
||||
];
|
||||
if (API_DOC_TYPES_TO_RENDER.indexOf(doc.docType) !== -1) {
|
||||
doc.breadCrumbs = [];
|
||||
doc.breadCrumbs.push({ text: 'API', path: '/api' });
|
||||
if (doc.moduleDoc) doc.breadCrumbs.push({ text: '@angular/' + doc.moduleDoc.id, path: doc.moduleDoc.path });
|
||||
doc.breadCrumbs.push({ text: doc.name, path: doc.path });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -13,14 +13,15 @@ describe('angular-api-package: computeApiBreadCrumbs processor', () => {
|
||||
expect(processor.$runBefore).toEqual(['rendering-docs']);
|
||||
});
|
||||
|
||||
it('should attach a breadCrumbs property to each of the EXPORT_DOC_TYPES docs', () => {
|
||||
const EXPORT_DOC_TYPES = ['class', 'interface'];
|
||||
const processor = processorFactory(EXPORT_DOC_TYPES);
|
||||
it('should attach a breadCrumbs property to each of the API_DOC_TYPES_TO_RENDER docs', () => {
|
||||
const API_DOC_TYPES_TO_RENDER = ['class', 'interface', 'module'];
|
||||
const processor = processorFactory(API_DOC_TYPES_TO_RENDER);
|
||||
|
||||
const docs = [
|
||||
{ docType: 'class', name: 'ClassA', path: 'module-1/class-a', moduleDoc: { id: 'moduleOne', path: 'module-1' } },
|
||||
{ docType: 'interface', name: 'InterfaceB', path: 'module-2/interface-b', moduleDoc: { id: 'moduleTwo', path: 'module-2' } },
|
||||
{ docType: 'guide', name: 'Guide One', path: 'guide/guide-1' },
|
||||
{ docType: 'module', name: 'testing', id: 'http/testing', path: 'http/testing' },
|
||||
];
|
||||
processor.$process(docs);
|
||||
|
||||
@ -35,5 +36,9 @@ describe('angular-api-package: computeApiBreadCrumbs processor', () => {
|
||||
{ text: 'InterfaceB', path: 'module-2/interface-b' },
|
||||
]);
|
||||
expect(docs[2].breadCrumbs).toBeUndefined();
|
||||
expect(docs[3].breadCrumbs).toEqual([
|
||||
{ text: 'API', path: '/api' },
|
||||
{ text: 'testing', path: 'http/testing' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -5,7 +5,7 @@
|
||||
module.exports = function filterContainedDocs() {
|
||||
return {
|
||||
docTypes: ['member', 'function-overload', 'get-accessor-info', 'set-accessor-info', 'parameter'],
|
||||
$runAfter: ['extra-docs-added'],
|
||||
$runAfter: ['extra-docs-added', 'checkContentRules'],
|
||||
$runBefore: ['computing-paths'],
|
||||
$process: function(docs) {
|
||||
var docTypes = this.docTypes;
|
||||
|
@ -1,6 +1,6 @@
|
||||
module.exports = function filterPrivateDocs() {
|
||||
return {
|
||||
$runAfter: ['extra-docs-added'],
|
||||
$runAfter: ['extra-docs-added', 'checkContentRules'],
|
||||
$runBefore: ['computing-paths'],
|
||||
$process: function(docs) {
|
||||
return docs.filter(function(doc) { return doc.privateExport !== true; });
|
||||
|
@ -18,7 +18,7 @@ describe('filterPrivateDocs processor', () => {
|
||||
|
||||
it('should run after the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runAfter).toEqual(['extra-docs-added']);
|
||||
expect(processor.$runAfter).toEqual(['extra-docs-added', 'checkContentRules']);
|
||||
});
|
||||
|
||||
it('should remove docs that are marked as private exports', () => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
module.exports = function generateApiListDoc() {
|
||||
|
||||
return {
|
||||
$runAfter: ['extra-docs-added'],
|
||||
$runAfter: ['extra-docs-added', 'computeStability'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
outputFolder: null,
|
||||
$validate: {outputFolder: {presence: true}},
|
||||
|
@ -13,7 +13,7 @@ describe('generateApiListDoc processor', () => {
|
||||
|
||||
it('should run after the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runAfter).toEqual(['extra-docs-added']);
|
||||
expect(processor.$runAfter).toEqual(['extra-docs-added', 'computeStability']);
|
||||
});
|
||||
|
||||
it('should run before the correct processor', () => {
|
||||
|
@ -1,3 +1,5 @@
|
||||
const {mergeProperties} = require('../../helpers/utils');
|
||||
|
||||
/**
|
||||
* Decorators in the Angular code base are made up from three code items:
|
||||
*
|
||||
@ -46,62 +48,62 @@
|
||||
module.exports = function mergeDecoratorDocs(log) {
|
||||
return {
|
||||
$runAfter: ['processing-docs'],
|
||||
$runBefore: ['docs-processed'],
|
||||
$runBefore: ['docs-processed', 'checkContentRules'],
|
||||
propertiesToMerge: [],
|
||||
makeDecoratorCalls: [
|
||||
{type: '', description: 'toplevel', functionName: 'makeDecorator'},
|
||||
{type: 'Prop', description: 'property', functionName: 'makePropDecorator'},
|
||||
{type: 'Param', description: 'parameter', functionName: 'makeParamDecorator'},
|
||||
],
|
||||
$process: function(docs) {
|
||||
$process(docs) {
|
||||
|
||||
var makeDecoratorCalls = this.makeDecoratorCalls;
|
||||
var docsToMerge = Object.create(null);
|
||||
const decoratorDocs = Object.create(null);
|
||||
|
||||
docs.forEach(function(doc) {
|
||||
// find all the decorators, signified by a call to `make...Decorator<Decorator>(metadata)`
|
||||
docs.forEach(doc => {
|
||||
const initializer = getInitializer(doc);
|
||||
if (initializer) {
|
||||
makeDecoratorCalls.forEach(function(call) {
|
||||
// find all the decorators, signified by a call to `make...Decorator<Decorator>(metadata)`
|
||||
this.makeDecoratorCalls.forEach(function(call) {
|
||||
if (initializer.expression && initializer.expression.text === call.functionName) {
|
||||
log.debug('mergeDecoratorDocs: found decorator', doc.docType, doc.name);
|
||||
doc.docType = 'decorator';
|
||||
doc.decoratorLocation = call.description;
|
||||
// Get the type of the decorator metadata from the first "type" argument of the call.
|
||||
// For example the `X` of `createDecorator<X>(...)`.
|
||||
doc.decoratorType = initializer.arguments[0].text;
|
||||
// clear the symbol type named since it is not needed
|
||||
doc.symbolTypeName = undefined;
|
||||
const decoratorType = initializer.arguments[0].text;
|
||||
|
||||
// keep track of the names of the metadata interface that will need to be merged into this decorator doc
|
||||
docsToMerge[doc.name + 'Decorator'] = doc;
|
||||
log.debug('mergeDecoratorDocs: found decorator', doc.docType, doc.name, decoratorType);
|
||||
|
||||
doc.docType = 'decorator';
|
||||
doc.decoratorLocation = call.description;
|
||||
doc.decoratorType = decoratorType;
|
||||
|
||||
decoratorDocs[doc.name + 'Decorator'] = doc;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// merge the metadata docs into the decorator docs
|
||||
docs = docs.filter(function(doc) {
|
||||
if (docsToMerge[doc.name]) {
|
||||
// merge the info from the associated metadata interfaces into the decorator docs
|
||||
docs = docs.filter(doc => {
|
||||
if (decoratorDocs[doc.name]) {
|
||||
|
||||
// We have found an `XxxDecorator` document that will hold the call signature of the decorator
|
||||
var decoratorDoc = docsToMerge[doc.name];
|
||||
var callMember = doc.members.filter(function(member) { return member.isCallMember; })[0];
|
||||
var decoratorDoc = decoratorDocs[doc.name];
|
||||
var callMember = doc.members.find(member => member.isCallMember);
|
||||
|
||||
log.debug(
|
||||
'mergeDecoratorDocs: merging', doc.name, 'into', decoratorDoc.name,
|
||||
callMember.description.substring(0, 50));
|
||||
|
||||
// Merge the documentation found in this call signature into the original decorator
|
||||
decoratorDoc.description = callMember.description;
|
||||
decoratorDoc.usageNotes = callMember.usageNotes;
|
||||
mergeProperties(decoratorDoc, callMember, this.propertiesToMerge);
|
||||
|
||||
// remove doc from its module doc's exports
|
||||
doc.moduleDoc.exports =
|
||||
doc.moduleDoc.exports.filter(function(exportDoc) { return exportDoc !== doc; });
|
||||
|
||||
|
||||
// remove from the overall list of docs to be rendered
|
||||
return false;
|
||||
doc.moduleDoc.exports = doc.moduleDoc.exports.filter(exportDoc => exportDoc !== doc);
|
||||
}
|
||||
return true;
|
||||
|
||||
return !decoratorDocs[doc.name];
|
||||
});
|
||||
|
||||
return docs;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -9,17 +9,21 @@ describe('mergeDecoratorDocs processor', () => {
|
||||
const injector = dgeni.configureInjector();
|
||||
processor = injector.get('mergeDecoratorDocs');
|
||||
|
||||
// Note that we do not include usageNotes in the tests.
|
||||
processor.propertiesToMerge = ['description', 'shortDescription'];
|
||||
|
||||
moduleDoc = {};
|
||||
|
||||
decoratorDoc = {
|
||||
name: 'Component',
|
||||
docType: 'const',
|
||||
description: 'A description of the metadata for the Component decorator',
|
||||
shortDescription: 'decorator - short description',
|
||||
description: 'decorator - description',
|
||||
symbol: {
|
||||
valueDeclaration: { initializer: { expression: { text: 'makeDecorator' }, arguments: [{ text: 'X' }] } }
|
||||
},
|
||||
members: [
|
||||
{ name: 'templateUrl', description: 'A description of the templateUrl property' }
|
||||
{ name: 'templateUrl', description: 'templateUrl - description' }
|
||||
],
|
||||
moduleDoc
|
||||
};
|
||||
@ -27,15 +31,15 @@ describe('mergeDecoratorDocs processor', () => {
|
||||
metadataDoc = {
|
||||
name: 'ComponentDecorator',
|
||||
docType: 'interface',
|
||||
description: 'A description of the interface for the call signature for the Component decorator',
|
||||
description: 'call interface - description',
|
||||
members: [
|
||||
{
|
||||
isCallMember: true,
|
||||
description: 'The actual description of the call signature',
|
||||
usageNotes: 'Use it like this...'
|
||||
description: 'call interface - call member - description',
|
||||
usageNotes: 'call interface - call member - usageNotes',
|
||||
},
|
||||
{
|
||||
description: 'Some other member'
|
||||
description: 'call interface - non call member - description'
|
||||
}
|
||||
],
|
||||
moduleDoc
|
||||
@ -65,10 +69,13 @@ describe('mergeDecoratorDocs processor', () => {
|
||||
expect(decoratorDoc.decoratorType).toEqual('X');
|
||||
});
|
||||
|
||||
it('should copy across properties from the call signature doc', () => {
|
||||
it('should copy across specified properties from the call signature doc', () => {
|
||||
processor.$process([decoratorDoc, metadataDoc, otherDoc]);
|
||||
expect(decoratorDoc.description).toEqual('The actual description of the call signature');
|
||||
expect(decoratorDoc.usageNotes).toEqual('Use it like this...');
|
||||
expect(decoratorDoc.description).toEqual('call interface - call member - description');
|
||||
// Since usageNotes is not in `propertiesToMerge` it will not get copied over in these tests.
|
||||
expect(decoratorDoc.usageNotes).toBeUndefined();
|
||||
// Since `shortDescription` does not exist on the call-member this will not get overridden.
|
||||
expect(decoratorDoc.shortDescription).toEqual('decorator - short description');
|
||||
});
|
||||
|
||||
it('should remove the metadataDoc from the module exports', () => {
|
||||
|
@ -1,4 +1,5 @@
|
||||
// A ts2dart compiler annotation that can be ignored in API docs.
|
||||
// A ts2dart compiler annotation that we don't care about for API docs.
|
||||
// But, if we don't have a tag-def for it the doc-gen will error.
|
||||
module.exports = function() {
|
||||
return {name: 'Annotation', ignore: true};
|
||||
return {name: 'Annotation'};
|
||||
};
|
||||
|
@ -65,7 +65,9 @@ module.exports = function autoLinkCode(getDocFromAlias) {
|
||||
};
|
||||
}
|
||||
function foundValidDoc(docs) {
|
||||
return docs.length === 1 && autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1;
|
||||
return docs.length === 1 &&
|
||||
!docs[0].internal &&
|
||||
autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1;
|
||||
}
|
||||
|
||||
function createLinkNode(doc, text) {
|
||||
|
@ -79,6 +79,13 @@ describe('autoLinkCode post-processor', () => {
|
||||
'</code>');
|
||||
});
|
||||
|
||||
it('should ignore code items that match an internal API doc', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass', internal: true });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>MyClass</code>');
|
||||
});
|
||||
|
||||
it('should insert anchors for individual text nodes within a code block', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code><span>MyClass</span><span>MyClass</span></code>' };
|
||||
|
@ -32,8 +32,9 @@ module.exports = function checkContentRules(log, createDocMessage) {
|
||||
docTypeRules: {},
|
||||
failOnContentErrors: false,
|
||||
$runAfter: ['tags-extracted'],
|
||||
$runBefore: ['processing-docs'],
|
||||
$runBefore: [],
|
||||
$process(docs) {
|
||||
const logMessage = this.failOnContentErrors ? log.error.bind(log) : log.warn.bind(log);
|
||||
const errors = [];
|
||||
docs.forEach(doc => {
|
||||
const docErrors = [];
|
||||
@ -55,10 +56,10 @@ module.exports = function checkContentRules(log, createDocMessage) {
|
||||
});
|
||||
|
||||
if (errors.length) {
|
||||
log.error('Content contains errors');
|
||||
logMessage('Content contains errors');
|
||||
errors.forEach(docError => {
|
||||
const errors = docError.errors.join('\n ');
|
||||
log.error(createDocMessage(errors + '\n ', docError.doc));
|
||||
logMessage(createDocMessage(errors + '\n ', docError.doc));
|
||||
});
|
||||
if (this.failOnContentErrors) {
|
||||
throw new Error('Stopping due to content errors.');
|
||||
|
@ -18,7 +18,7 @@ describe('checkContentRules processor', function() {
|
||||
|
||||
it('shpuld run at the right time', () => {
|
||||
expect(processor.$runAfter).toEqual(['tags-extracted']);
|
||||
expect(processor.$runBefore).toEqual(['processing-docs']);
|
||||
expect(processor.$runBefore).toEqual([]);
|
||||
});
|
||||
|
||||
it('should do nothing if not configured', () => {
|
||||
@ -67,10 +67,11 @@ describe('checkContentRules processor', function() {
|
||||
expect(descriptionSpy3).toHaveBeenCalledWith(docs[0], 'description', 'test doc 1');
|
||||
});
|
||||
|
||||
it('should log errors if the rule returns error messages', () => {
|
||||
it('should log warnings if the rule returns error messages and `failOnContentErrors` is false', () => {
|
||||
const nameSpy1 = jasmine.createSpy('name 1').and.returnValue('name error message');
|
||||
const descriptionSpy1 = jasmine.createSpy('description 1').and.returnValue('description error message');
|
||||
|
||||
processor.failOnContentErrors = false;
|
||||
processor.docTypeRules = {
|
||||
'test1': {
|
||||
name: [nameSpy1],
|
||||
@ -85,6 +86,32 @@ describe('checkContentRules processor', function() {
|
||||
|
||||
processor.$process(docs);
|
||||
|
||||
expect(logger.warn).toHaveBeenCalledTimes(2);
|
||||
expect(logger.warn).toHaveBeenCalledWith('Content contains errors');
|
||||
expect(logger.warn).toHaveBeenCalledWith(`name error message
|
||||
description error message
|
||||
- doc "test-1" (test1) `);
|
||||
});
|
||||
|
||||
it('should log errors and then throw if `failOnContentErrors` is true and errors are found', () => {
|
||||
const nameSpy1 = jasmine.createSpy('name 1').and.returnValue('name error message');
|
||||
const descriptionSpy1 = jasmine.createSpy('description 1').and.returnValue('description error message');
|
||||
|
||||
processor.failOnContentErrors = true;
|
||||
processor.docTypeRules = {
|
||||
'test1': {
|
||||
name: [nameSpy1],
|
||||
description: [descriptionSpy1]
|
||||
}
|
||||
};
|
||||
|
||||
const docs = [
|
||||
{ docType: 'test1', description: 'test doc 1', name: 'test-1' },
|
||||
{ docType: 'test2', description: 'test doc 2', name: 'test-2' }
|
||||
];
|
||||
|
||||
expect(() => processor.$process(docs)).toThrowError('Stopping due to content errors.');
|
||||
|
||||
expect(logger.error).toHaveBeenCalledTimes(2);
|
||||
expect(logger.error).toHaveBeenCalledWith('Content contains errors');
|
||||
expect(logger.error).toHaveBeenCalledWith(`name error message
|
||||
@ -92,17 +119,4 @@ describe('checkContentRules processor', function() {
|
||||
- doc "test-1" (test1) `);
|
||||
});
|
||||
|
||||
it('should throw an error if `failOnContentErrors` is true and errors are found', () => {
|
||||
const errorRule = jasmine.createSpy('error rule').and.returnValue('some error');
|
||||
processor.docTypeRules = {
|
||||
'test': { description: [errorRule] }
|
||||
};
|
||||
processor.failOnContentErrors = true;
|
||||
|
||||
const docs = [
|
||||
{ docType: 'test', description: 'test doc' },
|
||||
];
|
||||
expect(() => processor.$process(docs)).toThrowError('Stopping due to content errors.');
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -9,7 +9,7 @@ describe('hasValues filter', () => {
|
||||
|
||||
it('should return true if the specified property is truthy on any item in the list', function() {
|
||||
expect(filter.process([], 'a')).toEqual(false);
|
||||
expect(filter.process(0), 'a').toEqual(false);
|
||||
expect(filter.process(0, 'a')).toEqual(false);
|
||||
expect(filter.process({}, 'a')).toEqual(false);
|
||||
expect(filter.process([{a: 1}], 'a')).toEqual(true);
|
||||
expect(filter.process([{b: 2}], 'a')).toEqual(false);
|
||||
|
@ -96,5 +96,19 @@ module.exports = {
|
||||
attrMap[key] === false ? '' :
|
||||
attrMap[key] === true ? ` ${key}` :
|
||||
` ${key}="${attrMap[key].replace(/"/g, '"')}"`).join('');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Merge the specified properties from the source to the target document
|
||||
* @param {Document} target The document to receive the properties from the source
|
||||
* @param {Document} source The document from which to get the properties to merge
|
||||
* @param {string[]} properties A collection of the names of the properties to merge
|
||||
*/
|
||||
mergeProperties(target, source, properties) {
|
||||
properties.forEach(property => {
|
||||
if (source.hasOwnProperty(property)) {
|
||||
target[property] = source[property];
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
const { mapObject, parseAttributes, renderAttributes } = require('./utils');
|
||||
const { mergeProperties, mapObject, parseAttributes, renderAttributes } = require('./utils');
|
||||
|
||||
describe('utils', () => {
|
||||
describe('mapObject', () => {
|
||||
@ -96,4 +96,34 @@ describe('utils', () => {
|
||||
expect(renderAttributes({ })).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('mergeProperties', () => {
|
||||
it('should write specified properties from the source to the target', () => {
|
||||
const source = { a: 1, b: 2, c: 3 };
|
||||
const target = { };
|
||||
mergeProperties(target, source, ['a', 'b']);
|
||||
expect(target).toEqual({ a: 1, b: 2 });
|
||||
});
|
||||
|
||||
it('should not overwrite target properties that are not specified', () => {
|
||||
const source = { a: 1, b: 2, c: 3 };
|
||||
const target = { b: 10 };
|
||||
mergeProperties(target, source, ['a']);
|
||||
expect(target).toEqual({ a: 1, b: 10 });
|
||||
});
|
||||
|
||||
it('should not overwrite target properties that are specified but do not exist in the source', () => {
|
||||
const source = { a: 1 };
|
||||
const target = { b: 10 };
|
||||
mergeProperties(target, source, ['a', 'b']);
|
||||
expect(target).toEqual({ a: 1, b: 10 });
|
||||
});
|
||||
|
||||
it('should overwrite target properties even if they are `undefined` in the source', () => {
|
||||
const source = { a: undefined };
|
||||
const target = { a: 10 };
|
||||
mergeProperties(target, source, ['a']);
|
||||
expect(target).toEqual({ a: undefined });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -8,16 +8,20 @@ module.exports =
|
||||
.factory(require('./services/getAliases'))
|
||||
.factory(require('./services/getDocFromAlias'))
|
||||
.factory(require('./services/getLinkInfo'))
|
||||
.factory(require('./services/disambiguators/disambiguateByContainer'))
|
||||
.factory(require('./services/disambiguators/disambiguateByDeprecated'))
|
||||
.factory(require('./services/disambiguators/disambiguateByModule'))
|
||||
.factory(require('./services/disambiguators/disambiguateByNonMember'))
|
||||
|
||||
.config(function(inlineTagProcessor, linkInlineTagDef) {
|
||||
inlineTagProcessor.inlineTagDefinitions.push(linkInlineTagDef);
|
||||
})
|
||||
|
||||
.config(function(getDocFromAlias, disambiguateByDeprecated, disambiguateByModule) {
|
||||
.config(function(getDocFromAlias, disambiguateByContainer, disambiguateByDeprecated, disambiguateByModule, disambiguateByNonMember) {
|
||||
getDocFromAlias.disambiguators = [
|
||||
disambiguateByContainer,
|
||||
disambiguateByDeprecated,
|
||||
disambiguateByModule
|
||||
disambiguateByModule,
|
||||
disambiguateByNonMember,
|
||||
];
|
||||
});
|
||||
|
@ -14,7 +14,6 @@ var INLINE_LINK = /(\S+)(?:\s+([\s\S]+))?/;
|
||||
module.exports = function linkInlineTagDef(getLinkInfo, createDocMessage, log) {
|
||||
return {
|
||||
name: 'link',
|
||||
aliases: ['linkDocs'],
|
||||
failOnBadLink: false,
|
||||
description:
|
||||
'Process inline link tags (of the form {@link some/uri Some Title}), replacing them with HTML anchors',
|
||||
|
@ -19,7 +19,6 @@ describe('link inline-tag-def', function() {
|
||||
it('should be available as a service', () => {
|
||||
expect(tag).toBeDefined();
|
||||
expect(tag.name).toEqual('link');
|
||||
expect(tag.aliases).toEqual(['linkDocs']);
|
||||
});
|
||||
|
||||
it('should call getLinkInfo', () => {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user