@schematics/angular 18.0.0-next.3 → 18.0.0-next.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,28 +1,8 @@
1
1
  {
2
2
  "schematics": {
3
- "replace-nguniversal-builders": {
4
- "version": "17.0.0",
5
- "factory": "./update-17/replace-nguniversal-builders",
6
- "description": "Replace usages of '@nguniversal/builders' with '@angular-devkit/build-angular'."
7
- },
8
- "replace-nguniversal-engines": {
9
- "version": "17.0.0",
10
- "factory": "./update-17/replace-nguniversal-engines",
11
- "description": "Replace usages of '@nguniversal/' packages with '@angular/ssr'."
12
- },
13
- "update-workspace-config": {
14
- "version": "17.0.0",
15
- "factory": "./update-17/update-workspace-config",
16
- "description": "Replace deprecated options in 'angular.json'."
17
- },
18
- "add-browser-sync-dependency": {
19
- "version": "17.1.0",
20
- "factory": "./update-17/add-browser-sync-dependency",
21
- "description": "Add 'browser-sync' as dev dependency when '@angular-devkit/build-angular:ssr-dev-server' is used, as it is no longer a direct dependency of '@angular-devkit/build-angular'."
22
- },
23
3
  "use-application-builder": {
24
4
  "version": "18.0.0",
25
- "factory": "./update-17/use-application-builder",
5
+ "factory": "./use-application-builder/migration",
26
6
  "description": "Migrate application projects using '@angular-devkit/build-angular:browser' and '@angular-devkit/build-angular:browser-esbuild' to use the '@angular-devkit/build-angular:application' builder. Read more about this here: https://angular.dev/tools/cli/esbuild#using-the-application-builder",
27
7
  "optional": true
28
8
  }
@@ -9,7 +9,10 @@
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  const schematics_1 = require("@angular-devkit/schematics");
11
11
  const posix_1 = require("node:path/posix");
12
+ const dependencies_1 = require("../../utility/dependencies");
13
+ const dependency_1 = require("../../utility/dependency");
12
14
  const json_file_1 = require("../../utility/json-file");
15
+ const latest_versions_1 = require("../../utility/latest-versions");
13
16
  const workspace_1 = require("../../utility/workspace");
14
17
  const workspace_models_1 = require("../../utility/workspace-models");
15
18
  const css_import_lexer_1 = require("./css-import-lexer");
@@ -17,10 +20,6 @@ function* updateBuildTarget(projectName, buildTarget, serverTarget, tree, contex
17
20
  // Update builder target and options
18
21
  buildTarget.builder = workspace_models_1.Builders.Application;
19
22
  for (const [, options] of (0, workspace_1.allTargetOptions)(buildTarget, false)) {
20
- // Show warnings for using no longer supported options
21
- if (usesNoLongerSupportedOptions(options, context, projectName)) {
22
- continue;
23
- }
24
23
  if (options['index'] === '') {
25
24
  options['index'] = false;
26
25
  }
@@ -59,7 +58,6 @@ function* updateBuildTarget(projectName, buildTarget, serverTarget, tree, contex
59
58
  }
60
59
  }
61
60
  // Delete removed options
62
- delete options['deployUrl'];
63
61
  delete options['vendorChunk'];
64
62
  delete options['commonChunk'];
65
63
  delete options['resourcesOutputPath'];
@@ -142,6 +140,45 @@ function updateProjects(tree, context) {
142
140
  const projectSourceRoot = (0, posix_1.join)(project.root, project.sourceRoot ?? 'src');
143
141
  updateStyleImports(tree, projectSourceRoot, buildTarget);
144
142
  }
143
+ // Check for @angular-devkit/build-angular Webpack usage
144
+ let hasAngularDevkitUsage = false;
145
+ for (const [, target] of (0, workspace_1.allWorkspaceTargets)(workspace)) {
146
+ switch (target.builder) {
147
+ case workspace_models_1.Builders.Application:
148
+ case workspace_models_1.Builders.DevServer:
149
+ case workspace_models_1.Builders.ExtractI18n:
150
+ // Ignore application, dev server, and i18n extraction for devkit usage check.
151
+ // Both will be replaced if no other usage is found.
152
+ continue;
153
+ }
154
+ if (target.builder.startsWith('@angular-devkit/build-angular:')) {
155
+ hasAngularDevkitUsage = true;
156
+ break;
157
+ }
158
+ }
159
+ // Use @angular/build directly if there is no devkit package usage
160
+ if (!hasAngularDevkitUsage) {
161
+ for (const [, target] of (0, workspace_1.allWorkspaceTargets)(workspace)) {
162
+ switch (target.builder) {
163
+ case workspace_models_1.Builders.Application:
164
+ target.builder = '@angular/build:application';
165
+ break;
166
+ case workspace_models_1.Builders.DevServer:
167
+ target.builder = '@angular/build:dev-server';
168
+ break;
169
+ case workspace_models_1.Builders.ExtractI18n:
170
+ target.builder = '@angular/build:extract-i18n';
171
+ break;
172
+ }
173
+ }
174
+ // Add direct @angular/build dependencies and remove @angular-devkit/build-angular
175
+ rules.push((0, dependency_1.addDependency)('@angular/build', latest_versions_1.latestVersions.DevkitBuildAngular, {
176
+ type: dependency_1.DependencyType.Dev,
177
+ install: dependency_1.InstallBehavior.Always,
178
+ existing: dependency_1.ExistingBehavior.Replace,
179
+ }));
180
+ (0, dependencies_1.removePackageJsonDependency)(tree, '@angular-devkit/build-angular');
181
+ }
145
182
  return (0, schematics_1.chain)(rules);
146
183
  });
147
184
  }
