Skip to content

Commit 3296602

Browse files
hanslfilipesilva
authored andcommitted
docs: re-add angular/cli docs which were deleted when syncing devkit
1 parent fab5007 commit 3296602

File tree

117 files changed

+10522
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+10522
-0
lines changed

docs/design/deployurl-basehref.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
| | Deploy URL | Base HREF |
2+
|--|:--:|:--:|
3+
| Initial scripts (index.html) | ✅ 👍 | ✅ 👍 |
4+
| Initial stylesheets (index.html) | ✅ 👍 | ✅ 👍 |
5+
| Lazy scripts (routes/import()/etc.) | ✅ 👍 | ✅ 👍 |
6+
| Processed CSS resources (images/fonts/etc.) | ✅ 👍 | ✅ 👍 |
7+
| Relative template (HTML) assets | ❌ 👎 | ✅ 👍 |
8+
| Angular Router Default Base (APP_BASE_HREF) ||*1 |
9+
| Single reference in deployed Application | ❌ 👎 | ✅ 👍 |
10+
| Special resource logic within CLI | ✅ 👎 | ❌ 👍 |
11+
| Relative fetch/XMLHttpRequest |||
12+
13+
✅ - has/affects the item/trait
14+
❌ - does not have/affect the item/trait
15+
👍 - favorable behavior
16+
👎 - unfavorable behavior
17+
18+
*1 -- Users with more complicated setups may need to manually configure the `APP_BASE_HREF` token within the application. (e.g., application routing base is `/` but assets/scripts/etc. are at `/assets/`)

docs/design/docker-deploy.md

+454
Large diffs are not rendered by default.

