6

I'm using angular-cli's environment variables in a module. When I import my module in another project, is it possible to use my project's environment variables at compilation and runtime ?

My module

myModule/
    src/
        /app
            my.service.ts
        /environments
            environment.prod.ts
            environment.ts
    app.module.ts
    etc.

My module's my.service.ts

import { environment } from './environments/environment';
@Injectable()
export class MyService {
    private title = environment.title;
    showTitle(): string {
        return this.title;
    }
    etc.
}

My module's environment.ts

export const environment = {
  production: false,
  title: 'My Module in dev mode'
}

My module's environment.prod.ts

export const environment = {
  production: true,
  title: 'My Module in prod mode'
}

My project

myProject/
    src/
        /app
            app.component.ts
        /environments
            environment.prod.ts
            environment.ts
    app.module.ts
    etc.

My project's AppComponent

Component({
  selector: 'app-root',
  template: `<h1>{{title}}</h1>`
})
export class AppComponent {
    title: string;
    constructor(myService: MyService) {
        this.title = myService.showTitle();
    }        
}

My project's environment.ts

export const environment = {
  production: false,
  title: 'My Project in dev mode'
}

My project's environment.prod.ts

export const environment = {
  production: true,
  title: 'My Project in prod mode'
}

Currently, when I run my project, I see My Module in dev mode, but I'd want to see My Project in dev mode.

Is there a way to import environment.ts from a relative url like import { environment } from '/src/my-app/environments/environment' ?

1
  • I read it 3 times, no idea what you mean by project environments and module environments Commented Dec 30, 2016 at 13:46

2 Answers 2

5
+25

From what I understand is that you've a project: 'MyProject' and an external module 'MyModule' and you want to import 'MyProject' environment variables in the 'MyModule' service 'MyService'.

IMHO, From a design perspective, It's better if you pass the environment variable as an argument to 'MyService' where you intend to use it.

However, If you insist on importing it, to import both the environment variables, In your my.service.ts Try this:

import { myModuleEnvironment } from './environments/environment';
import { myProjectEnvironment } from  '../../../src/app/environments/environment

Considering your project folder structure to be:

myProject/
 myModule/
   src/
       /app
           my.service.ts
       /environments
           environment.prod.ts
           environment.ts
   app.module.ts
 src/
    /app
        app.component.ts
    /environments
        environment.prod.ts
        environment.ts
app.module.ts
etc.

More Clarification:

TypeScript import rules has same convention as nodeJS. If an import begins with a dot:

import {library} from './some/library/path';

Then it is treated as a relative path from the file that declares the import. If however it is an absolute path (e.g. importing angular2 Component):

import {Component} from '@angular/core';

So, Typescript consider this to be an external module, it goes up the file tree till it finds package.json file. Then go into the node_modules folder, and find a folder with the same name as the import (in the above example: @angular/core). Then looks in the package.json of the module for the main .d.ts or .ts file, and then loads that, or will look for a file that has the same name as the one specified, or an index.d.ts or index.ts file.

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

6 Comments

Thanks for clarification
I try from '../../../src/app/environments/environment'; but it does not work
@Karbos can u make a plunk for it or share with me the folder structure for your project, or perhaps follow the folder structure I suggested.
With your folder structure there are no problems. But my module is a shared module. I don't how to do it in a Plunker...
It will simply be a relative path from your module (likely in the node_modules folder) to the parent's environment file.
|
3

I don't think it is possible because the imported files are scoped to the file that imports it, so you can't access this file and data from outside unless you assign it to a class variable exposed to outside components.

What I suggest is:

Option 1

Import the env file in every file that needs it, there is no problem on doing that. Three shaking will remove duplication.

Option 2

Create a service in the model that import this env file, assign the data to a variable and expose that variable trough the service. So, whe you load the model in another model, you also load the service and can access the exposed env variable.

Something like:

my.service.ts

import { environment } from './environments/environment';
@Injectable()
export class MyService {

    environmentData = environment; // HERE YOU EXPOSE THE DATA THROUGH THIS SERVICE

    private title = environment.title;

    showTitle(): string {
        return this.title;
    }
    etc.
}

Then you can use this service wherever you want the env data.

4 Comments

Can you please give an example of Option 2 ?
Many thanks for your answer but it's not what I need. I want to make some logic in the environment.ts file (it's not a json file) like configure different loggers in dev mode and prod mode on each project, with a common logging interface... I understand I'm not on the good way with this file.
So, you are trying to use the loggerModule inside a different projectModule and want the first to have access to the second environment.ts file?
Yes, in my logger exemple, it is

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.