@@ -262,11 +299,3 @@ function default_1() {
262
299
  ]);
263
300
  }
264
301
  exports.default = default_1;
265
- function usesNoLongerSupportedOptions({ deployUrl }, context, projectName) {
266
- let hasUsage = false;
267
- if (typeof deployUrl === 'string') {
268
- hasUsage = true;
269
- context.logger.warn(`Skipping migration for project "${projectName}". "deployUrl" option is not available in the application builder.`);
270
- }
271
- return hasUsage;
272
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematics/angular",
3
- "version": "18.0.0-next.3",
3
+ "version": "18.0.0-next.4",
4
4
  "description": "Schematics specific to Angular",
5
5
  "homepage": "https://github.com/angular/angular-cli",
6
6
  "keywords": [
@@ -22,8 +22,8 @@
22
22
  },
23
23
  "schematics": "./collection.json",
24
24
  "dependencies": {
25
- "@angular-devkit/core": "18.0.0-next.3",
26
- "@angular-devkit/schematics": "18.0.0-next.3",
25
+ "@angular-devkit/core": "18.0.0-next.4",
26
+ "@angular-devkit/schematics": "18.0.0-next.4",
27
27
  "jsonc-parser": "3.2.1"
28
28
  },
29
29
  "repository": {
@@ -31,7 +31,7 @@
31
31
  "url": "https://github.com/angular/angular-cli.git"
32
32
  },
33
33
  "engines": {
34
- "node": "^18.19.1 || >=20.11.1",
34
+ "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
35
35
  "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
36
36
  "yarn": ">= 1.13.0"
37
37
  },
@@ -15,6 +15,6 @@ exports.latestVersions = {
15
15
  ...dependencies,
16
16
  // As Angular CLI works with same minor versions of Angular Framework, a tilde match for the current
17
17
  Angular: dependencies['@angular/core'],
18
- DevkitBuildAngular: '^18.0.0-next.3',
19
- AngularSSR: '^18.0.0-next.3',
18
+ DevkitBuildAngular: '^18.0.0-next.4',
19
+ AngularSSR: '^18.0.0-next.4',
20
20
  };
@@ -1,9 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC 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
- import { Rule } from '@angular-devkit/schematics';
9
- export default function (): Rule;
@@ -1,36 +0,0 @@
1
- "use strict";
2
- /**
3
- * @license
4
- * Copyright Google LLC All Rights Reserved.
5
- *
6
- * Use of this source code is governed by an MIT-style license that can be
7
- * found in the LICENSE file at https://angular.io/license
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- const utility_1 = require("../../utility");
11
- const dependencies_1 = require("../../utility/dependencies");
12
- const latest_versions_1 = require("../../utility/latest-versions");
13
- const workspace_1 = require("../../utility/workspace");
14
- const workspace_models_1 = require("../../utility/workspace-models");
15
- const BROWSER_SYNC_VERSION = latest_versions_1.latestVersions['browser-sync'];
16
- function default_1() {
17
- return async (tree) => {
18
- if ((0, dependencies_1.getPackageJsonDependency)(tree, 'browser-sync')?.version === BROWSER_SYNC_VERSION) {
19
- return;
20
- }
21
- const workspace = await (0, workspace_1.getWorkspace)(tree);
22
- for (const project of workspace.projects.values()) {
23
- if (project.extensions.projectType !== workspace_models_1.ProjectType.Application) {
24
- continue;
25
- }
26
- for (const target of project.targets.values()) {
27
- if (target.builder === workspace_models_1.Builders.SsrDevServer) {
28
- return (0, utility_1.addDependency)('browser-sync', BROWSER_SYNC_VERSION, {
29
- type: utility_1.DependencyType.Dev,
30
- });
31
- }
32
- }
33
- }
34
- };
35
- }
36
- exports.default = default_1;
@@ -1,9 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC 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
- import { Rule } from '@angular-devkit/schematics';
9
- export default function (): Rule;
@@ -1,47 +0,0 @@
1
- "use strict";
2
- /**
3
- * @license
4
- * Copyright Google LLC All Rights Reserved.
5
- *
6
- * Use of this source code is governed by an MIT-style license that can be
7
- * found in the LICENSE file at https://angular.io/license
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- const schematics_1 = require("@angular-devkit/schematics");
11
- const dependencies_1 = require("../../utility/dependencies");
12
- const workspace_1 = require("../../utility/workspace");
13
- const workspace_models_1 = require("../../utility/workspace-models");
14
- function default_1() {
15
- return (0, schematics_1.chain)([
16
- (0, workspace_1.updateWorkspace)((workspace) => {
17
- for (const [, project] of workspace.projects) {
18
- if (project.extensions.projectType !== workspace_models_1.ProjectType.Application) {
19
- // Only interested in application projects since these changes only effects application builders
20
- continue;
21
- }
22
- for (const [, target] of project.targets) {
23
- if (target.builder === '@nguniversal/builders:ssr-dev-server') {
24
- target.builder = '@angular-devkit/build-angular:ssr-dev-server';
25
- }
26
- else if (target.builder === '@nguniversal/builders:prerender') {
27
- target.builder = '@angular-devkit/build-angular:prerender';
28
- for (const [, options] of (0, workspace_1.allTargetOptions)(target, false)) {
29
- // Remove and replace builder options
30
- if (options['guessRoutes'] !== undefined) {
31
- options['discoverRoutes'] = options['guessRoutes'];
32
- delete options['guessRoutes'];
33
- }
34
- if (options['numProcesses'] !== undefined) {
35
- delete options['numProcesses'];
36
- }
37
- }
38
- }
39
- }
40
- }
41
- }),
42
- (host) => {
43
- (0, dependencies_1.removePackageJsonDependency)(host, '@nguniversal/builders');
44
- },
45
- ]);
46
- }
47
- exports.default = default_1;
@@ -1,9 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC 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
- import { Rule } from '@angular-devkit/schematics';
9
- export default function (): Rule;
@@ -1,197 +0,0 @@
1
- "use strict";
2
- /**
3
- * @license
4
- * Copyright Google LLC All Rights Reserved.
5
- *
6
- * Use of this source code is governed by an MIT-style license that can be
7
- * found in the LICENSE file at https://angular.io/license
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- const schematics_1 = require("@angular-devkit/schematics");
11
- const posix_1 = require("node:path/posix");
12
- const utility_1 = require("../../utility");
13
- const dependencies_1 = require("../../utility/dependencies");
14
- const latest_versions_1 = require("../../utility/latest-versions");
15
- const workspace_1 = require("../../utility/workspace");
16
- const workspace_models_1 = require("../../utility/workspace-models");
17
- function* visit(directory) {
18
- for (const path of directory.subfiles) {
19
- if (path.endsWith('.ts') && !path.endsWith('.d.ts')) {
20
- const entry = directory.file(path);
21
- if (entry) {
22
- const content = entry.content;
23
- if (content.includes('@nguniversal/')) {
24
- // Only need to rename the import so we can just string replacements.
25
- yield [entry.path, content.toString()];
26
- }
27
- }
28
- }
29
- }
30
- for (const path of directory.subdirs) {
31
- if (path === 'node_modules' || path.startsWith('.')) {
32
- continue;
33
- }
34
- yield* visit(directory.dir(path));
35
- }
36
- }
37
- const UNIVERSAL_PACKAGES = ['@nguniversal/common', '@nguniversal/express-engine'];
38
- /**
39
- * Regexp to match Universal packages.
40
- * @nguniversal/common/engine
41
- * @nguniversal/common
42
- * @nguniversal/express-engine
43
- **/
44
- const NGUNIVERSAL_PACKAGE_REGEXP = /@nguniversal\/(common(\/engine)?|express-engine)/g;
45
- function default_1() {
46
- return async (tree) => {
47
- const hasUniversalDeps = UNIVERSAL_PACKAGES.some((d) => (0, dependencies_1.getPackageJsonDependency)(tree, d));
48
- if (!hasUniversalDeps) {
49
- return;
50
- }
51
- return (0, schematics_1.chain)([
52
- async (tree) => {
53
- // Replace server file.
54
- const workspace = await (0, workspace_1.getWorkspace)(tree);
55
- for (const [, project] of workspace.projects) {
56
- if (project.extensions.projectType !== workspace_models_1.ProjectType.Application) {
57
- continue;
58
- }
59
- const serverMainFiles = new Map();
60
- for (const [, target] of project.targets) {
61
- if (target.builder !== workspace_models_1.Builders.Server) {
62
- continue;
63
- }
64
- const outputPath = project.targets.get('build')?.options?.outputPath;
65
- for (const [, { main }] of (0, workspace_1.allTargetOptions)(target, false)) {
66
- if (typeof main === 'string' &&
67
- typeof outputPath === 'string' &&
68
- tree.readText(main).includes('ngExpressEngine')) {
69
- serverMainFiles.set(main, outputPath);
70
- }
71
- }
72
- }
73
- // Replace all import specifiers in all files.
74
- let hasExpressTokens = false;
75
- const root = project.sourceRoot ?? `${project.root}/src`;
76
- const tokensFilePath = `/${root}/express.tokens.ts`;
77
- for (const file of visit(tree.getDir(root))) {
78
- const [path, content] = file;
79
- let updatedContent = content;
80
- // Check if file is importing tokens
81
- if (content.includes('@nguniversal/express-engine/tokens')) {
82
- hasExpressTokens ||= true;
83
- let tokensFileRelativePath = (0, posix_1.relative)((0, posix_1.dirname)(path), tokensFilePath);
84
- if (tokensFileRelativePath.charAt(0) !== '.') {
85
- tokensFileRelativePath = './' + tokensFileRelativePath;
86
- }
87
- updatedContent = updatedContent.replaceAll('@nguniversal/express-engine/tokens', tokensFileRelativePath.slice(0, -3));
88
- }
89
- updatedContent = updatedContent.replaceAll(NGUNIVERSAL_PACKAGE_REGEXP, '@angular/ssr');
90
- tree.overwrite(path, updatedContent);
91
- }
92
- // Replace server file and add tokens file if needed
93
- for (const [path, outputPath] of serverMainFiles.entries()) {
94
- tree.rename(path, path + '.bak');
95
- tree.create(path, getServerFileContents(outputPath, hasExpressTokens));
96
- if (hasExpressTokens) {
97
- tree.create(tokensFilePath, TOKENS_FILE_CONTENT);
98
- }
99
- }
100
- }
101
- // Remove universal packages from deps.
102
- for (const name of UNIVERSAL_PACKAGES) {
103
- (0, dependencies_1.removePackageJsonDependency)(tree, name);
104
- }
105
- },
106
- (0, utility_1.addDependency)('@angular/ssr', latest_versions_1.latestVersions.AngularSSR),
107
- ]);
108
- };
109
- }
110
- exports.default = default_1;
111
- const TOKENS_FILE_CONTENT = `
112
- import { InjectionToken } from '@angular/core';
113
- import { Request, Response } from 'express';
114
-
115
- export const REQUEST = new InjectionToken<Request>('REQUEST');
116
- export const RESPONSE = new InjectionToken<Response>('RESPONSE');
117
- `;
118
- function getServerFileContents(outputPath, hasExpressTokens) {
119
- return (`
120
- import 'zone.js/node';
121
-
122
- import { APP_BASE_HREF } from '@angular/common';
123
- import { CommonEngine } from '@angular/ssr';
124
- import * as express from 'express';
125
- import { existsSync } from 'node:fs';
126
- import { join } from 'node:path';
127
- import bootstrap from './src/main.server';` +
128
- (hasExpressTokens ? `\nimport { REQUEST, RESPONSE } from './src/express.tokens';` : '') +
129
- `
130
-
131
- // The Express app is exported so that it can be used by serverless Functions.
132
- export function app(): express.Express {
133
- const server = express();
134
- const distFolder = join(process.cwd(), '${outputPath}');
135
- const indexHtml = existsSync(join(distFolder, 'index.original.html'))
136
- ? join(distFolder, 'index.original.html')
137
- : join(distFolder, 'index.html');
138
-
139
- const commonEngine = new CommonEngine();
140
-
141
- server.set('view engine', 'html');
142
- server.set('views', distFolder);
143
-
144
- // Example Express Rest API endpoints
145
- // server.get('/api/**', (req, res) => { });
146
- // Serve static files from /browser
147
- server.get('*.*', express.static(distFolder, {
148
- maxAge: '1y'
149
- }));
150
-
151
- // All regular routes use the Angular engine
152
- server.get('*', (req, res, next) => {
153
- const { protocol, originalUrl, baseUrl, headers } = req;
154
-
155
- commonEngine
156
- .render({
157
- bootstrap,
158
- documentFilePath: indexHtml,
159
- url: \`\${protocol}://\${headers.host}\${originalUrl}\`,
160
- publicPath: distFolder,
161
- providers: [
162
- { provide: APP_BASE_HREF, useValue: baseUrl },` +
163
- (hasExpressTokens
164
- ? '\n { provide: RESPONSE, useValue: res },\n { provide: REQUEST, useValue: req }\n'
165
- : '') +
166
- `],
167
- })
168
- .then((html) => res.send(html))
169
- .catch((err) => next(err));
170
- });
171
-
172
- return server;
173
- }
174
-
175
- function run(): void {
176
- const port = process.env['PORT'] || 4000;
177
-
178
- // Start up the Node server
179
- const server = app();
180
- server.listen(port, () => {
181
- console.log(\`Node Express server listening on http://localhost:\${port}\`);
182
- });
183
- }
184
-
185
- // Webpack will replace 'require' with '__webpack_require__'
186
- // '__non_webpack_require__' is a proxy to Node 'require'
187
- // The below code is to ensure that the server is run only when not requiring the bundle.
188
- declare const __non_webpack_require__: NodeRequire;
189
- const mainModule = __non_webpack_require__.main;
190
- const moduleFilename = mainModule && mainModule.filename || '';
191
- if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
192
- run();
193
- }
194
-
195
- export default bootstrap;
196
- `);
197
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC 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
- import { Rule } from '@angular-devkit/schematics';
9
- export default function (): Rule;
@@ -1,32 +0,0 @@
1
- "use strict";
2
- /**
3
- * @license
4
- * Copyright Google LLC All Rights Reserved.
5
- *
6
- * Use of this source code is governed by an MIT-style license that can be
7
- * found in the LICENSE file at https://angular.io/license
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- const workspace_1 = require("../../utility/workspace");
11
- const workspace_models_1 = require("../../utility/workspace-models");
12
- function default_1() {
13
- return (0, workspace_1.updateWorkspace)((workspace) => {
14
- for (const [, project] of workspace.projects) {
15
- if (project.extensions.projectType !== workspace_models_1.ProjectType.Application) {
16
- // Only interested in application projects since these changes only effects application builders
17
- continue;
18
- }
19
- for (const [, target] of project.targets) {
20
- if (target.builder === workspace_models_1.Builders.ExtractI18n || target.builder === workspace_models_1.Builders.DevServer) {
21
- for (const [, options] of (0, workspace_1.allTargetOptions)(target, false)) {
22
- if (options['browserTarget'] !== undefined) {
23
- options['buildTarget'] = options['browserTarget'];
24
- delete options['browserTarget'];
25
- }
26
- }
27
- }
28
- }
29
- }
30
- });
31
- }
32
- exports.default = default_1;