首页 > 解决方案 > 在运行时读取 Angular 中的服务器环境变量

问题描述

我是角度的新手。我已经将一个角度应用程序部署到 aws 中的 docker 容器中。该应用程序需要连接到 aws s3 存储桶。我不需要硬编码 aws 密钥,所以我在 docker 中设置了一个环境变量。Angular 的部署使得来自 ng 构建的 dist 文件夹由 nginx docker 容器提供服务。

一旦将 dist 文件夹中的内容提供给服务器,是否可以通过角度读取服务器环境变量?像 php 和 nodejs 中的 env 函数

标签: angulardocker

解决方案


不幸的是,没有办法在 Angular 中读取类似于 nodejs 或 Spring Boot 等服务器框架提供的机制的环境变量。

但是,您可以在 Angular 应用程序引导之前从服务器加载环境(请在采用此路径之前阅读下面的缺点)。

从服务器加载环境变量:

  • 从根模块(例如 AppModule)中删除引导组件,使其不会自动引导
  • 在 root 中创建一个加载环境变量的单例服务,例如:
import { Injectable } from "@angular/core";

@Injectable({ providedIn: "root" })
export class EnvService {
  public myEnv: string;

  fetchEnv() {
    // This has to retrieved from some server.
    return fetch("some-url").then(env => {this.myEnv = env.myEnv; return Promise.resolve("env loaded");};
  }
}
  • 延迟根模块中的引导,直到加载环境:
@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent, HelloComponent]
})
export class AppModule {
  constructor(private envService: EnvService) {}
  ngDoBootstrap(app) {
    this.envService.fetchEnv().then(() => app.bootstrap(AppComponent));
  }
}

这种方法有几个缺点:

  • 在加载其他环境变量之前,必须知道从哪里检索环境设置的 url
  • 如果无法加载环境变量,Angular 应用程序将无法启动。当您使用 Docker 时,您可以在 Docker 容器内托管一个小型 Web 服务器,该服务器在 Angular 应用程序的专用端点上提供环境变量。然而,这可能会带来自己的问题,因为这会使创建 Angular Docker 容器变得更加复杂。

因此,我建议在构建期间配置环境变量。

有两种方法可以在构建期间设置环境变量:

1) 使用自定义 webpack 配置在构建中设置环境变量

见这篇文章

您可以在 angular.json 中指定自定义 webpack 配置:

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

webpack 配置文件如下所示:

const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        // Here you can set your env variables.
        SERVER_URL: JSON.stringify(process.env.SERVER_URL)
      }
    })
  ]
}

这种方法需要更多的依赖:

@angular-builders/custom-webpack
dotenv

2)构建过程中动态创建环境文件

参见例如自动生成的 src/environments/environment.prod.ts。您可以使用正确的环境值生成此文件,或在构建期间替换此文件中的占位符。

编辑:另见法比奥的回答。您可能不希望您的用户无论如何都知道 S3 存储桶,并且应该尽可能通过 Web 服务器将您的请求路由到存储桶。


推荐阅读