Utilisation de variables d’environnement | Angular 15

C’est une très ancienne demande … https://github.com/angular/angular-cli/issues/4318

Pouvoir utiliser les variables d’environnement au lieu de la compilation par configuration.

Ajout du custom webpack

On lance 

npm i -D @angular-builders/custom-webpack

Modification du fichier angular.json

"architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./config/custom-webpack.config.js"
            },

Nous passons du builder d’angular à un custom builder.

Puis nous ajoutons notre webpack config

Il faut le faire deux fois

Un pour le build, et un pour le serve

Attention, pour la partie serve, nous devons adapter notre code json pour ne pas dupliquer notre config et surtout partir sur un partie dev-server 👍

"serve": {
          "builder": "@angular-builders/custom-webpack:dev-server",
          "configurations": {
            "production": {
              "browserTarget": "angular-with-var-env:build:production"
            },
            "development": {
              "browserTarget": "angular-with-var-env:build:development"
            }
          },

Et ça y est, c’est bien pris en compte en serve

et en build 

Installer dotenv

npm i -D dotenv

On met Ă  jour notre extension de webpack.config

const { EnvironmentPlugin } = require('webpack');
require('dotenv').config();


module.exports = {
  plugins: [
    new EnvironmentPlugin([
// Nos variables ici
    ])
  ]
};

L’idée c’est d’insérer la liste des variables d’environnement, en tant que mot clef.

Ca donne par exemple :

const { EnvironmentPlugin } = require('webpack');

require('dotenv').config();

module.exports = {

  plugins: [

    new EnvironmentPlugin([

      'MON_API_STARWARS'

    ])

  ]

};

Où MON_API_STARWARS est la clef de variable d’environnement.

Appel dans un service

ng g s features/peoples/people-datalayer

@Injectable({
  providedIn: 'root'
})
export class PeopleDatalayerService {
  private readonly api = process.env['MON_API_STARWARS'];
  private http = inject(HttpClient);


  getAll(): Observable<PeopleApiResult> {
    return this.http.get<PeopleApiResult>(`${this.api}/api/people`);
  }
}

Notons ici l’appel de process.env (qui vient de nodejs).

Nous utilisons ici les models suivants

export type PersonResult = {
  name: string
}


export type PeopleApiResult = {
  results: PersonResult[]
}

(Nous avons bien entendu pensé à importer le HttpClientModule)

Appel depuis notre component

export class AppComponent {
  title = 'angular-with-var-env';
  people$: Observable<PeopleApiResult>


  constructor(private readonly service: PeopleDatalayerService) {
    this.people$ = this.service.getAll();
  }
}

Puis affichage sur notre template

<div *ngIf="people$ | async as result">
  <ul>
    <li *ngFor="let item of result.results">
      {{ item.name }}
    </li>
  </ul>
</div>

Ajout du node Ă  installer

Le process.env n’est pas reconnu, il faut l’ajouter.

Installation par npm i -D @types/node

Et après ajout dans les types à builder par typescript (dans le fichier tsconfig.app.json) :

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": [
      "node"
    ]
  },
…
}

Penser Ă  faire un trim

getAll(): Observable<PeopleApiResult> {
    return this.http.get<PeopleApiResult>(`${this.api?.trim()}/api/people`);
  }

Config variable et lancement

Nous pouvons alors setter la variable d’environnement MON_API_STARWARS et lancer l’application

SET 

MON_API_STARWARS=https://swapi.dev/&& npm start

Et voila notre variable est dĂ©finie Ă  l’extĂ©rieur d’angular ! 🙂

Un gist pour aider

Yes, ça attire ta curiosité ?

Tu souhaites aller plus loin en Angular ?

Notre adresse

1 rue du guesclin
44000 Nantes

Notre téléphone

+33 2 79 65 52 87

Société

DevToBeCurious SARL
84860163900018 - Nantes B 848 601 639