Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

environment.dev|prod|etc.ts files don't appear to be copied into environment.ts #2075

Closed
rjcoupe opened this issue Sep 12, 2016 · 29 comments
Closed
Labels
P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent type: bug/fix

Comments

@rjcoupe
Copy link

rjcoupe commented Sep 12, 2016

Please provide us with the following information:

  1. OS? Windows 7, 8 or 10. Linux (which distribution). Mac OSX (Yosemite? El Capitan?)
    Ubuntu 16.04
  2. Versions. Please run ng --version. If there's nothing outputted, please run
    in a Terminal: node --version and paste the result here:
» ng version                                                                                                                      
Could not start watchman; falling back to NodeWatcher for file system events.
Visit http://ember-cli.com/user-guide/#watchman for more info.
angular-cli: 1.0.0-beta.11-webpack.8
node: 6.3.0
os: linux x64
  1. Repro steps. Was this an app that wasn't created using the CLI? What change did you
    do on your code? etc.
    1. Add some custom fields/data in environment.dev.ts (or environment.prod.ts)
    2. Import src/environments/environment into a component and attempt to use a newly added variable.
    3. ng serve/build with the appropriate env set.
    4. Variable will not have been read, as environment.ts will still be { production: bool }
  2. The log given by the failure. Normally this include a stack trace and some
    more information.
    N/A
  3. Mention any other details that might be useful.
    Specifically importing environment.dev or environment.prod (as appropriate) works fine, but obviously isn't practical.

Thanks! We'll be in touch soon.

@JiriBalcar
Copy link

See #2073. It is changed to be only two files by default environment.ts (dev env) and environment.prod.ts (prod env)
You should add your variables to this two files.
I think this issue can be closed with this pull request.

@radoslavpetranov
Copy link

radoslavpetranov commented Sep 15, 2016

I'm a little confused. If environment.dev.ts or environment.prod.ts aren't copied into environment.ts on rebuild, how are we then supposed to import the correct environment file into our code?

@filipesilva
Copy link
Contributor

Bear in mind that the content will be copied at runtime, in memory for ng serve and to the output bundles in ng build. Your src/environments/environment.ts file will never be altered, only the generated code.

I just tried this on a brand new beta.14 app with ng serve --prod, and as far as I can tell it works properly:

image

@radoslavpetranov
Copy link

radoslavpetranov commented Sep 15, 2016

The problem with not actually overwriting the files is that trying to use environment.test throws a compilation error because environment.ts which we import doesn't actually have a test variable in it.

2016-09-16_01h47_07

@filipesilva
Copy link
Contributor

I think I know what's happening. It's the typechecker, it's not using the file replacement. I'll see if it can be fixed.

Try this for now: use the same interface in both files aka have the test object member in both. That should satisfy the typechecker and at runtime you will get the different content:

Example:

// environment.ts
export const environment = {
  production: true,
  test: 'hello'
};
// environment.prod.ts
export const environment = {
  production: true,
  test: 'goodbye'
};
  • ng serve will print hello in console.log(environment.test)
  • ng serve --prod will print goodbye in console.log(environment.test)

@filipesilva filipesilva reopened this Sep 16, 2016
@filipesilva filipesilva added type: bug/fix command: build P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent labels Sep 16, 2016
@radoslavpetranov
Copy link

Thanks for looking into it!

@ukaaa
Copy link

ukaaa commented Sep 26, 2016

When can we expect a fix for this please?

@JiriBalcar
Copy link

@ukaaa @radoslavpetranov What is the use case to have different variables in environment? How do you handle that in code?

@ukaaa
Copy link

ukaaa commented Sep 26, 2016

@JiriBalcar to only show information and links when we're running our app in a development environment.

@JiriBalcar
Copy link

@ukaaa And for that usecase you can use the production flag which is in both of the files. So you do not need different interface in evironment. Right?

@ukaaa
Copy link

ukaaa commented Sep 26, 2016

@JiriBalcar oh yes, definitely. Only that doesn't seem to work either for me using [email protected] (both global and local.)

I have the following environments under src/environments:

environment.dev.ts

export const environment = {
  production: false
};

environment.prod.ts

export const environment = {
  production: true
};

environment.ts

// The file contents for the current environment will overwrite these during build.
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
// The list of which env maps to which file can be found in `angular-cli.json`.

export const environment = {
  production: false
};

angular-cli.json

"environments": {
    "source": "environments/environment.ts",
    "dev": "environments/environment.dev.ts",
    "prod": "environments/environment.prod.ts"
}

And finally in one of my components let's say I have this:

import { environment } from '../../environments/environment';

But when I serve using ng serve --environment=prod or ng serve --prod and then log what's in the environment variable I get:

{
  production: false
}

Same happens with ng build.

@radoslavpetranov
Copy link

