docs: add schematics guide (#28343)

PR Close #28343
This commit is contained in:
Judy Bogart
2019-03-19 15:47:14 -04:00
committed by Matias Niemelä
parent a3ec058f6b
commit bc99b774ba
37 changed files with 1295 additions and 18 deletions
+3
View File
@@ -92,3 +92,6 @@ upgrade-phonecat-3-final/tsconfig-aot.json
upgrade-phonecat-3-final/rollup-config.js
!upgrade-phonecat-*/**/karma.conf.js
!upgrade-phonecat-*/**/karma-test-shim.js
# schematics
!schematics-for-libraries/projects/my-lib/package.json
@@ -0,0 +1,3 @@
{
"projectType": "schematics"
}
@@ -0,0 +1,7 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/my-lib",
"lib": {
"entryFile": "src/public_api.ts"
}
}
@@ -0,0 +1,20 @@
// #docplaster
// #docregion collection
{
"name": "my-lib",
"version": "0.0.1",
// #enddocregion collection
"scripts": {
"build": "../../node_modules/.bin/tsc -p tsconfig.schematics.json",
"copy:schemas": "cp --parents schematics/*/schema.json ../../dist/my-lib/",
"copy:files": "cp --parents -p schematics/*/files/** ../../dist/my-lib/",
"copy:collection": "cp schematics/collection.json ../../dist/my-lib/schematics/collection.json",
"postbuild": "npm run copy:schemas && npm run copy:files && npm run copy:collection"
},
"peerDependencies": {
"@angular/common": "^7.2.0",
"@angular/core": "^7.2.0"
},
// #docregion collection
"schematics": "./schematics/collection.json"
}
@@ -0,0 +1,9 @@
{
"$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"ng-add": {
"description": "Add my library to the project.",
"factory": "./ng-add/index#ngAdd"
}
}
}
@@ -0,0 +1,14 @@
{
"$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"ng-add": {
"description": "Add my library to the project.",
"factory": "./ng-add/index#ngAdd"
},
"my-service": {
"description": "Generate a service in the project.",
"factory": "./my-service/index#myService",
"schema": "./my-service/schema.json"
}
}
}
@@ -0,0 +1,10 @@
// #docregion template
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class <%= classify(name) %>Service {
constructor(private http: HttpClient) { }
}
@@ -0,0 +1,11 @@
import { Rule, Tree } from '@angular-devkit/schematics';
import { Schema as MyServiceSchema } from './schema';
// #docregion factory
export function myService(options: MyServiceSchema): Rule {
return (tree: Tree) => {
return tree;
};
}
// #enddocregion factory
@@ -0,0 +1,66 @@
// #docplaster
// #docregion schematics-imports, schema-imports, workspace
import {
Rule, Tree, SchematicsException,
apply, url, applyTemplates, move,
chain, mergeWith
} from '@angular-devkit/schematics';
import { strings, normalize, experimental } from '@angular-devkit/core';
// #enddocregion schematics-imports
import { Schema as MyServiceSchema } from './schema';
// #enddocregion schema-imports
export function myService(options: MyServiceSchema): Rule {
return (tree: Tree) => {
const workspaceConfig = tree.read('/angular.json');
if (!workspaceConfig) {
throw new SchematicsException('Could not find Angular workspace configuration');
}
// convert workspace to string
const workspaceContent = workspaceConfig.toString();
// parse workspace string into JSON object
const workspace: experimental.workspace.WorkspaceSchema = JSON.parse(workspaceContent);
// #enddocregion workspace
// #docregion project-fallback
if (!options.project) {
options.project = workspace.defaultProject;
}
// #enddocregion project-fallback
// #docregion project-info
const projectName = options.project as string;
const project = workspace.projects[projectName];
const projectType = project.projectType === 'application' ? 'app' : 'lib';
// #enddocregion project-info
// #docregion path
if (options.path === undefined) {
options.path = `${project.sourceRoot}/${projectType}`;
}
// #enddocregion path
// #docregion template
const templateSource = apply(url('./files'), [
applyTemplates({
classify: strings.classify,
dasherize: strings.dasherize,
name: options.name
}),
move(normalize(options.path as string))
]);
// #enddocregion template
// #docregion chain
return chain([
mergeWith(templateSource)
]);
// #enddocregion chain
// #docregion workspace
};
}
@@ -0,0 +1,28 @@
{
"$schema": "http://json-schema.org/schema",
"id": "SchematicsMyService",
"title": "My Service Schema",
"type": "object",
"properties": {
"name": {
"description": "The name of the service.",
"type": "string"
},
"path": {
"type": "string",
"format": "path",
"description": "The path to create the service.",
"visible": false
},
"project": {
"type": "string",
"description": "The name of the project.",
"$default": {
"$source": "projectName"
}
}
},
"required": [
"name"
]
}
@@ -0,0 +1,10 @@
export interface Schema {
// The name of the service.
name: string;
// The path to create the service.
path?: string;
// The name of the project.
project?: string;
}
@@ -0,0 +1,10 @@
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
// Just return the tree
export function ngAdd(_options: any): Rule {
return (tree: Tree, _context: SchematicContext) => {
_context.addTask(new NodePackageInstallTask());
return tree;
};
}
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MyLibComponent } from './my-lib.component';
describe('MyLibComponent', () => {
let component: MyLibComponent;
let fixture: ComponentFixture<MyLibComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MyLibComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyLibComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,19 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'lib-my-lib',
template: `
<p>
my-lib works!
</p>
`,
styles: []
})
export class MyLibComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
@@ -0,0 +1,10 @@
import { NgModule } from '@angular/core';
import { MyLibComponent } from './my-lib.component';
@NgModule({
declarations: [MyLibComponent],
imports: [
],
exports: [MyLibComponent]
})
export class MyLibModule { }
@@ -0,0 +1,12 @@
import { TestBed } from '@angular/core/testing';
import { MyLibService } from './my-lib.service';
describe('MyLibService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: MyLibService = TestBed.get(MyLibService);
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,9 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyLibService {
constructor() { }
}
@@ -0,0 +1,7 @@
/*
* Public API Surface of my-lib
*/
export * from './lib/my-lib.service';
export * from './lib/my-lib.component';
export * from './lib/my-lib.module';
@@ -0,0 +1,32 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/lib",
"target": "es2015",
"module": "es2015",
"moduleResolution": "node",
"declaration": true,
"sourceMap": true,
"inlineSources": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"types": [],
"lib": [
"dom",
"es2018"
]
},
"angularCompilerOptions": {
"annotateForClosureCompiler": true,
"skipTemplateCodegen": true,
"strictMetadataEmit": true,
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true,
"enableResourceInlining": true
},
"exclude": [
"src/test.ts",
"**/*.spec.ts"
]
}
@@ -0,0 +1,35 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": [
"es2018",
"dom"
],
"declaration": true,
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"rootDir": "schematics",
"outDir": "../../dist/my-lib/schematics",
"skipDefaultLibCheck": true,
"skipLibCheck": true,
"sourceMap": true,
"strictNullChecks": true,
"target": "es6",
"types": [
"jasmine",
"node"
]
},
"include": [
"schematics/**/*"
],
"exclude": [
"schematics/*/files/**/*"
]
}
@@ -0,0 +1,17 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": [
"jasmine",
"node"
]
},
"files": [
"src/test.ts"
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}
@@ -0,0 +1,12 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<h2>Library Schematics</h2>
`,
styles: []
})
export class AppComponent {
title = 'schematics-for-libraries';
}
@@ -0,0 +1,16 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>SchematicsForLibraries</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
@@ -0,0 +1,12 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
@@ -0,0 +1,10 @@
{
"description": "Schematics For Libraries",
"files": [
"!**/*.d.ts",
"!**/*.js",
"!**/*.[1].*",
"**/*.template"
],
"tags": ["Angular", "Libraries", "Schematics"]
}
+194
View File
@@ -0,0 +1,194 @@
# Authoring Schematics
You can create your own schematics to operate on Angular projects.
Library developers typically package schematics with their libraries in order to integrate them with the Angular CLI.
You can also create stand-alone schematics to manipulate the files and constructs in Angular applications as a way of customizing them for your development environment and making them conform to your standards and constraints.
Schematics can be chained, running other schematics to perform complex operations.
Manipulating the code in an application has the potential to be both very powerful and correspondingly dangerous.
For example, creating a file that already exists would be an error, and if it was applied immediately, it would discard all the other changes applied so far.
The Angular Schematics tooling guards against side effects and errors by creating a virtual file system.
A schematic describes a pipeline of transformations that can be applied to the virtual file system.
When a schematic runs, the transformations are recorded in memory, and only applied in the real file system once they're confirmed to be valid.
## Schematics concepts
The public API for schematics defines classes that represent the basic concepts.
* The virtual file system is represented by a `Tree`. The `Tree` data structure contains a *base* (a set of files that already exists) and a *staging area* (a list of changes to be applied to the base).
When making modifications, you don't actually change the base, but add those modifications to the staging area.
* A `Rule` object defines a function that takes a `Tree`, applies transformations, and returns a new `Tree`. The main file for a schematic, `index.ts`, defines a set of rules that implement the schematic's logic.
* A transformation is represented by an `Action`. There are four action types: `Create`, `Rename`, `Overwrite`, and `Delete`.
* Each schematic runs in a context, represented by a `SchematicContext` object.
The context object passed into a rule provides access to utility functions and metadata that the schematic may need to work with, including a logging API to help with debugging.
The context also defines a *merge strategy* that determines how changes are merged from the staged tree into the base tree. A change can be accepted or ignored, or throw an exception.
### Defining rules and actions
When you create a new blank schematic with the [Schematics CLI](#cli), the generated entry function is a *rule factory*.
A `RuleFactory`object defines a higher-order function that creates a `Rule`.
<code-example language="TypeScript" linenums="false">
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
// You don't have to export the function as default.
// You can also have more than one rule factory per file.
export function helloWorld(_options: any): Rule {
return (tree: Tree, _context: SchematicContext) => {
return tree;
};
}
</code-example>
Your rules can make changes to your projects by calling external tools and implementing logic.
You need a rule, for example, to define how a template in the schematic is to be merged into the hosting project.
Rules can make use of utilities provided with the `@schematics/angular` package. Look for helper functions for working with modules, dependencies, TypeScript, AST, JSON, Angular CLI workspaces and projects, and more.
<code-example language="none" linenums="false">
import {
JsonAstObject,
JsonObject,
JsonValue,
Path,
normalize,
parseJsonAst,
strings,
} from '&#64;angular-devkit/core';
</code-example>
### Defining input options with a schema and interfaces
Rules can collect option values from the caller and inject them into templates.
The options available to your rules, with their allowed values and defaults, are defined in the schematic's JSON schema file, `<schematic>/schema.json`.
You can define variable or enumerated data types for the schema using TypeScript interfaces.
You can see examples of schema files for the Angular CLI command schematics in [`@schematics/angular`](https://github.com/angular/angular-cli/blob/7.0.x/packages/schematics/angular/application/schema.json).
{@a cli}
## Schematics CLI
Schematics come with their own command-line tool.
Using Node 6.9 or above, install the Schematics command line tool globally:
<code-example language="bash" linenums="false">
npm install -g @angular-devkit/schematics-cli
</code-example>
This installs the `schematics` executable, which you can use to create a new schematics collection in its own project folder, add a new schematic to an existing collection, or extend an existing schematic.
In the following sections, we will create a new schematics collection using the CLI in order to introduce the files and file structure, and some of the basic concepts.
The most common use of schematics, however, is to integrate an Angular library with the Angular CLI.
You can do this by creating the schematic files directly within the library project in an Angular workspace, without using the Schematics CLI.
See [Schematics for Libraries](guide/schematics-for-libraries).
### Creating a schematics collection
The following command creates a new schematic named `hello-world` in a new project folder of the same name.
<code-example language="bash" linenums="false">
schematics blank --name=hello-world
</code-example>
The `blank` schematic is provided by the Schematics CLI. The command creates a new project folder (the root folder for the collection) and an initial named schematic in the collection.
Go to the collection folder, install your npm dependencies, and open your new collection in your favorite editor to see the generated files. For example, if you are using VSCode:
<code-example language="bash" linenums="false">
cd hello-world
npm install
npm run build
code .
</code-example>
The initial schematic gets the same name as the project folder, and is generated in `src/hello-world`.
You can add related schematics to this collection, and modify the generated skeleton code to define your schematic's functionality.
Each schematic name must be unique within the collection.
### Running a schematic
Use the `schematics` command to run a named schematic.
Provide the path to the project folder, the schematic name, and any mandatory options, in the following format.
<code-example language="bash" linenums="false">
schematics &lt;path-to-schematics-project&gt;:&lt;schematics-name&gt; --&lt;required-option&gt;=&lt;value&gt;
</code-example>
The path can be absolute or relative to the current working directory where the command is executed.
For example, to run the schematic we just generated (which has no required options), use the following command.
<code-example language="bash" linenums="false">
schematics .:hello-world
</code-example>
### Adding a schematic to a collection
To add a schematic to an existing collection, use the same command you use to start a new schematics project, but run the command inside the project folder.
<code-example language="bash" linenums="false">
cd hello-world
schematics blank --name=goodbye-world
</code-example>
The command generates the new named schematic inside your collection, with a main `index.ts` file and its associated test spec.
It also adds the name, description, and factory function for the new schematic to the collection's schema in the `collection.json` file.
## Collection contents
The top level of the root project folder for a collection contains configuration files, a `node_modules` folder, and a `src/` folder.
The `src/` folder contains subfolders for named schematics in the collection, and a schema, `collection.json`, which describes the collected schematics.
Each schematic is created with a name, description, and factory function.
<code-example language="none" linenums="false">
{
"$schema":
"../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"hello-world": {
"description": "A blank schematic.",
"factory": "./hello-world/index#helloWorld"
}
}
}
</code-example>
* The `$schema` property specifies the schema that the CLI uses for validation.
* The `schematics` property lists named schematics that belong to this collection.
Each schematic has a plain-text description, and points to the generated entry function in the main file.
* The `factory` property points to the generated entry function. In this example, you invoke the `hello-world` schematic by calling the `helloWorld()` factory function.
* The optional `schema` property points to a JSON schema file that defines the command-line options available to the schematic.
* The optional `aliases` array specifies one or more strings that can be used to invoke the schematic.
For example, the schematic for the Angular CLI “generate” command has an alias “g”, allowing you to use the command `ng g`.
### Named schematics
When you use the Schematics CLI to create a blank schematics project, the new blank schematic is the first member of the collection, and has the same name as the collection.
When you add a new named schematic to this collection, it is automatically added to the `collection.json` schema.
In addition to the name and description, each schematic has a `factory` property that identifies the schematic’s entry point.
In the example, you invoke the schematic's defined functionality by calling the `helloWorld()` function in the main file, `hello-world/index.ts`.
<figure>
<img src="generated/images/guide/schematics/collection-files.gif" alt="overview">
</figure>
Each named schematic in the collection has the following main parts.
| | |
| :------------- | :-------------------------------------------|
| `index.ts` | Code that defines the transformation logic for a named schematic. |
| `schema.json` | Schematic variable definition. |
| `schema.d.ts` | Schematic variables. |
| `files/` | Optional component/template files to replicate. |
It is possible for a schematic to provide all of its logic in the `index.ts` file, without additional templates.
You can create dynamic schematics for Angular, however, by providing components and templates in the `files/` folder, like those in standalone Angular projects.
The logic in the index file configures these templates by defining rules that inject data and modify variables.
File diff suppressed because it is too large Load Diff
+121
View File
@@ -0,0 +1,121 @@
# Schematics
A schematic is a template-based code generator that supports complex logic.
It is a set of instructions for transforming a software project by generating or modifying code.
Schematics are packaged into [collections](guide/glossary#collection) and installed with npm.
The schematic collection can be a powerful tool for creating, modifying, and maintaining any software project, but is particularly useful for customizing Angular projects to suit the particular needs of your own organization.
You might use schematics, for example, to generate commonly-used UI patterns or specific components, using predefined templates or layouts.
You can use schematics to enforce architectural rules and conventions, making your projects consistent and inter-operative.
## Schematics for the Angular CLI
Schematics are part of the Angular ecosystem. The [Angular CLI](guide/glossary#cli) uses schematics to apply transforms to a web-app project.
You can modify these schematics, and define new ones to do things like update your code to fix breaking changes in a dependency, for example, or to add a new configuration option or framework to an existing project.
Schematics that are included in the `@schematics/angular` collection are run by default by the commands `ng generate` and `ng add`.
The package contains named schematics that configure the options that are available to the CLI for `ng generate` sub-commands, such as `ng generate component` and `ng generate service`.
The subcommands for `ng generate` are shorthand for the corresponding schematic. You can specify a particular schematic (or collection of schematics) to generate, using the long form:
<code-example language="bash" linenums="false">
ng generate my-schematic-collection:my-schematic-name
</code-example>
&mdash;or&mdash;
<code-example language="bash" linenums="false">
ng generate my-schematic-name --collection collection-name
</code-example>
### Configuring CLI schematics
A JSON schema associated with a schematic tells the Angular CLI what options are available to commands and subcommands, and determines the defaults.
These defaults can be overridden by providing a different value for an option on the command line.
See [Workspace Configuration](guide/workspace-config) for information about how you can change the generation option defaults for your workspace.
The JSON schemas for the default schematics used by the CLI to generate projects and parts of projects are collected in the package [`@schematics/angular`](https://raw.githubusercontent.com/angular/angular-cli/v7.0.0/packages/schematics/angular/application/schema.json).
The schema describes the options available to the CLI for each of the `ng generate` sub-commands, as shown in the `--help` output.
## Developing schematics for libraries
As a library developer, you can create your own collections of custom schematics to integrate your library with the Angular CLI.
* An *add schematic* allows developers to install your library in an Angular workspace using `ng add`.
* *Generation schematics* can tell the `ng generate` subcommands how to modify projects, add configurations and scripts, and scaffold artifacts that are defined in your library.
* An *update schematic* can tell the `ng update` command how to update your library's dependencies and adjust for breaking changes when you release a new version.
For more details of what these look like and how to create them, see:
* [Authoring Schematics](guide/schematics-authoring)
* [Schematics for Libraries](guide/schematics-for-libraries)
### Add schematics
An add schematic is typically supplied with a library, so that the library can be added to an existing project with `ng add`.
The `add` command uses your package manager to download new dependencies, and invokes an installation script that is implemented as a schematic.
For example, the [`@angular/material`](https://material.angular.io/guide/schematics) schematic tells the `add` command to install and set up Angular Material and theming, and register new starter components that can be created with `ng generate`.
You can look at this one as an example and model for your own add schematic.
Partner and third party libraries also support the Angular CLI with add schematics.
For example, `@ng-bootstrap/schematics` adds [ng-bootstrap](https://ng-bootstrap.github.io/) to an app, and `@clr/angular` installs and sets up [Clarity from VMWare](https://vmware.github.io/clarity/documentation/v1.0/get-started).
An add schematic can also update a project with configuration changes, add additional dependencies (such as polyfills), or scaffold package-specific initialization code.
For example, the `@angular/pwa` schematic turns your application into a PWA by adding an app manifest and service worker, and the `@angular/elements`  schematic adds the `document-register-element.js` polyfill and dependencies for Angular Elements.
### Generation schematics
Generation schematics are instructions for the `ng generate` command.
The documented sub-commands use the default Angular generation schematics, but you can specify a different schematic (in place of a sub-command) to generate an artifact defined in your library.
Angular Material, for example, supplies generation schematics for the UI components that it defines.
The following command uses one of these schematics to render an Angular Material `<mat-table>` that is pre-configured with a datasource for sorting and pagination.
<code-example language="bash" linenums="false">
ng generate @angular/material:table <component-name>
</code-example>
### Update schematics
The `ng update` command can be used to update your workspace's library dependencies. If you supply no options or use the help option, the command examines your workspace and suggests libraries to update.
<code-example language="bash" linenums="false">
ng update
We analyzed your package.json, there are some packages to update:
Name Version Command to update
--------------------------------------------------------------------------------
@angular/cdk 7.2.2 -> 7.3.1 ng update @angular/cdk
@angular/cli 7.2.3 -> 7.3.0 ng update @angular/cli
@angular/core 7.2.2 -> 7.2.3 ng update @angular/core
@angular/material 7.2.2 -> 7.3.1 ng update @angular/material
rxjs 6.3.3 -> 6.4.0 ng update rxjs
There might be additional packages that are outdated.
Run "ng update --all" to try to update all at the same time.
</code-example>
If you pass the command a set of libraries to update (or the `--all` flag), it updates those libraries, their peer dependencies, and the peer dependencies that depend on them.
<div class="alert is-helpful">
If there are inconsistencies (for example, if peer dependencies cannot be matched by a simple [semver](https://semver.io/) range), the command generates an error and does not change anything in the workspace.
We recommend that you do not force an update of all dependencies by default. Try updating specific dependencies first.
For more about how the `ng update` command works, see [Update Command](https://github.com/angular/angular-cli/blob/master/docs/specifications/update.md).
</div>
If you create a new version of your library that introduces potential breaking changes, you can provide an *update schematic* to enable the `ng update` command to automatically resolve any such changes in the project being updated.
For example, suppose you want to update the Angular Material library.
<code-example language="bash" linenums="false">
ng update @angular/material
</code-example>
This command updates both `@angular/material` and its dependency `@angular/cdk` in your workspace's `package.json`.
If either package contains an update schematic that covers migration from the existing version to a new version, the command runs that schematic on your workspace.
+14 -14
View File
@@ -1,18 +1,18 @@
# Angular Workspace Configuration
A file named `angular.json` at the root level of an Angular [workspace](guide/glossary#workspace) provides workspace-wide and project-specific configuration defaults for build and development tools provided by the Angular CLI.
Path values given in the configuration are relative to the root workspace folder.
A file named `angular.json` at the root level of an Angular [workspace](guide/glossary#workspace) provides workspace-wide and project-specific configuration defaults for build and development tools provided by the Angular CLI.
Path values given in the configuration are relative to the root workspace folder.
## Overall JSON structure
At the top level of `angular.json`, a few properties configure the workspace, and a `projects` section contains the remaining per-project configuration options.
At the top level of `angular.json`, a few properties configure the workspace, and a `projects` section contains the remaining per-project configuration options.
* `version`: The configuration-file version.
* `newProjectRoot`: Path where new projects are created. Absolute or relative to the workspace folder.
* `defaultProject`: Default project name to use in commands, where not provided as an argument. When you use `ng new` to create a new app in a new workspace, that app is the default project for the workspace until you change it here.
* `projects` : Contains a subsection for each project (library, app, e2e test app) in the workspace, with the per-project configuration options.
* `projects` : Contains a subsection for each project (library, app, e2e test app) in the workspace, with the per-project configuration options.
The initial app that you create with `ng new app_name` is listed under "projects", along with its corresponding end-to-end test app:
The initial app that you create with `ng new app_name` is listed under "projects", along with its corresponding end-to-end test app:
<code-example format="." language="none" linenums="false">
projects
@@ -23,11 +23,11 @@ projects
</code-example>
Each additional app that you create with `ng generate application` has a corresponding end-to-end test project, with its own configuration section.
When you create a library project with `ng generate library`, the library project is also added to the `projects` section.
When you create a library project with `ng generate library`, the library project is also added to the `projects` section.
<div class="alert is-helpful">
Note that the `projects` section of the configuration file does not correspond exactly to the workspace file structure.
Note that the `projects` section of the configuration file does not correspond exactly to the workspace file structure.
* The initial app created by `ng new` is at the top level of the workspace file structure, along with its e2e app.
* Additional apps, e2e apps, and libraries go into a `projects` folder in the workspace.
@@ -56,14 +56,14 @@ The following top-level configuration properties are available for each project,
| `sourceRoot` | The root folder for this project's source files. |
| `projectType` | One of "application" or "library". An application can run independently in a browser, while a library cannot. Both an app and its e2e test app are of type "application".|
| `prefix` | A string that Angular prepends to generated selectors. Can be customized to identify an app or feature area. |
| `schematics` | An object containing schematics that customize CLI commands for this project. |
| `schematics` | An object containing configuration defaults that customize the CLI command behavior for this project. See [Schematics Overview](guide/schematics). |
| `architect` | An object containing configuration defaults for Architect builder targets for this project. |
## Project tool configuration options
Architect is the tool that the CLI uses to perform complex tasks such as compilation and test running, according to provided configurations. The `architect` section contains a set of Architect *targets*. Many of the targets correspond to the CLI commands that run them. Some additional predefined targets can be run using the `ng run` command, and you can define your own targets.
Each target object specifies the `builder` for that target, which is the npm package for the tool that Architect runs. In addition, each target has an `options` section that configure default options for the target, and a `configurations` section that names and specifies alternative configurations for the target. See the example in [Build target](#build-target) below.
Each target object specifies the `builder` for that target, which is the npm package for the tool that Architect runs. In addition, each target has an `options` section that configure default options for the target, and a `configurations` section that names and specifies alternative configurations for the target. See the example in [Build target](#build-target) below.
<code-example format="." language="json" linenums="false">
"architect": {
@@ -90,11 +90,11 @@ Each target object specifies the `builder` for that target, which is the npm pac
* The `architect/extract-i18n` section configures defaults for options of the `ng-xi18n` tool used by the `ng xi18n` command, which extracts marked message strings from source code and outputs translation files.
* The `architect/server` section configures defaults for creating a Universal app with server-side rendering, using the `ng run <project>:server` command.
* The `architect/server` section configures defaults for creating a Universal app with server-side rendering, using the `ng run <project>:server` command.
* The `architect/app-shell` section configures defaults for creating an app shell for a progressive web app (PWA), using the `ng run <project>:app-shell` command.
In general, the options for which you can configure defaults correspond to the command options listed in the [CLI reference page](cli) for each command.
In general, the options for which you can configure defaults correspond to the command options listed in the [CLI reference page](cli) for each command.
Note that all options in the configuration file must use [camelCase](guide/glossary#case-conventions), rather than dash-case.
{@a build-target}
@@ -113,15 +113,15 @@ The `architect/build` section configures defaults for options of the `ng build`
### Alternate build configurations
By default, a `production` configuration is defined, and the `ng build` command has `--prod` option that builds using this configuration. The `production` configuration sets defaults that optimize the app in a number of ways, such bundling files, minimizing excess whitespace, removing comments and dead code, and rewriting code to use short, cryptic names ("minification").
By default, a `production` configuration is defined, and the `ng build` command has `--prod` option that builds using this configuration. The `production` configuration sets defaults that optimize the app in a number of ways, such bundling files, minimizing excess whitespace, removing comments and dead code, and rewriting code to use short, cryptic names ("minification").
You can define and name additional alternate configurations (such as `stage`, for instance) appropriate to your development process. Some examples of different build configurations are `stable`, `archive` and `next` used by AIO itself, and the individual locale-specific configurations required for building localized versions of an app. For details, see [Internationalization (i18n)](guide/i18n#merge-aot).
You can define and name additional alternate configurations (such as `stage`, for instance) appropriate to your development process. Some examples of different build configurations are `stable`, `archive` and `next` used by AIO itself, and the individual locale-specific configurations required for building localized versions of an app. For details, see [Internationalization (i18n)](guide/i18n#merge-aot).
{@a build-props}
### Additional build and test options
The configurable options for a default or targeted build generally correspond to the options available for the [`ng build`](cli/build), [`ng serve`](cli/serve), and [`ng test`](cli/test) commands. For details of those options and their possible values, see the [CLI Reference](cli).
The configurable options for a default or targeted build generally correspond to the options available for the [`ng build`](cli/build), [`ng serve`](cli/serve), and [`ng test`](cli/test) commands. For details of those options and their possible values, see the [CLI Reference](cli).
Some additional options (listed below) can only be set through the configuration file, either by direct editing or with the [`ng config`](cli/config) command.

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