You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Request: Method to pass environment variables during build vs file. #4318
I really like the environment variables setup with the CLI and we have switched to using them. One problem though is we no longer have access to server set ENV variables which is how we pass information to certain things during deployment. Consider:
Bugsnag.releaseStage=environment.releaseStage;// can't access process.env anymore with the CLIconstcommit=process.env.CI_COMMIT_ID;if(commit)Bugsnag.metaData={commits: {id: commit}};
Being able to add the release stage, branch, and commit ID allows us to segment and track bugs/issues very accurately.
My problem is I know the build takes whatever stage I pass and replaces the environment.ts file so I can't just edit the file with a bash script (well, if I know EXACTLY the build before hand I could) but it would be nice to be able to pass env variables in the build line.
Consider: ng build --prod could be: ng build --prod --envVar:commitId: CI_COMMIT_ID
which would append the variable after the file gets merged
Why not make ENV variables available in process.env again?
I'm really feeling comfortable with Heroku Config Vars and Codeship environment variables, I already set up them, moved all my sensitive data like secret keys to angular-cli environment.dev.ts, BUT I can't use them.(
So then there will be opportunity access them from process.env.CUSTOM_ENV_VAR, etc.
Reacted by Ole Spaarmann, Krzysztof Socha, Chris Murphy, Dennis Smolek, Carles Muiños, Randall Meeker, Sasha Kalmikov, trickpattyFH20, Ludwig Ruderstaller, Stefan Bauer and 84 more
I ran into the same issue a day ago. And for a temporary workaround, that works (just checked it with Codeship), I just added the "prebuild" script, that generates the appropriate environment file using current env variables. ejs is used as a template processor due to it's simplicity.
scripts/prebuild.js - this is a script with the required logic
#!/usr/bin/env node
constfs=require('fs');constpath=require('path');constejs=require('ejs');constenvironmentFilesDirectory=path.join(__dirname,'../src/environments');consttargetEnvironmentTemplateFileName='environment.prod.ts.template';consttargetEnvironmentFileName='environment.prod.ts';// Define default values in case there are no defined ones,// but you should define only non-crucial values here,// because build should fail if you don't provide the correct values// for your production environmentconstdefaultEnvValues={PREFIX_STORAGE_TYPE: 'localStorage',PREFIX_USER_TOKEN_FIELD_NAME: 'userToken',};// Load template fileconstenvironmentTemplate=fs.readFileSync(path.join(environmentFilesDirectory,targetEnvironmentTemplateFileName),{encoding: 'utf-8'});// Generate output dataconstoutput=ejs.render(environmentTemplate,Object.assign({},defaultEnvValues,process.env));// Write environment filefs.writeFileSync(path.join(environmentFilesDirectory,targetEnvironmentFileName),output);process.exit(0);
src/environments/environment.prod.ts.template - this is a template file, that generates the required environment file. Notice, that PREFIX_BACKEND_URL isn't provided in scripts/prebuild.js script in defaultEnvValues, because in production it should be defined only by build environment variables.
package.json - there are some changes here. In scripts/prebuild.jsshebang (#!) style is used, so "prebuild" is just a pointer to the script file. And to make it work it must be marked as executable, that's why "postinstall" script is added either.
Reacted by Joe Costanzo, Carlos Feria, Ashish K Mondal, emreavsar, Mario Alejandro Gil Lázaro, Omar Jimenez, Julio López Torres, Michel Selerin, pavan, Mwaa Joseph and 23 more
Reacted by hongshao007, Johnny Cruz, Tharanga Hewavithana and Drake Stansberry
@k10der this is great, this is similar to what we did. What we do is actually move the environment scripting out of angular totally. We have a single environment.ts file for all builds and use a custom script to generate the correct values via the env variables.
I still think this should be something within the CLI but there are of course workarounds.
Reacted by emreavsar, Code Monkey, Dmitri, George Evstigneev and Martin Neumann
@DennisSmolek, I also think, that handling of process.env variables should be built-in in cli. And your approach to use a single environment file, that is generated by external tool makes sense: my dev environment variables are currently stored in the project repository, which is OK unless I'll start using some 3rd party APIs with private keys. So I guess one-environment-file approach should be used in future angular-cli versions.
Injecting environment variables during build seems essential. Any ETA for supporting this in the ng cli?
Reacted by garysui, Carlos Feria, Aslan Vatsaev, Richard Durazo, Lars Behnke, Serene Yew, Jake Wesorick, Chris Grant, shafiquelislam, Bruno Garcia and 73 more
I'd also really like to be able to use process.env variables. I'm deploying to docker swarms and the capability to be able to include variables in a compose file is important to my application.
Reacted by Maxime Vanmeerbeck, Ralph Navarro, Sander Hammelburg and Floyd Haremsa
Reacted by Juracy Filho, Cristian Boariu, Vlad Chernikov, Isaac, Jacob Spizziri, Jake Wesorick, Chris Grant, shafiquelislam, Haig, Bruno Garcia and 106 more
Reacted by bokyu, Vehans Ayvazi, Ralph Navarro and ThiemoFischer
@k10der Do you have any repository on github that is using the solution you proposed? I'd like to check it because I could not find any real solution on the internet.
Hey, @carlosthe19916. I have a sample project, that I use just for practicing in Angular2+. It's not a production ready and you probably won't get any benefit from running it, but I use the proposed solution there. And it's exactly as I described it in this topic.
Reacted by Carlos Feria, Sam Dornan, Chris Grant and shafiquelislam
Another way to do this is, as mentioned before, requesting the data from a file (maybe created by the HELM that deploy the node) or a property server. For this I created kuoki, with the Environment and the Environment Angular libraries.
There are many options, but I use to run away from variable injection in code because of race condition problems in the properties load or the dependency from objects like Window, that's an open door to attacks.
As a new user of Angular I was really surprised environment variables weren't supported. Every other major front-end framework I've so far used has supported them.
After trying three or four of the recommended approaches here (spent half a day on them all), I personally settled on @chihab's ngx-env builder. It's a safe approach and works with minimal fuss (encouraging separation of secrets from code).
vite supports .env files and import.meta env vars out of the box. Why use it in @angular-devkit/build-angular:application and disable this functionality?
Reacted by Ilya Borisov, J Gingold, Andrii Oriekhov, Sangram-mohanty, Vladislav Shukelait, Tiago Requeijo and Panagiotis Kapros
Another idea is opening esbuild-plugins to allow us create plugins like "define" ourselfs. Here an example using @angular-builders/custom-esbuild. It is much more flexible instead of just only dotenv support.
This is definately a step in the right direction but its still not using environment variables in the bundle so the initial request is not really fulfilled.
We've just added another cli arg to inject but if i have a .env file or exported variables they still wont be picked up.
They still need to be buildtime injected into the cli build command which is almost the same as generating an environment.ts file at build time
Reacted by João Dias, Vishwesh Joshi, Mickaël Olaria, Marvin Heilemann, Benjamin Crosnier, Peter Ashwood, Serhii Atamaniuk, Jack Farley, Marcelo Luz and Lehoczky Zoltán
I think this is a good step forward, but in the end, environment variables and files have been a de facto standard. If with this issue here you don't want to expose the underlying tooling, for example, Webpack in its time, and now Vite, why don't exposing them in your own way? One that doesn't need knowledge about the tooling.
But the important part here is to be able to load a variable from the environment, and this is not loading from the environment.
If you want to use a certain prefix to sanitize variables, that's ok, it's also de facto standard, and most tooling does that to prevent exposing variables not related to the app. And if you want to do it a standard future-proof way, using import.meta seems pretty standard and future-proof.
Again, this is a great start, but I don't feel like this is really fixing the issue here.
Reacted by Ilya Borisov, João Dias, Marvin Heilemann, Mickaël Olaria, Peter Ashwood, Gergely Sárosi, Marcelo Luz, DanielHabenicht, Serhii Atamaniuk, Shaijil and 1 more
I completely agree with @michaeljota. I will not be able to replace my usage of dotenv with the feature that closed this issue. @alan-agius4 Please either reopen or advise us to open a new issue.
Reacted by Jack Farley, Cristiano Aguzzi, Tanishq Manuja and Scott Langley
Activity
Brocco commentedon Feb 1, 2017
@hansl we were just discussing this, thought you might have something to add
yuzhva commentedon Feb 8, 2017
Why not make ENV variables available in process.env again?
I'm really feeling comfortable with Heroku Config Vars and Codeship environment variables, I already set up them, moved all my sensitive data like secret keys to angular-cli environment.dev.ts, BUT I can't use them.(
Because there is no way to access variables from test env or production like:
in my environment.test.ts and environment.prod.ts
Need to thinking on using third party packages like dotenv or env2
P.S: Is it hard to implement configuration like this:
So then there will be opportunity access them from process.env.CUSTOM_ENV_VAR, etc.
k10der commentedon Apr 13, 2017
I ran into the same issue a day ago. And for a temporary workaround, that works (just checked it with Codeship), I just added the "prebuild" script, that generates the appropriate environment file using current env variables. ejs is used as a template processor due to it's simplicity.
scripts/prebuild.js - this is a script with the required logic
src/environments/environment.prod.ts.template - this is a template file, that generates the required environment file. Notice, that
PREFIX_BACKEND_URLisn't provided in scripts/prebuild.js script indefaultEnvValues, because in production it should be defined only by build environment variables.export const environment = { production: true, backendUrl: '<%= PREFIX_BACKEND_URL %>', storageType: '<%= PREFIX_STORAGE_TYPE %>', userTokenFieldName: '<%= PREFIX_USER_TOKEN_FIELD_NAME %>' };package.json - there are some changes here. In scripts/prebuild.js shebang (#!) style is used, so "prebuild" is just a pointer to the script file. And to make it work it must be marked as executable, that's why "postinstall" script is added either.
{ ... "scripts": { ... "build": "ng build --prod --aot", "prebuild": "./scripts/prebuild.js", ... "postinstall": "chmod +x ./scripts/*.js" }, ... "devDependencies": { ... "ejs": "^2.5.6", ... } }DennisSmolek commentedon Apr 14, 2017
@k10der this is great, this is similar to what we did. What we do is actually move the environment scripting out of angular totally. We have a single environment.ts file for all builds and use a custom script to generate the correct values via the env variables.
I still think this should be something within the CLI but there are of course workarounds.
k10der commentedon Apr 14, 2017
@DennisSmolek, I also think, that handling of process.env variables should be built-in in cli. And your approach to use a single environment file, that is generated by external tool makes sense: my dev environment variables are currently stored in the project repository, which is OK unless I'll start using some 3rd party APIs with private keys. So I guess one-environment-file approach should be used in future angular-cli versions.
AmirSasson commentedon Apr 20, 2017
Injecting environment variables during build seems essential. Any ETA for supporting this in the ng cli?
davidwalter0 commentedon May 12, 2017
Why would common cross platform method for OS configuration support of env variables be excluded?
Unless there's a strong argument against 12factor that is being proposed for angular?
zpydee commentedon May 13, 2017
I'd also really like to be able to use process.env variables. I'm deploying to docker swarms and the capability to be able to include variables in a compose file is important to my application.
avatsaev commentedon May 15, 2017
very needed for dockerizing the apps indeed
carlosthe19916 commentedon May 20, 2017
@k10der Do you have any repository on github that is using the solution you proposed? I'd like to check it because I could not find any real solution on the internet.
k10der commentedon May 20, 2017
Hey, @carlosthe19916. I have a sample project, that I use just for practicing in Angular2+. It's not a production ready and you probably won't get any benefit from running it, but I use the proposed solution there. And it's exactly as I described it in this topic.
127 remaining items
RicardoJBarrios commentedon Apr 20, 2023
Another way to do this is, as mentioned before, requesting the data from a file (maybe created by the HELM that deploy the node) or a property server. For this I created kuoki, with the Environment and the Environment Angular libraries.
There are many options, but I use to run away from variable injection in code because of race condition problems in the properties load or the dependency from objects like Window, that's an open door to attacks.
motdotla commentedon Aug 3, 2023
As a new user of Angular I was really surprised environment variables weren't supported. Every other major front-end framework I've so far used has supported them.
After trying three or four of the recommended approaches here (spent half a day on them all), I personally settled on @chihab's
ngx-envbuilder. It's a safe approach and works with minimal fuss (encouraging separation of secrets from code).#4318 (comment)
Here's the result: https://www.dotenv.org/docs/frameworks/angular/vercel
griest024 commentedon May 30, 2024
vite supports
.envfiles andimport.metaenv vars out of the box. Why use it in@angular-devkit/build-angular:applicationand disable this functionality?muuvmuuv commentedon Jul 12, 2024
Another idea is opening esbuild-plugins to allow us create plugins like "define" ourselfs. Here an example using
@angular-builders/custom-esbuild. It is much more flexible instead of just only dotenv support.alan-agius4 commentedon Sep 9, 2024
Closed via #28362, which will be included in version 19, currently in prerelease.
Lindsor commentedon Sep 9, 2024
This is definately a step in the right direction but its still not using environment variables in the bundle so the initial request is not really fulfilled.
We've just added another cli arg to inject but if i have a .env file or exported variables they still wont be picked up.
They still need to be buildtime injected into the cli build command which is almost the same as generating an
environment.tsfile at build timemichaeljota commentedon Sep 15, 2024
I think this is a good step forward, but in the end, environment variables and files have been a de facto standard. If with this issue here you don't want to expose the underlying tooling, for example, Webpack in its time, and now Vite, why don't exposing them in your own way? One that doesn't need knowledge about the tooling.
But the important part here is to be able to load a variable from the environment, and this is not loading from the environment.
If you want to use a certain prefix to sanitize variables, that's ok, it's also de facto standard, and most tooling does that to prevent exposing variables not related to the app. And if you want to do it a standard future-proof way, using import.meta seems pretty standard and future-proof.
Again, this is a great start, but I don't feel like this is really fixing the issue here.
griest024 commentedon Sep 15, 2024
I completely agree with @michaeljota. I will not be able to replace my usage of dotenv with the feature that closed this issue. @alan-agius4 Please either reopen or advise us to open a new issue.
muuvmuuv commentedon Oct 2, 2024
Me neither, and no dev-server support
selangley-wa commentedon Oct 17, 2024
I created a new issue that at least captures my unmet use case:
Ability to set environment/configuration values at runtime instead of buildtime angular/angular#58433
angular/angular#58433
Lindsor commentedon Oct 17, 2024
Reopened this ticket as: #28661
angular-automatic-lock-bot commentedon Nov 30, 2024
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.