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 ! 🙂
Yes, ça attire ta curiosité ?