Skip to content

Commit 5d31a58

Browse files
committed
fix(@schematics/angular): enable opt-in for new @angular/ssr feature
This commit updates several schematics to make the new `@angular/ssr` feature opt-in. Users can opt in by using the `--server-routing` option or by responding with `yes` to the prompt.
1 parent 1890fe4 commit 5d31a58

29 files changed

+165
-29
lines changed

packages/angular/ssr/schematics/ng-add/schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
"description": "Skip installing dependency packages.",
1616
"type": "boolean",
1717
"default": false
18+
},
19+
"serverRouting": {
20+
"description": "Creates a server application using the Server Routing and App Engine APIs (Developer Preview).",
21+
"type": "boolean"
1822
}
1923
},
2024
"required": ["project"],

packages/schematics/angular/app-shell/index.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import {
2929
import { applyToUpdateRecorder } from '../utility/change';
3030
import { getAppModulePath, isStandaloneApp } from '../utility/ng-ast-utils';
3131
import { findBootstrapApplicationCall, getMainFilePath } from '../utility/standalone/util';
32-
import { getWorkspace } from '../utility/workspace';
32+
import { getWorkspace, updateWorkspace } from '../utility/workspace';
33+
import { Builders } from '../utility/workspace-models';
3334
import { Schema as AppShellOptions } from './schema';
3435

3536
const APP_SHELL_ROUTE = 'shell';
@@ -169,6 +170,29 @@ function getMetadataProperty(metadata: ts.Node, propertyName: string): ts.Proper
169170
return property;
170171
}
171172

