feat(angular): add --bundler flag for applications (#17919)

This commit is contained in:
Colum Ferry 2023-07-03 16:22:37 +01:00 committed by GitHub
parent 55c0a168cf
commit 9eaa240b4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 65 additions and 17 deletions

View File

@ -161,6 +161,12 @@
"description": "Generate a Angular app with a minimal setup.",
"type": "boolean",
"default": false
},
"bundler": {
"description": "Bundler to use to build the application.",
"type": "string",
"enum": ["webpack", "esbuild"],
"default": "webpack"
}
},
"additionalProperties": false,

View File

@ -53,6 +53,11 @@ describe('Angular Projects', () => {
`generate @nx/angular:app ${standaloneApp} --directory=myDir --standalone=true --no-interactive`
);
const esbuildApp = uniq('esbuild-app');
runCLI(
`generate @nx/angular:app ${esbuildApp} --bundler=esbuild --directory=myDir --no-interactive`
);
updateFile(
`apps/${app1}/src/app/app.module.ts`,
`
@ -73,10 +78,11 @@ describe('Angular Projects', () => {
// check build
runCLI(
`run-many --target build --projects=${app1},my-dir-${standaloneApp} --parallel --prod --output-hashing none`
`run-many --target build --projects=${app1},my-dir-${standaloneApp},my-dir-${esbuildApp} --parallel --prod --output-hashing none`
);
checkFilesExist(`dist/apps/${app1}/main.js`);
checkFilesExist(`dist/apps/my-dir/${standaloneApp}/main.js`);
checkFilesExist(`dist/apps/my-dir/${esbuildApp}/index.html`);
// This is a loose requirement because there are a lot of
// influences external from this project that affect this.
const es2015BundleSize = getSize(tmpProjPath(`dist/apps/${app1}/main.js`));
@ -87,7 +93,7 @@ describe('Angular Projects', () => {
// check unit tests
runCLI(
`run-many --target test --projects=${app1},my-dir-${standaloneApp},${lib1} --parallel`
`run-many --target test --projects=${app1},my-dir-${standaloneApp},my-dir-${esbuildApp},${lib1} --parallel`
);
// check e2e tests

View File

@ -969,6 +969,27 @@ describe('app', () => {
appTree.read('apps/plain/src/app/app.component.html', 'utf-8')
).toMatchSnapshot();
});
it('should generate a correct build target for --bundler=esbuild', async () => {
await generateApp(appTree, 'ngesbuild', {
routing: true,
bundler: 'esbuild',
});
const project = readProjectConfiguration(appTree, 'ngesbuild');
expect(project.targets.build.executor).toEqual(
'@angular-devkit/build-angular:browser-esbuild'
);
expect(
project.targets.build.configurations.development.namedChunks
).toBeUndefined();
expect(
project.targets.build.configurations.development.vendorChunks
).toBeUndefined();
expect(
project.targets.build.configurations.production.budgets
).toBeUndefined();
});
});
});

View File

@ -6,6 +6,10 @@ import type { NormalizedSchema } from './normalized-schema';
export function createProject(tree: Tree, options: NormalizedSchema) {
const installedAngularInfo = getInstalledAngularVersionInfo(tree);
const buildExecutor =
options.bundler === 'webpack'
? '@angular-devkit/build-angular:browser'
: '@angular-devkit/build-angular:browser-esbuild';
const project: AngularProjectConfiguration = {
name: options.name,
projectType: 'application',
@ -15,7 +19,7 @@ export function createProject(tree: Tree, options: NormalizedSchema) {
tags: options.parsedTags,
targets: {
build: {
executor: '@angular-devkit/build-angular:browser',
executor: buildExecutor,
outputs: ['{options.outputPath}'],
options: {
outputPath: `dist/${
@ -37,18 +41,21 @@ export function createProject(tree: Tree, options: NormalizedSchema) {
},
configurations: {
production: {
budgets: [
{
type: 'initial',
maximumWarning: '500kb',
maximumError: '1mb',
},
{
type: 'anyComponentStyle',
maximumWarning: '2kb',
maximumError: '4kb',
},
],
budgets:
options.bundler === 'webpack'
? [
{
type: 'initial',
maximumWarning: '500kb',
maximumError: '1mb',
},
{
type: 'anyComponentStyle',
maximumWarning: '2kb',
maximumError: '4kb',
},
]
: undefined,
fileReplacements:
installedAngularInfo.major === 14
? [
@ -63,10 +70,10 @@ export function createProject(tree: Tree, options: NormalizedSchema) {
development: {
buildOptimizer: false,
optimization: false,
vendorChunk: true,
vendorChunk: options.bundler === 'webpack' ? true : undefined,
extractLicenses: false,
sourceMap: true,
namedChunks: true,
namedChunks: options.bundler === 'webpack' ? true : undefined,
},
},
defaultConfiguration: 'production',

View File

@ -68,6 +68,7 @@ export function normalizeOptions(
e2eTestRunner: E2eTestRunner.Cypress,
linter: Linter.EsLint,
strict: true,
bundler: options.bundler ?? 'webpack',
...options,
prefix,
name: appProjectName,

View File

@ -27,4 +27,5 @@ export interface Schema {
standalone?: boolean;
rootProject?: boolean;
minimal?: boolean;
bundler?: 'webpack' | 'esbuild';
}

View File

@ -164,6 +164,12 @@
"description": "Generate a Angular app with a minimal setup.",
"type": "boolean",
"default": false
},
"bundler": {
"description": "Bundler to use to build the application.",
"type": "string",
"enum": ["webpack", "esbuild"],
"default": "webpack"
}
},
"additionalProperties": false,