8
8
import {
9
9
Path ,
10
10
basename ,
11
- experimental ,
12
11
join ,
13
12
normalize ,
14
13
parseJson ,
@@ -32,52 +31,44 @@ import {
32
31
import * as ts from '../third_party/github.com/Microsoft/TypeScript/lib/typescript' ;
33
32
import { findNode , getDecoratorMetadata } from '../utility/ast-utils' ;
34
33
import { InsertChange } from '../utility/change' ;
35
- import { getWorkspace , updateWorkspace } from '../utility/config' ;
36
34
import { addPackageJsonDependency , getPackageJsonDependency } from '../utility/dependencies' ;
37
35
import { findBootstrapModuleCall , findBootstrapModulePath } from '../utility/ng-ast-utils' ;
38
- import { getProject } from '../utility/project' ;
39
- import { getProjectTargets , targetBuildNotFoundError } from '../utility/project-targets ' ;
40
- import { Builders , WorkspaceTargets } from '../utility/workspace-models' ;
36
+ import { targetBuildNotFoundError } from '../utility/project-targets ' ;
37
+ import { getWorkspace , updateWorkspace } from '../utility/workspace ' ;
38
+ import { BrowserBuilderOptions , Builders } from '../utility/workspace-models' ;
41
39
import { Schema as UniversalOptions } from './schema' ;
42
40
43
-
44
- function getFileReplacements ( target : WorkspaceTargets ) {
45
- const fileReplacements =
46
- target . build &&
47
- target . build . configurations &&
48
- target . build . configurations . production &&
49
- target . build . configurations . production . fileReplacements ;
50
-
51
- return fileReplacements || [ ] ;
52
- }
53
-
54
41
function updateConfigFile ( options : UniversalOptions , tsConfigDirectory : Path ) : Rule {
55
- return ( host : Tree ) => {
56
- const workspace = getWorkspace ( host ) ;
57
- const clientProject = getProject ( workspace , options . clientProject ) ;
58
- const projectTargets = getProjectTargets ( clientProject ) ;
59
-
60
- projectTargets . server = {
61
- builder : Builders . Server ,
62
- options : {
63
- outputPath : `dist/${ options . clientProject } -server` ,
64
- main : `${ clientProject . root } src/main.server.ts` ,
65
- tsConfig : join ( tsConfigDirectory , `${ options . tsconfigFileName } .json` ) ,
66
- } ,
67
- configurations : {
68
- production : {
69
- fileReplacements : getFileReplacements ( projectTargets ) ,
70
- sourceMap : false ,
71
- optimization : {
72
- scripts : false ,
73
- styles : true ,
42
+ return updateWorkspace ( workspace => {
43
+ const clientProject = workspace . projects . get ( options . clientProject ) ;
44
+ if ( clientProject ) {
45
+ const buildTarget = clientProject . targets . get ( 'build' ) ;
46
+ let fileReplacements ;
47
+ if ( buildTarget && buildTarget . configurations && buildTarget . configurations . production ) {
48
+ fileReplacements = buildTarget . configurations . production . fileReplacements ;
49
+ }
50
+
51
+ clientProject . targets . add ( {
52
+ name : 'server' ,
53
+ builder : Builders . Server ,
54
+ options : {
55
+ outputPath : `dist/${ options . clientProject } -server` ,
56
+ main : `${ clientProject . root } src/main.server.ts` ,
57
+ tsConfig : join ( tsConfigDirectory , `${ options . tsconfigFileName } .json` ) ,
58
+ } ,
59
+ configurations : {
60
+ production : {
61
+ fileReplacements,
62
+ sourceMap : false ,
63
+ optimization : {
64
+ scripts : false ,
65
+ styles : true ,
66
+ } ,
74
67
} ,
75
68
} ,
76
- } ,
77
- } ;
78
-
79
- return updateWorkspace ( workspace ) ;
80
- } ;
69
+ } ) ;
70
+ }
71
+ } ) ;
81
72
}
82
73
83
74
function findBrowserModuleImport ( host : Tree , modulePath : string ) : ts . Node {
@@ -99,13 +90,9 @@ function findBrowserModuleImport(host: Tree, modulePath: string): ts.Node {
99
90
return browserModuleNode ;
100
91
}
101
92
102
- function wrapBootstrapCall ( options : UniversalOptions ) : Rule {
93
+ function wrapBootstrapCall ( mainFile : string ) : Rule {
103
94
return ( host : Tree ) => {
104
- const clientTargets = getProjectTargets ( host , options . clientProject ) ;
105
- if ( ! clientTargets . build ) {
106
- throw targetBuildNotFoundError ( ) ;
107
- }
108
- const mainPath = normalize ( '/' + clientTargets . build . options . main ) ;
95
+ const mainPath = normalize ( '/' + mainFile ) ;
109
96
let bootstrapCall : ts . Node | null = findBootstrapModuleCall ( host , mainPath ) ;
110
97
if ( bootstrapCall === null ) {
111
98
throw new SchematicsException ( 'Bootstrap module not found.' ) ;
@@ -172,18 +159,17 @@ function findCallExpressionNode(node: ts.Node, text: string): ts.Node | null {
172
159
return foundNode ;
173
160
}
174
161
175
- function addServerTransition ( options : UniversalOptions ) : Rule {
162
+ function addServerTransition (
163
+ options : UniversalOptions ,
164
+ mainFile : string ,
165
+ clientProjectRoot : string ,
166
+ ) : Rule {
176
167
return ( host : Tree ) => {
177
- const clientProject = getProject ( host , options . clientProject ) ;
178
- const clientTargets = getProjectTargets ( clientProject ) ;
179
- if ( ! clientTargets . build ) {
180
- throw targetBuildNotFoundError ( ) ;
181
- }
182
- const mainPath = normalize ( '/' + clientTargets . build . options . main ) ;
168
+ const mainPath = normalize ( '/' + mainFile ) ;
183
169
184
170
const bootstrapModuleRelativePath = findBootstrapModulePath ( host , mainPath ) ;
185
171
const bootstrapModulePath = normalize (
186
- `/${ clientProject . root } /src/${ bootstrapModuleRelativePath } .ts` ) ;
172
+ `/${ clientProjectRoot } /src/${ bootstrapModuleRelativePath } .ts` ) ;
187
173
188
174
const browserModuleImport = findBrowserModuleImport ( host , bootstrapModulePath ) ;
189
175
const appId = options . appId ;
@@ -214,8 +200,7 @@ function addDependencies(): Rule {
214
200
} ;
215
201
}
216
202
217
- function getTsConfigOutDir ( host : Tree , targets : experimental . workspace . WorkspaceTool ) : string {
218
- const tsConfigPath = targets . build . options . tsConfig ;
203
+ function getTsConfigOutDir ( host : Tree , tsConfigPath : string ) : string {
219
204
const tsConfigBuffer = host . read ( tsConfigPath ) ;
220
205
if ( ! tsConfigBuffer ) {
221
206
throw new SchematicsException ( `Could not read ${ tsConfigPath } ` ) ;
@@ -233,18 +218,24 @@ function getTsConfigOutDir(host: Tree, targets: experimental.workspace.Workspace
233
218
}
234
219
235
220
export default function ( options : UniversalOptions ) : Rule {
236
- return ( host : Tree , context : SchematicContext ) => {
237
- const clientProject = getProject ( host , options . clientProject ) ;
238
- if ( clientProject . projectType !== 'application' ) {
221
+ return async ( host : Tree , context : SchematicContext ) => {
222
+ const workspace = await getWorkspace ( host ) ;
223
+
224
+ const clientProject = workspace . projects . get ( options . clientProject ) ;
225
+ if ( ! clientProject || clientProject . extensions . projectType !== 'application' ) {
239
226
throw new SchematicsException ( `Universal requires a project type of "application".` ) ;
240
227
}
241
- const clientTargets = getProjectTargets ( clientProject ) ;
242
- const outDir = getTsConfigOutDir ( host , clientTargets ) ;
243
- if ( ! clientTargets . build ) {
228
+
229
+ const clientBuildTarget = clientProject . targets . get ( 'build' ) ;
230
+ if ( ! clientBuildTarget ) {
244
231
throw targetBuildNotFoundError ( ) ;
245
232
}
233
+ const clientBuildOptions =
234
+ ( clientBuildTarget . options || { } ) as unknown as BrowserBuilderOptions ;
235
+
236
+ const outDir = getTsConfigOutDir ( host , clientBuildOptions . tsConfig ) ;
246
237
247
- const clientTsConfig = normalize ( clientTargets . build . options . tsConfig ) ;
238
+ const clientTsConfig = normalize ( clientBuildOptions . tsConfig ) ;
248
239
const tsConfigExtends = basename ( clientTsConfig ) ;
249
240
// this is needed because prior to version 8, tsconfig might have been in 'src'
250
241
// and we don't want to break the 'ng add @nguniversal/express-engine schematics'
@@ -281,8 +272,8 @@ export default function (options: UniversalOptions): Rule {
281
272
mergeWith ( rootSource ) ,
282
273
addDependencies ( ) ,
283
274
updateConfigFile ( options , tsConfigDirectory ) ,
284
- wrapBootstrapCall ( options ) ,
285
- addServerTransition ( options ) ,
275
+ wrapBootstrapCall ( clientBuildOptions . main ) ,
276
+ addServerTransition ( options , clientBuildOptions . main , clientProject . root ) ,
286
277
] ) ;
287
278
} ;
288
279
}
0 commit comments