2

I've built my Angular 2 project using the Angular 2 CLI and was able to deploy the application to Heroku using this tutorial.

Now, I'd like to create a pipeline for the different environments of the applications (dev, staging, production, etc...).

In my package.json I have "postinstall": "ng build -prod" which creates a production build of my code, which my application runs off of. Is there a way that I could have -prod change based on CONFIG_VARS that I would have in my Heroku setup? For example it would say "postinstall": "ng build -dev" for a dev environment or "postinstall": "ng build -staging" for a staging environment. Or would I need to set up my project differently?

1

3 Answers 3

6

The short answer is: No, you will need to do something different.

Explanation: The npm postinstall script runs when the Heroku slug is built, when you do a git push to the first Heroku app in your pipeline. Subsequently, when you "promote" releases through your Heroku pipeline (e.g. from "development" to "staging" to "production"), the pre-built Heroku slug is promoted "as is", and is NOT rebuilt.

Hence, let's say you have a config var set up in your "development" app that would set the argument that you pass to "ng build" to "dev". That means that when you git push to your "development" app, the slug will get built with the "dev" options. That is fine for the "development" app. HOWEVER, when you subsequently promote to "staging" and "production", you will be promoting the pre-built slug that was built with the "dev" options, which is NOT what you want.

So, to get the functionality you want you will need to consider a different approach.

One way to do it would be to run your "ng build" script in the "npm prestart" phase. That should work, and enable you to use Heroku config vars to modify your Angular2 app depending on the Heroku pipeline phase they are deployed on. However, I typically would NOT recommend this approach. This will cause your "ng build" to run every time "npm start" is run, which is quite often on Heroku (i.e. at least once every 24 hours or so, plus every time your Heroku dynos restart for whatever reason). This would cause your app to experience longer downtime than necessary EVERY time your dynos restart. Not a good idea, typically.

Instead, a better option may be to have your Angular2 app query your server when it initializes, and have the server return whatever pipeline-phase specific values your Angular2 app needs, based on regular Heroku config vars.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your answer. So to make sure I understand correctly, I won't be able to leverage the environments in which the Angular CLI has set up for me as intended?
Not in the way you suggested in your question, no.
Hi @YoniRabinovitch I'm facing the same problem and asked a question about implementing the server query for environment in Angular 4, can you please help
2

If you are running your application in a Heroku node environment you can try to take a look at this solution to avoid having your environments variables and security keys hardcoded in the repositories: https://medium.com/@natchiketa/angular-cli-and-os-environment-variables-4cfa3b849659

I strongly suggest also to take a look at its first response that introduce a dynamic solution to create the environment file at building time: https://medium.com/@h_martos/amazing-job-sara-you-save-me-a-lot-of-time-thank-you-8703b628e3eb

Maybe they are not the best solutions, but a trick to avoid setting up projects differently each time.

4 Comments

These are good ideas, but you still have the problem that postInstall command on Heroku will need to have the environment you are building for hardcoded as part of the command (so that the config script knows which environment file to dynamically generate - so a Catch-22 basically).
I have set the NODE_ENV variables in Heroku that are different for each environment (if needed you can have multiple variables). So when the build is running it grabs the correct environment variable and create the environment.ts file accordingly. In my local environment I have a .env file that has the same variables and this file should not be saved in the repository.
Ok I see that I misunderstood. Basically you dynamically create the environment file at build time from the Heroku env vars. So you are always creating environment.ts (but with different contents based on the env vars on that app) - meaning, you don't create environment.staging.ts and environment.prod.ts etc. Thanks for replying!
Precisely, you got it!
0

i found your question when i was researching the same issue.. how to use environment vars from heroku inside of angular.. after not finding any satisfying answer i came with this (cookie) approach for using different API endpoints for my pipeline.

set a cookie in your server response (server.js) with the content of your var:

app.use(function(req, res, next) {
  res.cookie('API_URL', process.env.API_URL || 'http://127.0.0.1:8500/api/');
  next();
});

read the value inside of your module:

this.apiUrl = cookieService.get('API_URL');

it's a workaround that will of course only work when user accepts cookies...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.