From 2b262401b8daaa14fad46577b2ed7c24a038f59c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 1 Apr 2025 20:06:56 -0400 Subject: [PATCH] refactor(@angular/build): provide a default for the application index option The application build system's `index` option is now considered optional. If not present, the value will be an `index.html` file within the configured project source root (`sourceRoot`). The default only applies to the short-form of the option. The object-based long-form continues to require explicit configuration of the input index HTML file. This change allows the removal of the `index` option from any project that uses the default generated value. --- goldens/public-api/angular/build/index.api.md | 2 +- .../build/src/builders/application/options.ts | 12 +++++++----- .../build/src/builders/application/schema.json | 2 +- .../application/tests/options/index_spec.ts | 17 +++++++++++++++++ 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/goldens/public-api/angular/build/index.api.md b/goldens/public-api/angular/build/index.api.md index 062f6d92ff38..bf620bfa15c4 100644 --- a/goldens/public-api/angular/build/index.api.md +++ b/goldens/public-api/angular/build/index.api.md @@ -40,7 +40,7 @@ export type ApplicationBuilderOptions = { fileReplacements?: FileReplacement[]; i18nDuplicateTranslation?: I18NTranslation; i18nMissingTranslation?: I18NTranslation; - index: IndexUnion; + index?: IndexUnion; inlineStyleLanguage?: InlineStyleLanguage; loader?: { [key: string]: any; diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index 5db6d2c41e16..f2950dcb9629 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -332,11 +332,16 @@ export async function normalizeOptions( let indexHtmlOptions; // index can never have a value of `true` but in the schema it's of type `boolean`. if (typeof options.index !== 'boolean') { + let indexInput: string; let indexOutput: string; // The output file will be created within the configured output path if (typeof options.index === 'string') { - indexOutput = options.index; + indexInput = indexOutput = path.join(workspaceRoot, options.index); + } else if (typeof options.index === 'undefined') { + indexInput = path.join(projectSourceRoot, 'index.html'); + indexOutput = 'index.html'; } else { + indexInput = path.join(workspaceRoot, options.index.input); indexOutput = options.index.output || 'index.html'; } @@ -356,10 +361,7 @@ export async function normalizeOptions( : indexBaseName; indexHtmlOptions = { - input: path.join( - workspaceRoot, - typeof options.index === 'string' ? options.index : options.index.input, - ), + input: indexInput, output: indexOutput, insertionOrder: [ ['polyfills', true], diff --git a/packages/angular/build/src/builders/application/schema.json b/packages/angular/build/src/builders/application/schema.json index b34dabe49f7c..934bfe9390f4 100644 --- a/packages/angular/build/src/builders/application/schema.json +++ b/packages/angular/build/src/builders/application/schema.json @@ -616,7 +616,7 @@ } }, "additionalProperties": false, - "required": ["index", "browser", "tsConfig"], + "required": ["browser", "tsConfig"], "definitions": { "assetPattern": { "oneOf": [ diff --git a/packages/angular/build/src/builders/application/tests/options/index_spec.ts b/packages/angular/build/src/builders/application/tests/options/index_spec.ts index d3a5fe9e57d3..11228658bbce 100644 --- a/packages/angular/build/src/builders/application/tests/options/index_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/index_spec.ts @@ -62,6 +62,23 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { harness.expectFile('dist/browser/index.html').content.toContain('TEST_123'); }); + it('should use the the index.html file within the project source root when not present', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + index: undefined, + }); + + await harness.writeFile( + 'src/index.html', + 'TEST_123', + ); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + harness.expectFile('dist/browser/index.html').content.toContain('TEST_123'); + }); + // TODO: Build needs to be fixed to not throw an unhandled exception for this case xit('should fail build when a string path to non-existent file', async () => { harness.useTarget('build', {