diff --git a/examples/custom-esbuild/sanity-esbuild-app/angular.json b/examples/custom-esbuild/sanity-esbuild-app/angular.json index bf46ee4396..068af97671 100644 --- a/examples/custom-esbuild/sanity-esbuild-app/angular.json +++ b/examples/custom-esbuild/sanity-esbuild-app/angular.json @@ -80,6 +80,14 @@ } } ] + }, + "target-options-test": { + "plugins": [ + "esbuild/define-configuration-plugin.js" + ], + "indexHtmlTransformer": "esbuild/configuration-transformer.js", + "optimization": false, + "outputHashing": "none" } }, "defaultConfiguration": "production" @@ -206,4 +214,4 @@ "typeSeparator": "." } } -} +} \ No newline at end of file diff --git a/examples/custom-esbuild/sanity-esbuild-app/esbuild/configuration-transformer.js b/examples/custom-esbuild/sanity-esbuild-app/esbuild/configuration-transformer.js new file mode 100644 index 0000000000..63bb308295 --- /dev/null +++ b/examples/custom-esbuild/sanity-esbuild-app/esbuild/configuration-transformer.js @@ -0,0 +1,10 @@ +/** + * Index HTML transformer for issues #1690 / #1710 test. + * Signature: (indexHtml: string, target: Target) => string + * Injects a tag with the configuration name so we can verify it in the output file. + */ +module.exports = function configurationTransformer(indexHtml, target) { + const configuration = target.configuration ?? 'default'; + const metaTag = ``; + return indexHtml.replace('', ` ${metaTag}\n`); +}; diff --git a/examples/custom-esbuild/sanity-esbuild-app/esbuild/define-configuration-plugin.js b/examples/custom-esbuild/sanity-esbuild-app/esbuild/define-configuration-plugin.js new file mode 100644 index 0000000000..8a5bb7e45a --- /dev/null +++ b/examples/custom-esbuild/sanity-esbuild-app/esbuild/define-configuration-plugin.js @@ -0,0 +1,21 @@ +/** + * Factory plugin (Pattern 1: string path in angular.json). + * Receives (builderOptions, target) from the builder. + * Injects `target.configuration` as a global define constant `buildConfiguration`. + * + * This is the test for issues #1710 and #1690: + * verifying that target.configuration is accessible inside a factory plugin. + */ +function defineConfigurationPlugin(builderOptions, target) { + const configuration = target.configuration ?? 'default'; + return { + name: 'define-configuration', + setup(build) { + const options = build.initialOptions; + options.define = options.define || {}; + options.define.buildConfiguration = JSON.stringify(configuration); + }, + }; +} + +module.exports = defineConfigurationPlugin; diff --git a/examples/custom-esbuild/sanity-esbuild-app/package.json b/examples/custom-esbuild/sanity-esbuild-app/package.json index fd76748c4a..ff4c824081 100644 --- a/examples/custom-esbuild/sanity-esbuild-app/package.json +++ b/examples/custom-esbuild/sanity-esbuild-app/package.json @@ -8,7 +8,8 @@ "lint": "ng lint", "e2e": "ng e2e", "cypress:open": "cypress open", - "cypress:run": "cypress run" + "cypress:run": "cypress run", + "build-target-options": "ng build --configuration target-options-test && node -e \"const fs = require('fs');const dist = 'dist/sanity-esbuild-app/browser';const indexHtml = fs.readFileSync(dist + '/index.html', 'utf8');const jsFiles = fs.readdirSync(dist).filter(f => f.endsWith('.js'));const mainJs = jsFiles.map(f => fs.readFileSync(dist + '/' + f, 'utf8')).join('');if (!indexHtml.includes('content=\\\"target-options-test\\\"')) { console.error('FAIL: indexHtmlTransformer did not inject configuration into index.html'); process.exit(1); }if (!mainJs.includes('target-options-test')) { console.error('FAIL: plugin did not inject buildConfiguration into JS bundle'); process.exit(1); }console.log('PASS: target.configuration is accessible in both plugin and indexHtmlTransformer');\"" }, "private": true, "dependencies": { @@ -42,4 +43,4 @@ "typescript-eslint": "8.59.0", "vitest": "4.1.5" } -} +} \ No newline at end of file diff --git a/examples/custom-esbuild/sanity-esbuild-app/src/app/app.component.html b/examples/custom-esbuild/sanity-esbuild-app/src/app/app.component.html index 7034c8f302..7e7a14d708 100644 --- a/examples/custom-esbuild/sanity-esbuild-app/src/app/app.component.html +++ b/examples/custom-esbuild/sanity-esbuild-app/src/app/app.component.html @@ -1,3 +1,4 @@
{{ buildConfiguration }}
diff --git a/examples/custom-esbuild/sanity-esbuild-app/src/app/app.component.ts b/examples/custom-esbuild/sanity-esbuild-app/src/app/app.component.ts index b878467344..ca0d751028 100644 --- a/examples/custom-esbuild/sanity-esbuild-app/src/app/app.component.ts +++ b/examples/custom-esbuild/sanity-esbuild-app/src/app/app.component.ts @@ -3,6 +3,7 @@ import { Component } from '@angular/core'; declare const title: string; declare const subtitle: string; declare const titleByOption: string; +declare const buildConfiguration: string; @Component({ selector: 'app-root', @@ -14,10 +15,12 @@ export class AppComponent { title: string; subtitle: string; titleByOption: string; + buildConfiguration: string; constructor() { this.title = typeof title !== 'undefined' ? title : 'sanity-esbuild-app'; this.subtitle = typeof subtitle !== 'undefined' ? subtitle : 'sanity-esbuild-app subtitle'; this.titleByOption = typeof titleByOption !== 'undefined' ? titleByOption : 'sanity-esbuild-app optionTitle'; + this.buildConfiguration = typeof buildConfiguration !== 'undefined' ? buildConfiguration : 'no-config'; } } diff --git a/packages/custom-esbuild/README.md b/packages/custom-esbuild/README.md index 7fcaf14728..931877908c 100644 --- a/packages/custom-esbuild/README.md +++ b/packages/custom-esbuild/README.md @@ -202,7 +202,10 @@ export default (builderOptions: ApplicationBuilderOptions, target: Target): Plug name: 'define-text', setup(build: PluginBuild) { const options = build.initialOptions; + // target.project is the Angular project name (e.g. "my-app") options.define.currentProject = JSON.stringify(target.project); + // target.configuration is the active build configuration (e.g. "production", "staging") + options.define.currentConfiguration = JSON.stringify(target.configuration ?? 'default'); }, }; }; @@ -296,7 +299,9 @@ It is useful when you want to transform your `index.html` according to the build `index-html-transformer.js`: ```js -module.exports = indexHtml => { +module.exports = (indexHtml, target) => { + // target.configuration is the active build configuration (e.g. "production", "staging") + // target.project is the Angular project name const i = indexHtml.indexOf('