@JiriBalcar my use case is slightly different. I think it makes sense to put all possible config variables in a single file (let's say environment.dev.ts) and then have environment.prod.ts basically import environment.dev.ts and extend it (Object.assign) with only those values we need to set different from defaults. This way all supported config values and their defaults are in one place and in the other file we only change the ones we care about without worrying about adding new config values to both files.

For that reason I tried importing environment.dev.ts into environment.prod.ts where I would just extend the defaults in and return the extended environment.dev.ts object. I expected that the end result would end up in environment.ts but then this thread made me realize this is not how it works. All in all at first I thought this is a bug but then I realized that's by design hence my participation in this thread.

@JiriBalcar
Copy link

@ukaaa Strange, for me this exact scenario works great. Did you tried that in new project? ng new

@radoslavpetranov I beleive it should work if you put your dev config to environment.ts instead of environment.dev.ts as this pull request (#2073). Then you always have full development variables and in prod mode the extend the dev. Did you tried that?

@ukaaa
Copy link

ukaaa commented Sep 27, 2016

@JiriBalcar With a new project it seems to work … Very strange. Not sure what I should do now.

@ukaaa
Copy link

ukaaa commented Sep 27, 2016

I've just upgraded my existing project to [email protected] but it still doesn't work.

@JiriBalcar
Copy link

@ukaaa Can I look at your repository?

@ukaaa
Copy link

ukaaa commented Sep 29, 2016

@JiriBalcar I did a clean install of the project and now everything works. Probably some files remained somewhere they didn't need to be. I remember the environments folder moving around a few versions back, I guess it was related to that.

@Kosmonaft
Copy link

I'm having the same problem. On new project is working but on old one is not. Any suggestions?

@ukaaa
Copy link

ukaaa commented Oct 13, 2016

@Kosmonaft the environments folder is now on a different location than in earlier versions. Maybe you can compare both projects and their folder structure.

@egavrilov
Copy link

egavrilov commented Oct 20, 2016

I have the similar issue, but simple to solve just looking how it works in new created by angular-cli project.
Without creating new project, you can fix it in existing one this way:

  • Move ./src/app/environments folder as ./src/environments
  • Move ./src/environments/environment.dev.ts as ./src/environments/environment.ts with replacement (don't forget to merge your configs before)
  • In ./angular-cli.json file edit environments section as it is in new project:
    "environments": {
        "source": "environments/environment.ts",
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }

Worked for me.

@aaronleestic
Copy link

My environment.dev|etc.ts files don't appear to be copied into environment.ts when using AoT AND using components that are AoT compiled/imported from another library...

I had an auth service class that is injected into a lot of various components throughout my app. It's a singleton defined once in the Core Module (per ng docs example). Previously, the class had an import { environment } from "../path/to/environment.ts" in it, which then allowed it different env's API, etc.

Now, I've just refactored this class to another beta.22 / ng 2.4.1 repository, which serves as a common components library for the x other angular app I'll be writing. It is compiled using ngc so my first (and future) app can import it.

Since the service class can no longer depend on a locally imported environment.ts file to inform it of API endpoints, I am instead injecting a config object into the class. (per ng doc's tutorial on DI, OpaqueToken...). This config object is defined in the Core Module instead. And in my Core Module code, I no longer importing auth service locally. This is essentially how it looks:

import { AuthService, AUTH_CONFIG } from "my-common-lib/dist";
import { environment } from "../local/path/to/environment.ts";
@NgModule({
providers: [ 
   { provide: AUTH_CONFIG, useValue: { api:  environment.authApi },
   AuthService
],
})

Works fine so far. Now, I've also refactored out all my auth-related pages, like login, sign-up, reset password pages. These are all packed together into an NgModule and lazy loaded. I successfully refactored it out into the common repo as well:

Routes:

 path: '/my-auth-pages-route',
 loadChildren: "app/auth/module#AuthModule" ...

app/auth/module.ts:

import { AuthPagesModule } from "my-common-lib"
@NgModule({
  imports: [AuthPagesModule],
})
export class AuthModule { }

(in the above file, simply doing an export { AuthModule } from 'my-common-lib' works in normal but do not compile in AoT. I may open another issue for that)

If I serve the app it in normal mode and using the imported pages, the env is set.
If I serve the app in AoT, but use pages defined locally, the env is set.

It is only when I do the import AND use AoT that the env is not set. More specifically, a console.log right before the useValue show that the imported env is correct. But, milliseconds later in the console, in the root component constructor, logging the authService's config shows that the env values are the dummy one.

@pfleeter
Copy link

@aaronleeucla I might be seeing the same thing. I have a string provider like this:

{provide: 'ApiUrl', useValue: environment.apiurl}

And in my constructor, I print out that the value in the environment is different than the one in the injected provider.

constructor(@Inject('ApiUrl') private csConsoleUrl:string) {
    console.log("Handed ApiUrl provider of " + csConsoleUrl + " vs " + environment.apiurl);
}

This is only during build (which I am doing with AOT). I guess the environment value is being set during compilation prior to the environment being worked out?

@deebloo
Copy link
Contributor

deebloo commented Jan 16, 2017

@aaronleeucla @pfleeter the issued tied to providing the environment to the DI is logged here. #2673. The workaround for now is to provide a factory instead of providing a value

@pfleeter
Copy link

@deebloo @aaronleeucla Thanks. I wasn't aware of useFactory. Worked perfectly.

@RonitMaity
Copy link

hi,
how to configure environment variables in angular2 without CLI

@Toxicable
Copy link

Can be closed? I believe this was fixed awhile ago

@etwillbefine
Copy link

for me it also happens in 1.0.0-rc.0 but it was fixed for me by adding the missing typings

environment.d.ts
interface Environment {
    production: boolean;
    someValue?: {
        nestedProp: string;
    };
}
environment.ts
export const environment: Environment = {
    production: false,
    someValue: {
      nestedProp: 'my value'
    }
}
environment.prod.ts
export const environment: Environment = {
    production: true
}

but: is that really desired / the correct solution?

@filipesilva
Copy link
Contributor

Closing as fixed.

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent type: bug/fix
Projects
None yet
Development

No branches or pull requests