173+
function addAppShellConfigToWorkspace(options: AppShellOptions): Rule {
174+
return updateWorkspace((workspace) => {
175+
const project = workspace.projects.get(options.project);
176+
if (!project) {
177+
return;
178+
}
179+
const buildTarget = project.targets.get('build');
180+
if (
181+
buildTarget?.builder === Builders.Application ||
182+
buildTarget?.builder === Builders.BuildApplication
183+
) {
184+
// Application builder configuration.
185+
const prodConfig = buildTarget.configurations?.production;
186+
if (!prodConfig) {
187+
throw new SchematicsException(
188+
`A "production" configuration is not defined for the "build" builder.`,
189+
);
190+
}
191+
prodConfig.appShell = true;
192+
}
193+
});
194+
}
195+
172196
function addServerRoutes(options: AppShellOptions): Rule {
173197
return async (host: Tree) => {
174198
// The workspace gets updated so this needs to be reloaded
@@ -266,6 +290,10 @@ function addStandaloneServerRoute(options: AppShellOptions): Rule {
266290
);
267291
}
268292

293+
if (!options.serverRouting) {
294+
return;
295+
}
296+
269297
// Add route to providers literal.
270298
recorder.remove(providersLiteral.getStart(), providersLiteral.getWidth());
271299
const updatedProvidersString = [
@@ -349,9 +377,12 @@ export default function (options: AppShellOptions): Rule {
349377
return chain([
350378
validateProject(browserEntryPoint),
351379
schematic('server', options),
352-
isStandalone ? noop() : addRouterModule(browserEntryPoint),
353-
isStandalone ? addStandaloneServerRoute(options) : addServerRoutes(options),
354-
addServerRoutingConfig(options),
380+
...(isStandalone
381+
? [addStandaloneServerRoute(options)]
382+
: [addRouterModule(browserEntryPoint), addServerRoutes(options)]),
383+
options.serverRouting
384+
? addServerRoutingConfig(options)
385+
: addAppShellConfigToWorkspace(options),
355386
schematic('component', {
356387
name: 'app-shell',
357388
module: 'app.module.server.ts',

packages/schematics/angular/app-shell/index_spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ describe('App Shell Schematic', () => {
1919
);
2020
const defaultOptions: AppShellOptions = {
2121
project: 'bar',
22+
serverRouting: true,
2223
};
2324

2425
const workspaceOptions: WorkspaceOptions = {

packages/schematics/angular/app-shell/schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
"$default": {
1313
"$source": "projectName"
1414
}
15+
},
16+
"serverRouting": {
17+
"description": "Creates a server application using the Server Routing (Developer Preview).",
18+
"type": "boolean",
19+
"default": false
1520
}
1621
},
1722
"required": ["project"]

packages/schematics/angular/application/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export default function (options: ApplicationOptions): Rule {
101101
options.ssr
102102
? schematic('ssr', {
103103
project: options.name,
104+
serverRouting: options.serverRouting,
104105
skipInstall: true,
105106
})
106107
: noop(),

packages/schematics/angular/application/schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@
118118
"default": false,
119119
"x-user-analytics": "ep.ng_ssr"
120120
},
121+
"serverRouting": {
122+
"description": "Creates a server application using the Server Routing and App Engine APIs (Developer Preview).",
123+
"type": "boolean"
124+
},
121125
"experimentalZoneless": {
122126
"description": "Create an application that does not utilize zone.js.",
123127
"type": "boolean",

packages/schematics/angular/ng-new/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export default function (options: NgNewOptions): Rule {
5757
minimal: options.minimal,
5858
standalone: options.standalone,
5959
ssr: options.ssr,
60+
serverRouting: options.serverRouting,
6061
experimentalZoneless: options.experimentalZoneless,
6162
};
6263

packages/schematics/angular/ng-new/schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@
139139
"type": "boolean",
140140
"x-user-analytics": "ep.ng_ssr"
141141
},
142+
"serverRouting": {
143+
"description": "Creates a server application using the Server Routing and App Engine APIs (Developer Preview).",
144+
"type": "boolean"
145+
},
142146
"experimentalZoneless": {
143147
"description": "Create an application that does not utilize zone.js.",
144148
"type": "boolean",

packages/schematics/angular/server/files/application-builder/standalone-src/app/app.config.server.ts.template

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
2-
import { provideServerRendering } from '@angular/platform-server';
3-
import { provideServerRoutesConfig } from '@angular/ssr';
4-
import { appConfig } from './app.config';
5-
import { serverRoutes } from './app.routes.server';
2+
import { provideServerRendering } from '@angular/platform-server';<% if(serverRouting) { %>
3+
import { provideServerRoutesConfig } from '@angular/ssr';<% } %>
4+
import { appConfig } from './app.config';<% if(serverRouting) { %>
5+
import { serverRoutes } from './app.routes.server';<% } %>
66

77
const serverConfig: ApplicationConfig = {
88
providers: [
9-
provideServerRendering(),
10-
provideServerRoutesConfig(serverRoutes)
9+
provideServerRendering(),<% if(serverRouting) { %>
10+
provideServerRoutesConfig(serverRoutes)<% } %>
1111
]
1212
};
1313

packages/schematics/angular/server/index.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ import {
1414
apply,
1515
applyTemplates,
1616
chain,
17+
filter,
1718
mergeWith,
1819
move,
19-
renameTemplateFiles,
20+
noop,
2021
strings,
2122
url,
2223
} from '@angular-devkit/schematics';
@@ -112,7 +113,9 @@ function updateConfigFileApplicationBuilder(options: ServerOptions): Rule {
112113
serverMainEntryName,
113114
);
114115

115-
buildTarget.options['outputMode'] = 'static';
116+
if (options.serverRouting) {
117+
buildTarget.options['outputMode'] = 'static';
118+
}
116119
});
117120
}
118121

@@ -191,6 +194,9 @@ export default function (options: ServerOptions): Rule {
191194
filesUrl += isStandalone ? 'standalone-src' : 'ngmodule-src';
192195

193196
const templateSource = apply(url(filesUrl), [
197+
options.serverRouting
198+
? noop()
199+
: filter((path) => !path.endsWith('app.routes.server.ts.template')),
194200
applyTemplates({
195201
...strings,
196202
...options,

0 commit comments

Comments
 (0)