Skip to content

Commit 135a055

Browse files
committed
feat(@schematics/angular): directly use @angular/build in new projects
The `@angular/build` package is now used directly within all newly created projects and replaces the previous usage of the `@angular-devkit/build-angular` package. This has the advantage of removing the need to install all of the Webpack related transitive dependencies contained within `@angular-devkit/build-angular` that are used to support the `browser` builder. This results in a significant reduction in both total dependency count and disk install size for new projects. New projects that would prefer to use the Webpack-based `browser` builder can still install the `@angular-devkit/build-angular` package within the workspace. The `@angular/build@19.2.0-next.2` package currently has a total unpacked size of ~115 MB. The `@angular-devkit/build-angular@19.2.0-next.2` package currently has a total unpacked size of ~291 MB.
1 parent 9f870b4 commit 135a055

File tree

11 files changed

+70
-25
lines changed

11 files changed

+70
-25
lines changed

packages/angular/pwa/pwa/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,14 @@ export default function (options: PwaOptions): Rule {
9696
for (const target of project.targets.values()) {
9797
if (
9898
target.builder === '@angular-devkit/build-angular:browser' ||
99-
target.builder === '@angular-devkit/build-angular:application'
99+
target.builder === '@angular-devkit/build-angular:application' ||
100+
target.builder === '@angular/build:application'
100101
) {
101102
buildTargets.push(target);
102-
} else if (target.builder === '@angular-devkit/build-angular:karma') {
103+
} else if (
104+
target.builder === '@angular-devkit/build-angular:karma' ||
105+
target.builder === '@angular/build:karma'
106+
) {
103107
testTargets.push(target);
104108
}
105109
}

packages/schematics/angular/application/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ function addDependenciesToPackageJson(options: ApplicationOptions) {
120120
},
121121
{
122122
type: NodeDependencyType.Dev,
123-
name: '@angular-devkit/build-angular',
124-
version: latestVersions.DevkitBuildAngular,
123+
name: '@angular/build',
124+
version: latestVersions.AngularBuild,
125125
},
126126
{
127127
type: NodeDependencyType.Dev,
@@ -234,7 +234,7 @@ function addAppToWorkspaceFile(
234234
schematics,
235235
targets: {
236236
build: {
237-
builder: Builders.Application,
237+
builder: Builders.BuildApplication,
238238
defaultConfiguration: 'production',
239239
options: {
240240
outputPath: `dist/${folderName}`,
@@ -260,7 +260,7 @@ function addAppToWorkspaceFile(
260260
},
261261
},
262262
serve: {
263-
builder: Builders.DevServer,
263+
builder: Builders.BuildDevServer,
264264
defaultConfiguration: 'development',
265265
options: {},
266266
configurations: {
@@ -273,12 +273,12 @@ function addAppToWorkspaceFile(
273273
},
274274
},
275275
'extract-i18n': {
276-
builder: Builders.ExtractI18n,
276+
builder: Builders.BuildExtractI18n,
277277
},
278278
test: options.minimal
279279
? undefined
280280
: {
281-
builder: Builders.Karma,
281+
builder: Builders.BuildKarma,
282282
options: {
283283
polyfills: options.experimentalZoneless ? [] : ['zone.js', 'zone.js/testing'],
284284
tsConfig: `${projectRoot}tsconfig.spec.json`,

packages/schematics/angular/application/index_spec.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,11 @@ describe('Application Schematic', () => {
205205
});
206206

207207
describe(`update package.json`, () => {
208-
it(`should add build-angular to devDependencies`, async () => {
208+
it(`should add @angular/build to devDependencies`, async () => {
209209
const tree = await schematicRunner.runSchematic('application', defaultOptions, workspaceTree);
210210

211211
const packageJson = JSON.parse(tree.readContent('package.json'));
212-
expect(packageJson.devDependencies['@angular-devkit/build-angular']).toEqual(
213-
latestVersions.DevkitBuildAngular,
214-
);
212+
expect(packageJson.devDependencies['@angular/build']).toEqual(latestVersions.AngularBuild);
215213
});
216214

217215
it('should use the latest known versions in package.json', async () => {

packages/schematics/angular/config/files/karma.conf.js.template

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
module.exports = function (config) {
55
config.set({
66
basePath: '',
7-
frameworks: ['jasmine', '@angular-devkit/build-angular'],
7+
frameworks: ['jasmine'<% if (needDevkitPlugin) { %>, '@angular-devkit/build-angular'<% } %>],
88
plugins: [
99
require('karma-jasmine'),
1010
require('karma-chrome-launcher'),
1111
require('karma-jasmine-html-reporter'),
12-
require('karma-coverage'),
13-
require('@angular-devkit/build-angular/plugins/karma')
12+
require('karma-coverage'),<% if (needDevkitPlugin) { %>
13+
require('@angular-devkit/build-angular/plugins/karma')<% } %>
1414
],
1515
client: {
1616
jasmine: {

packages/schematics/angular/config/index.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,13 @@ function addKarmaConfig(options: ConfigOptions): Rule {
6666
);
6767
}
6868

69-
if (testTarget.builder !== AngularBuilder.Karma) {
69+
if (
70+
testTarget.builder !== AngularBuilder.Karma &&
71+
testTarget.builder !== AngularBuilder.BuildKarma
72+
) {
7073
throw new SchematicsException(
71-
`Cannot add a karma configuration as builder for "test" target in project does not use "${AngularBuilder.Karma}".`,
74+
`Cannot add a karma configuration as builder for "test" target in project does not` +
75+
` use "${AngularBuilder.Karma}" or "${AngularBuilder.BuildKarma}".`,
7276
);
7377
}
7478

@@ -87,6 +91,7 @@ function addKarmaConfig(options: ConfigOptions): Rule {
8791
applyTemplates({
8892
relativePathToWorkspaceRoot: relativePathToWorkspaceRoot(project.root),
8993
folderName,
94+
needDevkitPlugin: testTarget.builder === AngularBuilder.Karma,
9095
}),
9196
move(project.root),
9297
]),

packages/schematics/angular/config/index_spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,24 @@ describe('Config Schematic', () => {
5858
expect(tree.exists('projects/foo/karma.conf.js')).toBeTrue();
5959
});
6060

61+
it('should not include devkit karma plugin by default', async () => {
62+
const tree = await runConfigSchematic(ConfigType.Karma);
63+
const karmaConf = tree.readText('projects/foo/karma.conf.js');
64+
expect(karmaConf).not.toContain(`'@angular-devkit/build-angular'`);
65+
});
66+
67+
it('should include devkit karma plugin with angular-devkit/build-angular: karma is used', async () => {
68+
applicationTree.overwrite(
69+
'angular.json',
70+
applicationTree
71+
.readText('angular.json')
72+
.replace('@angular/build:karma', '@angular-devkit/build-angular:karma'),
73+
);
74+
const tree = await runConfigSchematic(ConfigType.Karma);
75+
const karmaConf = tree.readText('projects/foo/karma.conf.js');
76+
expect(karmaConf).toContain(`'@angular-devkit/build-angular'`);
77+
});
78+
6179
it('should set the right coverage folder', async () => {
6280
const tree = await runConfigSchematic(ConfigType.Karma);
6381
const karmaConf = tree.readText('projects/foo/karma.conf.js');

packages/schematics/angular/library/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ function addDependenciesToPackageJson() {
5353
},
5454
{
5555
type: NodeDependencyType.Dev,
56-
name: '@angular-devkit/build-angular',
57-
version: latestVersions.DevkitBuildAngular,
56+
name: '@angular/build',
57+
version: latestVersions.AngularBuild,
5858
},
5959
{
6060
type: NodeDependencyType.Dev,
@@ -91,7 +91,7 @@ function addLibToWorkspaceFile(
9191
prefix: options.prefix,
9292
targets: {
9393
build: {
94-
builder: Builders.NgPackagr,
94+
builder: Builders.BuildNgPackagr,
9595
defaultConfiguration: 'production',
9696
options: {
9797
project: `${projectRoot}/ng-package.json`,
@@ -106,7 +106,7 @@ function addLibToWorkspaceFile(
106106
},
107107
},
108108
test: {
109-
builder: Builders.Karma,
109+
builder: Builders.BuildKarma,
110110
options: {
111111
tsConfig: `${projectRoot}/tsconfig.spec.json`,
112112
polyfills: ['zone.js', 'zone.js/testing'],

packages/schematics/angular/library/index_spec.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,14 @@ describe('Library Schematic', () => {
388388
const tree = await schematicRunner.runSchematic('library', defaultOptions, workspaceTree);
389389

390390
const workspace = JSON.parse(tree.readContent('/angular.json'));
391-
expect(workspace.projects.foo.architect.build.builder).toBe(
392-
'@angular-devkit/build-angular:ng-packagr',
393-
);
391+
expect(workspace.projects.foo.architect.build.builder).toBe('@angular/build:ng-packagr');
392+
});
393+
394+
it(`should add 'karma' test builder`, async () => {
395+
const tree = await schematicRunner.runSchematic('library', defaultOptions, workspaceTree);
396+
397+
const workspace = JSON.parse(tree.readContent('/angular.json'));
398+
expect(workspace.projects.foo.architect.test.builder).toBe('@angular/build:karma');
394399
});
395400

396401
describe('standalone=false', () => {

packages/schematics/angular/service-worker/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ export default function (options: ServiceWorkerOptions): Rule {
122122
let browserEntryPoint: string | undefined;
123123
const ngswConfigPath = join(normalize(project.root), 'ngsw-config.json');
124124

125-
if (buildTarget.builder === Builders.Application) {
125+
if (
126+
buildTarget.builder === Builders.Application ||
127+
buildTarget.builder === Builders.BuildApplication
128+
) {
126129
browserEntryPoint = buildOptions.browser as string;
127130
const productionConf = buildTarget.configurations?.production;
128131
if (productionConf) {

packages/schematics/angular/utility/workspace-models.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,14 @@ export enum Builders {
2626
Prerender = '@angular-devkit/build-angular:prerender',
2727
BrowserEsbuild = '@angular-devkit/build-angular:browser-esbuild',
2828
Karma = '@angular-devkit/build-angular:karma',
29+
BuildKarma = '@angular/build:karma',
2930
TsLint = '@angular-devkit/build-angular:tslint',
3031
NgPackagr = '@angular-devkit/build-angular:ng-packagr',
3132
BuildNgPackagr = '@angular/build:ng-packagr',
3233
DevServer = '@angular-devkit/build-angular:dev-server',
34+
BuildDevServer = '@angular/build:dev-server',
3335
ExtractI18n = '@angular-devkit/build-angular:extract-i18n',
36+
BuildExtractI18n = '@angular/build:extract-i18n',
3437
Protractor = '@angular-devkit/build-angular:private-protractor',
3538
BuildApplication = '@angular/build:application',
3639
}

tests/legacy-cli/e2e/initialize/500-create-project.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,21 @@ export default async function () {
4343
namedChunks: true,
4444
buildOptimizer: false,
4545
};
46+
47+
const test = json['projects']['test-project']['architect']['test'];
48+
test.builder = '@angular-devkit/build-angular:karma';
4649
});
4750
await updateJsonFile('tsconfig.json', (tsconfig) => {
4851
delete tsconfig.compilerOptions.esModuleInterop;
4952
tsconfig.compilerOptions.allowSyntheticDefaultImports = true;
5053
});
5154
}
55+
56+
// Always need `@angular-devkit/build-angular` due to the use of protractor
57+
await updateJsonFile('package.json', (packageJson) => {
58+
packageJson.devDependencies['@angular-devkit/build-angular'] =
59+
packageJson.devDependencies['@angular/build'];
60+
});
5261
}
5362

5463
await prepareProjectForE2e('test-project');

0 commit comments

Comments
 (0)