66 * found in the LICENSE file at https://angular.io/license
77 */
88import { JsonObject , normalize , relative , strings , tags } from '@angular-devkit/core' ;
9- import { experimental } from '@angular-devkit/core' ;
109import {
1110 MergeStrategy ,
1211 Rule ,
@@ -24,11 +23,15 @@ import {
2423 url ,
2524} from '@angular-devkit/schematics' ;
2625import { Schema as E2eOptions } from '../e2e/schema' ;
27- import { getWorkspace , getWorkspacePath } from '../utility/config' ;
26+ import {
27+ WorkspaceProject ,
28+ WorkspaceSchema ,
29+ addProjectToWorkspace ,
30+ getWorkspace ,
31+ } from '../utility/config' ;
2832import { latestVersions } from '../utility/latest-versions' ;
2933import { Schema as ApplicationOptions } from './schema' ;
3034
31- type WorkspaceSchema = experimental . workspace . WorkspaceSchema ;
3235
3336// TODO: use JsonAST
3437// function appendPropertyInAstObject(
@@ -85,171 +88,166 @@ function addDependenciesToPackageJson() {
8588}
8689
8790function addAppToWorkspaceFile ( options : ApplicationOptions , workspace : WorkspaceSchema ) : Rule {
88- return ( host : Tree , context : SchematicContext ) => {
89- // TODO: use JsonAST
90- // const workspacePath = '/angular.json';
91- // const workspaceBuffer = host.read(workspacePath);
92- // if (workspaceBuffer === null) {
93- // throw new SchematicsException(`Configuration file (${workspacePath}) not found.`);
94- // }
95- // const workspaceJson = parseJson(workspaceBuffer.toString());
96- // if (workspaceJson.value === null) {
97- // throw new SchematicsException(`Unable to parse configuration file (${workspacePath}).`);
98- // }
99- let projectRoot = options . projectRoot !== undefined
100- ? options . projectRoot
101- : `${ workspace . newProjectRoot } /${ options . name } ` ;
102- if ( projectRoot !== '' && ! projectRoot . endsWith ( '/' ) ) {
103- projectRoot += '/' ;
104- }
105- const rootFilesRoot = options . projectRoot === undefined
106- ? projectRoot
107- : projectRoot + 'src/' ;
91+ // TODO: use JsonAST
92+ // const workspacePath = '/angular.json';
93+ // const workspaceBuffer = host.read(workspacePath);
94+ // if (workspaceBuffer === null) {
95+ // throw new SchematicsException(`Configuration file (${workspacePath}) not found.`);
96+ // }
97+ // const workspaceJson = parseJson(workspaceBuffer.toString());
98+ // if (workspaceJson.value === null) {
99+ // throw new SchematicsException(`Unable to parse configuration file (${workspacePath}).`);
100+ // }
101+ let projectRoot = options . projectRoot !== undefined
102+ ? options . projectRoot
103+ : `${ workspace . newProjectRoot } /${ options . name } ` ;
104+ if ( projectRoot !== '' && ! projectRoot . endsWith ( '/' ) ) {
105+ projectRoot += '/' ;
106+ }
107+ const rootFilesRoot = options . projectRoot === undefined
108+ ? projectRoot
109+ : projectRoot + 'src/' ;
108110
109- const schematics : JsonObject = { } ;
111+ const schematics : JsonObject = { } ;
110112
111- if ( options . inlineTemplate === true
112- || options . inlineStyle === true
113- || options . style !== 'css' ) {
114- schematics [ '@schematics/angular:component' ] = { } ;
115- if ( options . inlineTemplate === true ) {
116- ( schematics [ '@schematics/angular:component' ] as JsonObject ) . inlineTemplate = true ;
117- }
118- if ( options . inlineStyle === true ) {
119- ( schematics [ '@schematics/angular:component' ] as JsonObject ) . inlineStyle = true ;
120- }
121- if ( options . style && options . style !== 'css' ) {
122- ( schematics [ '@schematics/angular:component' ] as JsonObject ) . styleext = options . style ;
123- }
113+ if ( options . inlineTemplate === true
114+ || options . inlineStyle === true
115+ || options . style !== 'css' ) {
116+ schematics [ '@schematics/angular:component' ] = { } ;
117+ if ( options . inlineTemplate === true ) {
118+ ( schematics [ '@schematics/angular:component' ] as JsonObject ) . inlineTemplate = true ;
124119 }
125-
126- if ( options . skipTests === true ) {
127- [ 'class' , 'component' , 'directive' , 'guard' , 'module' , 'pipe' , 'service' ] . forEach ( ( type ) => {
128- if ( ! ( `@schematics/angular:${ type } ` in schematics ) ) {
129- schematics [ `@schematics/angular:${ type } ` ] = { } ;
130- }
131- ( schematics [ `@schematics/angular:${ type } ` ] as JsonObject ) . spec = false ;
132- } ) ;
120+ if ( options . inlineStyle === true ) {
121+ ( schematics [ '@schematics/angular:component' ] as JsonObject ) . inlineStyle = true ;
133122 }
123+ if ( options . style && options . style !== 'css' ) {
124+ ( schematics [ '@schematics/angular:component' ] as JsonObject ) . styleext = options . style ;
125+ }
126+ }
134127
135- // tslint:disable-next-line:no-any
136- const project : any = {
137- root : projectRoot ,
138- projectType : 'application' ,
139- prefix : options . prefix || 'app' ,
140- schematics,
141- architect : {
142- build : {
143- builder : '@angular-devkit/build-angular:browser' ,
144- options : {
145- outputPath : `dist/${ options . name } ` ,
146- index : `${ projectRoot } src/index.html` ,
147- main : `${ projectRoot } src/main.ts` ,
148- polyfills : `${ projectRoot } src/polyfills.ts` ,
149- tsConfig : `${ rootFilesRoot } tsconfig.app.json` ,
150- assets : [
151- {
152- glob : 'favicon.ico' ,
153- input : `${ projectRoot } src` ,
154- output : '/' ,
155- } ,
156- {
157- glob : '**/*' ,
158- input : `${ projectRoot } src/assets` ,
159- output : '/assets' ,
160- } ,
161- ] ,
162- styles : [
163- `${ projectRoot } src/styles.${ options . style } ` ,
164- ] ,
165- scripts : [ ] ,
166- } ,
167- configurations : {
168- production : {
169- fileReplacements : [ {
170- replace : `${ projectRoot } src/environments/environment.ts` ,
171- with : `${ projectRoot } src/environments/environment.prod.ts` ,
172- } ] ,
173- optimization : true ,
174- outputHashing : 'all' ,
175- sourceMap : false ,
176- extractCss : true ,
177- namedChunks : false ,
178- aot : true ,
179- extractLicenses : true ,
180- vendorChunk : false ,
181- buildOptimizer : true ,
128+ if ( options . skipTests === true ) {
129+ [ 'class' , 'component' , 'directive' , 'guard' , 'module' , 'pipe' , 'service' ] . forEach ( ( type ) => {
130+ if ( ! ( `@schematics/angular:${ type } ` in schematics ) ) {
131+ schematics [ `@schematics/angular:${ type } ` ] = { } ;
132+ }
133+ ( schematics [ `@schematics/angular:${ type } ` ] as JsonObject ) . spec = false ;
134+ } ) ;
135+ }
136+
137+ const project : WorkspaceProject = {
138+ root : projectRoot ,
139+ projectType : 'application' ,
140+ prefix : options . prefix || 'app' ,
141+ schematics,
142+ architect : {
143+ build : {
144+ builder : '@angular-devkit/build-angular:browser' ,
145+ options : {
146+ outputPath : `dist/${ options . name } ` ,
147+ index : `${ projectRoot } src/index.html` ,
148+ main : `${ projectRoot } src/main.ts` ,
149+ polyfills : `${ projectRoot } src/polyfills.ts` ,
150+ tsConfig : `${ rootFilesRoot } tsconfig.app.json` ,
151+ assets : [
152+ {
153+ glob : 'favicon.ico' ,
154+ input : `${ projectRoot } src` ,
155+ output : '/' ,
182156 } ,
183- } ,
184- } ,
185- serve : {
186- builder : '@angular-devkit/build-angular:dev-server' ,
187- options : {
188- browserTarget : `${ options . name } :build` ,
189- } ,
190- configurations : {
191- production : {
192- browserTarget : `${ options . name } :build:production` ,
157+ {
158+ glob : '**/*' ,
159+ input : `${ projectRoot } src/assets` ,
160+ output : '/assets' ,
193161 } ,
194- } ,
162+ ] ,
163+ styles : [
164+ `${ projectRoot } src/styles.${ options . style } ` ,
165+ ] ,
166+ scripts : [ ] ,
195167 } ,
196- 'extract-i18n' : {
197- builder : '@angular-devkit/build-angular:extract-i18n' ,
198- options : {
199- browserTarget : `${ options . name } :build` ,
168+ configurations : {
169+ production : {
170+ fileReplacements : [ {
171+ replace : `${ projectRoot } src/environments/environment.ts` ,
172+ with : `${ projectRoot } src/environments/environment.prod.ts` ,
173+ } ] ,
174+ optimization : true ,
175+ outputHashing : 'all' ,
176+ sourceMap : false ,
177+ extractCss : true ,
178+ namedChunks : false ,
179+ aot : true ,
180+ extractLicenses : true ,
181+ vendorChunk : false ,
182+ buildOptimizer : true ,
200183 } ,
201184 } ,
202- test : {
203- builder : '@angular-devkit/build-angular:karma' ,
204- options : {
205- main : `${ projectRoot } src/test.ts` ,
206- polyfills : `${ projectRoot } src/polyfills.ts` ,
207- tsConfig : `${ rootFilesRoot } tsconfig.spec.json` ,
208- karmaConfig : `${ rootFilesRoot } karma.conf.js` ,
209- styles : [
210- `${ projectRoot } styles.${ options . style } ` ,
211- ] ,
212- scripts : [ ] ,
213- assets : [
214- {
215- glob : 'favicon.ico' ,
216- input : `${ projectRoot } src/` ,
217- output : '/' ,
218- } ,
219- {
220- glob : '**/*' ,
221- input : `${ projectRoot } src/assets` ,
222- output : '/assets' ,
223- } ,
224- ] ,
225- } ,
185+ } ,
186+ serve : {
187+ builder : '@angular-devkit/build-angular:dev-server' ,
188+ options : {
189+ browserTarget : `${ options . name } :build` ,
226190 } ,
227- lint : {
228- builder : '@angular-devkit/build-angular:tslint' ,
229- options : {
230- tsConfig : [
231- `${ rootFilesRoot } tsconfig.app.json` ,
232- `${ rootFilesRoot } tsconfig.spec.json` ,
233- ] ,
234- exclude : [
235- '**/node_modules/**' ,
236- ] ,
191+ configurations : {
192+ production : {
193+ browserTarget : `${ options . name } :build:production` ,
237194 } ,
238195 } ,
239196 } ,
240- } ;
241- // tslint:disable-next-line:no-any
242- // const projects: JsonObject = (<any> workspaceAst.value).projects || {};
243- // tslint:disable-next-line:no-any
244- // if (!(<any> workspaceAst.value).projects) {
245- // // tslint:disable-next-line:no-any
246- // (<any> workspaceAst.value).projects = projects;
247- // }
248-
249- workspace . projects [ options . name ] = project ;
250-
251- host . overwrite ( getWorkspacePath ( host ) , JSON . stringify ( workspace , null , 2 ) ) ;
197+ 'extract-i18n' : {
198+ builder : '@angular-devkit/build-angular:extract-i18n' ,
199+ options : {
200+ browserTarget : `${ options . name } :build` ,
201+ } ,
202+ } ,
203+ test : {
204+ builder : '@angular-devkit/build-angular:karma' ,
205+ options : {
206+ main : `${ projectRoot } src/test.ts` ,
207+ polyfills : `${ projectRoot } src/polyfills.ts` ,
208+ tsConfig : `${ rootFilesRoot } tsconfig.spec.json` ,
209+ karmaConfig : `${ rootFilesRoot } karma.conf.js` ,
210+ styles : [
211+ `${ projectRoot } styles.${ options . style } ` ,
212+ ] ,
213+ scripts : [ ] ,
214+ assets : [
215+ {
216+ glob : 'favicon.ico' ,
217+ input : `${ projectRoot } src/` ,
218+ output : '/' ,
219+ } ,
220+ {
221+ glob : '**/*' ,
222+ input : `${ projectRoot } src/assets` ,
223+ output : '/assets' ,
224+ } ,
225+ ] ,
226+ } ,
227+ } ,
228+ lint : {
229+ builder : '@angular-devkit/build-angular:tslint' ,
230+ options : {
231+ tsConfig : [
232+ `${ rootFilesRoot } tsconfig.app.json` ,
233+ `${ rootFilesRoot } tsconfig.spec.json` ,
234+ ] ,
235+ exclude : [
236+ '**/node_modules/**' ,
237+ ] ,
238+ } ,
239+ } ,
240+ } ,
252241 } ;
242+ // tslint:disable-next-line:no-any
243+ // const projects: JsonObject = (<any> workspaceAst.value).projects || {};
244+ // tslint:disable-next-line:no-any
245+ // if (!(<any> workspaceAst.value).projects) {
246+ // // tslint:disable-next-line:no-any
247+ // (<any> workspaceAst.value).projects = projects;
248+ // }
249+
250+ return addProjectToWorkspace ( workspace , options . name , project ) ;
253251}
254252const projectNameRegexp = / ^ [ a - z A - Z ] [ . 0 - 9 a - z A - Z ] * ( - [ . 0 - 9 a - z A - Z ] * ) * $ / ;
255253const unsupportedProjectNames = [ 'test' , 'ember' , 'ember-cli' , 'vendor' , 'app' ] ;
0 commit comments