将 Angular 2 环境配置具体化的最现代方法? [英] Most modern way to externalize Angular 2 environment configuration?

查看:26
本文介绍了将 Angular 2 环境配置具体化的最现代方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇截至 2017 年 4 月,使用外部配置构建用于部署的 Angular 2 应用程序的最现代方式是什么?

I'm curious what the most modern way, as of April 2017, to build an Angular 2 app for deployment with external configuration?

遵循一次构建,随处部署的理念,我想弄清楚如何将我的 Angular 2 应用程序打包为一个 Docker 镜像,我可以将其放到任何服务器上并从外部进行配置.

Following the Build Once Deploy Anywhere philosophy I'd like to figure out how to package my Angular 2 app as a Docker image that I can drop onto any server and configure from outside.

我已经用这个应用程序的大多数其他组件(包括 Spring Boot 后端)完成了这个相当简单的工作,但是用 Angular 2 做到这一点的最佳方法很难确定,因为该框架在 beta 版本之间发生了巨大的变化,以至于很多的信息已过时.

I've done this fairly simple with most other components of this application including a Spring Boot backend, but the best way to do this with Angular 2 is hard to pin down since the framework evolved so massively between beta releases that a lot of information is out-of-date.

我有 Angular 2.4.9 和 NPM,用于在 Node Docker 容器中运行的包管理,作为 JIT 应用程序,在构建时将特定的 environment.ts 嵌入到映像中.我想获得 AoT 编译的大小和速度优势以及最终的缩小和其他下载大小增强功能,但 AoT 将 environment.ts 文件的内容直接烘焙到 main.bundle.js 中,因此根本没有办法在 ng build

I've got Angular 2.4.9 with NPM for package management running in a Node Docker container as a JIT app with specific environment.ts baked into the image at build-time. I'd like to get the size and speed advantages of AoT compilation as well as eventual minification and other download size enhancements, but AoT bakes the contents of an environment.ts file directly into main.bundle.js so there's no way at all to change it after ng build

Angular2-webpack-starter 项目似乎非常过时,无论如何与 Angular-CLI 是互斥的,但它有 这里的这个方法 似乎设置了 config/webpack.ENV.js 文件,这些文件引用了操作系统环境变量.我觉得环境变量对于很多应用程序来说有点过于复杂,但总比没有好.但是我如何在 Angular-CLI 术语中应用它,或者有更好的方法吗?

The Angular2-webpack-starter project seems very out-of-date and is mutually exclusive with Angular-CLI anyway, but it's got this method here which seems to setup config/webpack.ENV.js files that refer to OS environment variables. I feel like environment variables are a bit overly complicated for a lot of apps, but it's better than nothing. But how can I apply this in Angular-CLI terms, or is there a better way?

据我所知,Angular-CLI 过多地抽象了 webpack,无法直接访问 webpack 和插件配置来遵循这种方法.但是我可以在我的 environment.ts 中引用 process.env 而 Bob 是你的叔叔,还是比这更复杂?

As I understand it Angular-CLI abstracts webpack too heavily to directly access the webpack and plugin configs to follow this approach. But could I just reference process.env in my environment.ts and Bob's your uncle or is it more complicated than that?

我是否需要打开 main.bundle.js 并重写 var environment = {//# sourceMappingURL=environment.js.map 之间的位?对于像 Angular 这样流行的东西来说,这似乎是不必要的.

Do I need to crack open main.bundle.js and rewrite the bits between var environment = { and //# sourceMappingURL=environment.js.map? That seems needlessly hacky for something as popular as Angular.

推荐答案

如果您确实必须构建一次并多次部署同一个构建工件,那么一个解决方案(尽管在我看来有点小技巧)是将您的'assets' 文件夹中的外部配置,然后从 environment.ts 进行 ajax 调用以读取值:

If you really must build once and deploy the same build artifact multiple times then one solution (although in my opinion is a bit of a hack) is to put your external configuration inside 'assets' folder then make an ajax call from environment.ts to read the values:

src/environments/environment.ts:

export const environment = new Promise((resolve, reject) => {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', './assets/environment.json');
  xhr.onload = function () {
    if (xhr.status === 200) {
      resolve(JSON.parse(xhr.responseText));
    }
    else {
      reject("Cannot load configuration...");
    }
  };
  xhr.send();
});

src/assets/environment.json:

{
  "production": false,
  "some_api_url": "https://dev_url"
}

您还需要将模块引导推迟到 ajax 调用完成时:

You also need to postpone module bootstrapping to when ajax call is completed:

src/main.ts:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment as environmentPromise } from './environments/environment';

environmentPromise.then(environment => {

  if (environment["production"]) {
    enableProdMode();
  }

  platformBrowserDynamic().bootstrapModule(AppModule);
});

此处的工作示例: https://github.com/mehradoo/angular-external-cfg/commit/0dd6122a0d8ff100c23458807cc379e9e24cc439

这篇关于将 Angular 2 环境配置具体化的最现代方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