Skip to content

Commit c7e1266

Browse files
alan-agius4clydin
authored andcommitted
feat(@schematics/angular): add production by default optional migration
With this change we add an optional migration to update Angular CLI workspace configurations to 'production' mode by default. To run this migration use the below commands ``` ng update @angular/cli ng update @angular/cli --migrate-only production-by-default ```
1 parent decb05b commit c7e1266

File tree

4 files changed

+448
-1
lines changed

4 files changed

+448
-1
lines changed

packages/schematics/angular/migrations/migration-collection.json

+5
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@
144144
"version": "12.0.0-next.4",
145145
"factory": "./update-8/#updateLazyModulePaths",
146146
"description": "Lazy loading syntax migration. Update lazy loading string syntax to use dynamic imports."
147+
},
148+
"production-by-default": {
149+
"version": "9999.0.0",
150+
"factory": "./update-12/production-default-config",
151+
"description": "Optional migration to update Angular CLI workspace configurations to 'production' mode by default."
147152
}
148153
}
149154
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import { JsonValue, logging, tags, workspaces } from '@angular-devkit/core';
10+
import { Rule } from '@angular-devkit/schematics';
11+
import { allTargetOptions, allWorkspaceTargets, updateWorkspace } from '../../utility/workspace';
12+
import { Builders } from '../../utility/workspace-models';
13+
14+
export default function (): Rule {
15+
return async (_host, context) => updateWorkspace(workspace => {
16+
for (const [name, target] of allWorkspaceTargets(workspace)) {
17+
let defaultConfiguration: string | undefined;
18+
19+
// Only interested in 1st party builders
20+
switch (target.builder) {
21+
case Builders.AppShell:
22+
case Builders.Browser:
23+
case Builders.Server:
24+
case Builders.NgPackagr:
25+
defaultConfiguration = 'production';
26+
break;
27+
case Builders.DevServer:
28+
case Builders.Protractor:
29+
case '@nguniversal/builders:ssr-dev-server':
30+
defaultConfiguration = 'development';
31+
break;
32+
case Builders.TsLint:
33+
case Builders.ExtractI18n:
34+
case Builders.Karma:
35+
// Nothing to update
36+
break;
37+
default:
38+
context.logger.warn(tags.stripIndents`Cannot update "${name}" target configuration as it's using "${target.builder}"
39+
which is a third-party builder. This target configuration will require manual review.`);
40+
41+
continue;
42+
}
43+
44+
if (!defaultConfiguration) {
45+
continue;
46+
}
47+
48+
updateTarget(name, target, context.logger, defaultConfiguration);
49+
}
50+
});
51+
}
52+
53+
function getArchitectTargetWithConfig(currentTarget: string, overrideConfig?: string): string {
54+
const [project, target, config = 'development'] = currentTarget.split(':');
55+
56+
return `${project}:${target}:${overrideConfig || config}`;
57+
}
58+
59+
function updateTarget(
60+
targetName: string,
61+
target: workspaces.TargetDefinition,
62+
logger: logging.LoggerApi,
63+
defaultConfiguration: string,
64+
): void {
65+
if (!target.configurations) {
66+
target.configurations = {};
67+
}
68+
69+
if (target.configurations?.development) {
70+
logger.info(tags.stripIndents`Skipping updating "${targetName}" target configuration as a "development" configuration is already defined.`);
71+
72+
return;
73+
}
74+
75+
if (!target.configurations?.production) {
76+
logger.info(tags.stripIndents`Skipping updating "${targetName}" target configuration as a "production" configuration is not defined.`);
77+
78+
return;
79+
}
80+
81+
const developmentOptions: Record<string, JsonValue | undefined> = {};
82+
let serverTarget = true;
83+
let browserTarget = true;
84+
let devServerTarget = true;
85+
86+
for (const [, options] of allTargetOptions(target)) {
87+
if (typeof options.serverTarget === 'string') {
88+
options.serverTarget = getArchitectTargetWithConfig(options.serverTarget);
89+
if (!developmentOptions.serverTarget) {
90+
developmentOptions.serverTarget = getArchitectTargetWithConfig(options.serverTarget, 'development');
91+
}
92+
} else {
93+
serverTarget = false;
94+
}
95+
96+
if (typeof options.browserTarget === 'string') {
97+
options.browserTarget = getArchitectTargetWithConfig(options.browserTarget);
98+
if (!developmentOptions.browserTarget) {
99+
developmentOptions.browserTarget = getArchitectTargetWithConfig(options.browserTarget, 'development');
100+
}
101+
} else {
102+
browserTarget = false;
103+
}
104+
105+
if (typeof options.devServerTarget === 'string') {
106+
options.devServerTarget = getArchitectTargetWithConfig(options.devServerTarget);
107+
if (!developmentOptions.devServerTarget) {
108+
developmentOptions.devServerTarget = getArchitectTargetWithConfig(options.devServerTarget, 'development');
109+
}
110+
} else {
111+
devServerTarget = false;
112+
}
113+
}
114+
115+
// If all configurastions have a target defined delete the one in options.
116+
if (target.options) {
117+
if (serverTarget) {
118+
delete target.options.serverTarget;
119+
}
120+
121+
if (browserTarget) {
122+
delete target.options.browserTarget;
123+
}
124+
125+
if (devServerTarget) {
126+
delete target.options.devServerTarget;
127+
}
128+
}
129+
130+
target.defaultConfiguration = defaultConfiguration;
131+
target.configurations.development = developmentOptions;
132+
}

0 commit comments

Comments
 (0)