docs/design/ngConfig.md

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# ngConfig - Design
2+
3+
## Goals
4+
5+
Currently, a project scaffolded with the CLI have no way of specifying options and configurations affecting their projects. There are ways to affect the build (with the `angular-cli-build.js` file), but the following questions cannot be answered without actual project options:
6+
7+
* Where in my directory is my karma.conf file?
8+
* What is my firebase database URL?
9+
* Where is my client code?
10+
* How can I use a different lazy-loading boundary prefix (or none at all)?
11+
* Any other backend I want to run prior to `ng serve`?
12+
13+
# Proposed Solution
14+
15+
Since the data is static, we only need to keep it in a static store somewhere.
16+
17+
One solution would be to keep the data in the `package.json`. Unfortunately, the metadata contains too much data and the `package.json` file would become unmanageable.
18+
19+
Instead of polluting the package file, a `.angular-cli.json` file will be created that contains all the values. Access to that file will be allowed to the user if he knows the structure of the file (unknown keys will be kept but ignored), and it's easy to read and write.
20+
21+
22+
## Fallback
23+
24+
There should be two `.angular-cli.json` files; one for the project and a general one. The general one should contain information that can be useful when scaffolding new apps, or informations about the user.
25+
26+
The project `.angular-cli.json` goes into the project root. The global configuration should live at `$HOME/.angular-cli.json`.
27+
28+
## Structure
29+
30+
The structure should be defined by a JSON schema (see [here](http://json-schema.org/)). The schema will be used to generate the `d.ts`, but that file will be kept in the file system along the schema for IDEs.
31+
32+
Every PR that would change the schema should include the update to the `d.ts`.
33+
34+
# API
35+
36+
## CLI
37+
38+
#### Getting values
39+
40+
The new command `get` should be used to output values on the terminal. It takes a set of flags and an optional array of [paths](#path);
41+
42+
* `--glob` or `-g`; the path follows a glob format, where `*` can be replaced by any amount of characters and `?` by a single character. This will output `name=value` for each values matched.
43+
44+
Otherwise, outputs the value of the path passed in. If multiple paths are passed in, they follow the format of `name=value`.
45+
46+
#### Setting values
47+
48+
The new command `set` should be used to set values in the local configuration file. It takes a set of flags and an optional array of `[path](#path)=value`;
49+
50+
* `--global`; sets the value in the global configuration.
51+
* `--remove`; removes the key (no value should be passed in).
52+
53+
The schema needs to be taken into account when setting the value of the field;
54+
55+
* If the field is a number, the string received from the command line is parsed. `NaN` throws an error.
56+
* If the field is an object, an error is thrown.
57+
* If the path is inside an object but the object hasn't been defined yet, sets the object with empty values (use the schema to create a valid object).
58+
59+
#### Path<a name="path"></a>
60+
61+
The paths are json formatted path; each `.` separates a map, while `[]` indicates an index in an array.
62+
63+
An example is the following:
64+
65+
keyA.keyB.arrayC[3].value
66+
67+
## Model
68+
69+
A model should be created that will include loading and saving the configuration, including the global configuration.
70+
71+
**The model should be part of the project and created on the `project` object.**
72+
73+
That model can be used internally by the tool to get information. It will include a proxy handler that throws if an operation doesn't respect the schema. It will also sets values on globals and locals depending on which branches you access.
74+
75+
A simple API would return the TypeScript interface:
76+
77+
```typescript
78+
class Config {
79+
// ...
80+
get local(): ICliConfig { /* ... */ }
81+
get global(): ICliConfig { /* ... */ }
82+
}
83+
```
84+
85+
The `local` and `global` getters return proxies that respect the JSON Schema defined for the Angular config. These proxies allow users to not worry about the existence of values; those values will only be created on disc when they are setted.
86+
87+
Also, `local` will always defer to the same key-path in `global` if a value isn't available. If a value is set and the parent exists in `global`, it should be created to `local` such that it's saved locally to the project. The proxies only care about the end points of `local` and `global`, not the existence of a parent in either.
88+
89+
For example, assuming the following globals/locals:
90+
91+
```js
92+
// Global
93+
{
94+
"key1": {
95+
"key2": {
96+
"value": 0,
97+
"value2": 1
98+
}
99+
}
100+
}
101+
102+
// Local
103+
{
104+
"key1": {
105+
"key2": {
106+
"value2": 2,
107+
"value3": 3
108+
}
109+
}
110+
}
111+
```
112+
113+
The following stands true:
114+
115+
```typescript
116+
const config = new Config(/* ... */);
117+
118+
console.log(config.local.key1.key2.value); // 0, even if it doesn't exist.
119+
console.log(config.local.key1.key2.value2); // 2, local overrides.
120+
console.log(config.local.key1.key2.value3); // 3.
121+
console.log(config.local.key1.key2.value4); // Schema's default value.
122+
123+
console.log(config.global.key1.key2.value); // 0.
124+
console.log(config.global.key1.key2.value2); // 1, only global.
125+
console.log(config.global.key1.key2.value3); // Schema's default value.
126+
127+
config.local.key1.key2.value = 1;
128+
// Now the value is 1 inside the local. Global stays the same.
129+
130+
config.local.key1.key2.value3 = 5;
131+
// The global config isn't modified.
132+
133+
config.global.key1.key2.value4 = 99;
134+
// The local config stays the same.
135+
console.log(config.local.key1.key2.value4); // 99, the global value.
136+
137+
config.save(); // Commits if there's a change to global and/or local.
138+
```

docs/design/third-party-libraries.md

+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# Installing third party libraries
2+
3+
# Abstract
4+
5+
The current `ng install` process is faulty; third parties have to add a `bundles/` directory
6+
with metadata that we expect. This document explores ways to improve on the process.
7+
8+
# Requirements
9+
10+
The following use cases need to be supported by `ng install`:
11+
12+
1. Support for _any_ thirdparties, ultimately falling back to running `npm install` only and
13+
doing nothing else, if necessary.
14+
1. Not a new package manager.
15+
1. Metadata storage by thirdparties in `package.json`. This must be accessible by plugins for
16+
the build process or even when scaffolding.
17+
1. Proper configuration of SystemJs in the browser.
18+
1. SystemJS configuration managed by the user needs to be kept separated from the autogenerated
19+
part.
20+
1. The build process right now is faulty because the `tmp/` directory used by Broccoli is
21+
inside the project. TypeScript when using `moduleResolution: "node"` can resolve the
22+
`node_modules` directory (since it's in an ancestor folder), which means that TypeScript
23+
compiles properly, but the build does not copy files used by TypeScript to `dist/`. We need
24+
to proper map the imports and move them to `tmp` before compiling, then to `dist/` properly.
25+
1. Potentially hook into scaffolding.
26+
1. Potentially hook into the build.
27+
1. Safe uninstall path.
28+
29+
# Usages
30+
31+
Here's a few stories that should work right off:
32+
33+
```sh
34+
$ ng new my-app && cd my-app/
35+
$ ng install jquery
36+
```
37+
^(this makes jQuery available in the index)
38+
39+
```sh
40+
$ ng install angularfire2
41+
> Please specify your Firebase database URL [my-app.firebaseio.com]: _
42+
```
43+
^(makes firebase available and provided to the App)
44+
45+
```sh
46+
$ ng install angularfire2 --dbUrl=my-firebase-db.example.com
47+
```
48+
^(skip prompts for values passed on the command line)
49+
50+
```sh
51+
$ ng install angularfire2 --quiet
52+
```
53+
^(using `--quiet` to skip all prompts and use default values)
54+
55+
```sh
56+
$ ng install less
57+
```
58+
^(now compiles CSS files with less for the appropriate extensions)
59+
60+
# Proposed Solution
61+
62+
The `install` task will perform the following subtasks:
63+
64+
1. **Run `npm install ${libName}`.** On failure, fail the install process.
65+
1. **Run `preinstall` scripts.** If any script fails, run `npm uninstall ${libName}` and fail
66+
the install process.
67+
1. **Copy the `appData` to the `angular.json` file of the generated app, creating it if it
68+
doesn't exist, under the `"modules"` key.** This data will be sent to the App as is. See the
69+
[appData](#appData) section for more information.
70+
1. **Read the `package["angular-cli"].appPrompt` and prompt the user configuration values,
71+
if any.** See the [appData](#appData) section for more information.
72+
1. **Add the providers specified in `package["angular-cli"]["providers"]` to the angular.js
73+
`providers` list.** Rebuild the `providers.js` file. See the [Providers](#providers)
74+
section for more information.
75+
1. **Run `package["angular-cli"].scripts["install"]` if it exists.** If the script fails,
76+
run `npm uninstall ${libName}` and fail the install process.
77+
1. **Detect if a package named `angular/cli-wrapper-${libName}` exist in the angular
78+
organization.** If so, run the steps above as if ng install angular/angular-${libName}. If
79+
this install fails, ignore the failure.
80+
81+
These packages can be used to wrap libraries that we want to support but can't update
82+
easily, like Jasmine or LESS.
83+
1. **Install typings.** See the [Typings](#typings) section.
84+
1. **Run `postinstall` scripts.**
85+
86+
# Proof of Concept
87+
A proof of concept is being developed.
88+
89+
# Hooks
90+
The third party library can implement hooks into the scaffolding, and the build system. The
91+
CLI's tasks will look for the proper hooks prior to running and execute them.
92+
93+
The order of execution of these hooks is breadth first, going through all node packages and
94+
checking for the `package['angular-cli']['hooks']['${hookName}']`. The hooks are then
95+
`require()`'d as is, from within the app root folder. Within the same level of the dependency
96+
tree, there is no guarantee for the order of execution.
97+
98+
## Install Hooks
99+
The only tricky part here is install hooks. The installed package should recursively call
100+
its `(pre|post|)install` hooks only on packages that are newly installed. It should call
101+
`(pre|post|)reinstall` on those who were already installed. A map of the currently installed
102+
packages should be kept before performing `npm install`.
103+
104+
# <a name="appData">appData</a>
105+
The `angular-cli` key in the generated app should be used for Angular CLI specific data.
106+
This includes the CLI configuration itself, as well as third-parties library configuration.
107+
108+
Third-parties can store data that will be passed to the app, and can use that data themselves.
109+
That data can be anything. Any keys starting with either `$` or `_` will be ignored and not
110+
passed to the client. It could be used for builds or scaffolding information.
111+
112+
During installation, there's a step to prompt the user for data. The schema contains a prompt
113+
text and a default value. The default value type is used to convert the string entered by the
114+
user. The key used in `appPrompt` is the key saved in appData.
115+
116+
Example:
117+
118+
```typescript
119+
{ // ...
120+
"angular-cli": {
121+
"appPrompt": {
122+
"number": {
123+
"prompt": "Please enter a number:",
124+
"defaultValue": 0
125+
},
126+
"url": {
127+
"prompt": "URL of your website:",
128+
"defaultValue": "${homepage}"
129+
}
130+
}
131+
}
132+
}
133+
```
134+
135+
The default value is necessary as a `quiet` mode is enforced, using default values to fill
136+
in the data without user interaction. The special strings `${...}` can be used to replace
137+
with special values in the default string values. The values are taken from the `package.json`.
138+
139+
We use a declarative style to enforce sensible defaults and make sure developers think about
140+
this. *In the case where developers want more complex interaction, they can use the
141+
install/uninstall hooks to prompt users.* But 3rd party libraries developers need to be aware
142+
that those hooks might not prompt users (no STDIN) and throw an error.
143+
144+
# <a name="providers">Providers</a>
145+
Adding Angular providers to the app should be seamless. The install process will create a
146+
`providers.js` from all the providers contained in all the dependencies. The User can blacklist
147+
providers it doesn't want.
148+
149+
The `providers.js` file will always be overwritten by the `install` / `uninstall` process. It
150+
needs to exist for toolings to be able to understand dependencies. These providers are global
151+
to the application.
152+
153+
In order to blacklist providers from being global, the user can use the `--no-global-providers`
154+
flag during installation, or can change the dependencies by using `ng providers`. As an example:
155+
156+
```bash
157+
ng new my-todo-app
158+
ng generate component database
159+
ng install --no-global-providers angularfirebase2
160+
ng providers database angularfirebase2
161+
```
162+
163+
Or, alternatively, the user can add its own providers and dependencies to its components.
164+
165+
# Dependencies
166+
Because dependencies are handled by `npm`, we don't have to handle it.
167+
168+
# <a name="typings">Typings</a>
169+
Typings should be added, but failure to find typings should not be a failure of installation. The
170+
user might still want to install custom typings himself in the worst case.
171+
172+
The `typings` package can be used to install/verify that typings exist. If the typings do not exist natively, we should tell the user to install the ambient version if he wants to.
173+
174+
# Index.html
175+
We do not touch the `index.html` file during the installation task. The default page should
176+
link to a SystemJS configuration file that is auto generated by the CLI and not user
177+
configurable (see SystemJS below). If the user install a third party library, like jQuery, and
178+
wants to use it, they have to import it using `import * as $ from 'vendor/jquery'`.
179+
180+
The `index.html` also includes a section to configure SystemJS that can be managed by the user.
181+
This is separate from the generated code.
182+
183+
# SystemJS
184+
It is important that SystemJS works without any modifications by the user. It is also important
185+
to leave the liberty to the user to change the SystemJS configuration so that it fits their needs.
186+
187+
We will not use SystemJS bundles in development. This is for better debugging, future proofing
188+
(when moving the build system) and better CDN support, as many of the loaded files will end up
189+
being pulled from a CDN in production. During the `ng build` process for production, the
190+
SystemJS configuration script will be rebuilt to fetch from the CDN.
191+
192+
# Upgrade Strategy
193+
The upgrade process simply uses NPM. If new appData is added, it should be added manually using
194+
a migration hook for `postinstall`.
195+
196+
# Remaining Problems
197+
198+
1. Installing dependencies of packages need to be further sketched out.
199+
2. Need to add a fully fledged example with Firebase.

0 commit comments

Comments
 (0)