title: Angular (8) application build once (with production config) and deploy to multiple environments
body: <p>I have a situation where I’m trying to build my angular application with production config and deploy to multiple environments, say, <strong>ng build --configuration=production</strong></p>
  
  <p>The work flow here is when I build using the above command (<strong>ng build --configuration=production</strong>), the environment.ts file gets replaced with environment.prod.ts </p>
  
  <p>The configurations I have in environment.prod.ts is as follows,</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>export const environment = {
    production: true,
    environment: 'Production',
    _webApiHost: 'prodsomename.company.com/api/',
  };</code></pre>
  </div>
  </div>
  </p>
  
  <p>The configurations I have in environmrnt.test.ts is as follows,</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>export const environment = {
      production: true,
      environment: 'Test',
      _webApiHost: 'testsomename.company.com/api/',
  };</code></pre>
  </div>
  </div>
  </p>
  
  <p>The setting I have on angular.json file is as follows,</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>"configurations": {
              "production": {
                "fileReplacements": [ {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                } ],
                "optimization": true,
                "outputHashing": "all",
                "sourceMap": false,
                "extractCss": true,
                "namedChunks": false,
                "aot": true,
                "extractLicenses": true,
                "vendorChunk": false,
                "buildOptimizer": true,
                "budgets": [ {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                } ]
              },
              "test": {
                "fileReplacements": [ {
                  "replace": "src/assets/configs/environment.ts",
                  "with": "src/assets/configs/environment.test.ts"
                } ],
                "optimization": true,
                "outputHashing": "all",
                "sourceMap": false,
                "extractCss": true,
                "namedChunks": false,
                "aot": true,
                "extractLicenses": true,
                "vendorChunk": false,
                "buildOptimizer": true,
                "budgets": [ {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                } ]
              }
            }</code></pre>
  </div>
  </div>
  </p>
  
  <p>If I build the solution for every environment separately and deploy to appropriate environment as below figure,
  <a href="https://i.stack.imgur.com/pU0u6.png" rel="noreferrer"><img src="https://i.stack.imgur.com/pU0u6.png" alt="enter image description here"></a></p>
  
  <p>it works like charm, which mean the,</p>
  
  <p><strong>testApp</strong> communicates to _webApiHost: <strong>testsomename.company.com/api/</strong> and 
  <strong>prodApp</strong> communicates to _webApiHost: <strong>prodsomename.company.com/api/</strong></p>
  
  <p>In the above case the <strong>artifact which is tested by QA is different from the artifact which is deployed to production</strong>, which is not the ideal way of pushing the code to production.</p>
  
  <p>But my concern is I want to build the app only once and deploy it to multiple environments, where each environment will communicate to appropriate api, like below figure,
  <a href="https://i.stack.imgur.com/DmeiP.png" rel="noreferrer"><img src="https://i.stack.imgur.com/DmeiP.png" alt="enter image description here"></a></p>
  
  <p>When I build it using the command <strong>ng build --configuration=production</strong>, the environment.ts file will have production configurations, </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>export const environment = {
    production: true,
    environment: 'Production',
    _webApiHost: 'prodsomename.company.com/api/',
  };</code></pre>
  </div>
  </div>
  </p>
  
  <p>So if that artifact is deployed to test environment,
  the <strong>testApp</strong> is trying to communicate with <strong>_webApiHost: 'prodsomename.company.com/api/, which is not right.</strong></p>
  
  <p>Here is the Azure DevOps build pipeline powershell script I use to build the solution.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>Set-Location "$(Build.Repository.LocalPath)\Buffini.Web.UI\Angular"
  Write-Host 'Angular Install Starting'
  npm install -g @angular/cli@8.0.6 -Verbose
  Write-Host 'Angular Install Finished'
  Write-Host 'NPM Install Starting'
  npm install -Verbose
  Write-Host 'NPM Install Finished'
  Write-Host 'NPM Update Starting'
  npm update -Verbose
  Write-Host 'NPM Update Finished'
  Write-Host 'NPM Audit Starting'
  npm audit fix -Verbose
  Write-Host 'NPM Audit Finished'
  Write-Host 'Angular Build Starting'
  ng build --configuration=production --deleteOutputPath=true
  Write-Host 'Angular Build Finished'</code></pre>
  </div>
  </div>
  </p>
  
  <p>I have tried searching for a solution online but I couldn’t find any. 
  Please help me in resolving the issue. I’ll highly appreciate your time and help on this. Thanks in advance.</p>