如何在Angular 2应用程序中配置不同的开发环境

48

我有一个常量文件

export class constants {
    public static get API_ENDPOINT(): string { return 'https://dvelopment-server/'; }
}

然后我将它导入到我的服务中

private _registrationUrl = constants.API_ENDPOINT+'api/v1/register';

我该如何在服务器更改时更改端点。我有开发服务器、暂存服务器和本地服务器。我希望应用程序能够检测到环境的变化。

在我的 Angular 1 应用程序中,我使用了 EnvServiceProvider 来实现这一点。我可以在 Angular 2 应用程序中使用相同的方法吗?


我认为您也可以在Angular2中实现这个。不确定是否有与该库在Angular2中相等的内容,但我相信您可以轻松地自己复制它。您需要检查您的应用程序所运行的域名(localhost、devserver.com等),并根据此设置来自服务配置对象的变量。 - eesdil
如何检查 Angular 2 应用程序运行的域名? - QCG
您可以使用位置(Location)对象,即使在WebWorker中也可以工作,只需在前面加上self。https://developer.mozilla.org/zh-CN/docs/Web/API/Locationhttps://developer.mozilla.org/zh-CN/docs/Web/API/WorkerLocation - eesdil
如果您想构建一次并多次部署相同的构建工件,请参阅https://dev59.com/DFgQ5IYBdhLWcg3wJgmO#43980985。 - Mehrad Sadegh
我建议看一下https://dev59.com/qFkS5IYBdhLWcg3wFi-k#40431356。基本思路是使用一个脚本(例如在docker容器中),根据您的环境修改创建的压缩js。 - schneida
正如最后两条评论所述,我建议看看不涉及构建配置的选项。你最好只需要构建一次,然后在不同的环境中使用该构建。否则,QA/测试阶段可能会被半废除,因为构建可能会引入问题。 - redfox05
6个回答

71
简短回答:使用Angular CLI。它虽然还在测试阶段,但非常好用,Angular团队推荐用于新项目的开发。使用此工具可以配置不同的环境。在构建时,src/client/app/environment.ts将被替换为当前CLI环境下的config/environment.dev.tsconfig/environment.prod.ts
环境默认为dev,但您可以通过-prod标志生成生产构建,例如ng build -prodng serve -prod。由于这是一个新功能,可能会有些混乱,请查看this great guide以获取有关如何使用CLI设置Angular环境的其他信息。
希望这可以帮助到您。

7
请注意,指南中的 import 命令似乎不再有效(可能是路径已更改)。以下是我用过的正确版本:import { environment } from '../../environments/environment'; - zavié
1
@zavié 可能更好的做法是 import { environment } from "app/../environments/environment;",因为它适用于任何文件位置。 - Cartucho
好奇心…如果你继承了一个手动构建而不是通过Angular CLI构建的Angular 2应用程序,那么该怎么办?“长答案”是什么? - markreyes
@markreyes 我猜在这种情况下,你至少有两个选择。第一种选择:从头开始创建一个CLI项目并迁移你的应用程序。第二种选择:在你继承的应用程序基础设施、构建工具、npm项目或任何你拥有的东西中添加处理环境的功能。对于“长答案”,可以查看其他回复以获取想法,或创建一个新的CLI项目并查看代码(这就是开源项目的魔力)。 - Cartucho
刚刚将一个SystemJS应用迁移到AngularCLI,我可以告诉你这并不难。我在不到一小时的时间内运行了CLI版本,并且在不到一天的时间内使所有东西都正常工作,这只是为了测试一切并修复一些问题(RecordRTC和CKEditor给了我一些小问题,还有我的样式必须稍微重新调整)。 - Joo Beck
显示剩余3条评论

32

我想补充一下@Cartucho提供的答案。他对设置angular 2应用程序的个性化环境所需的步骤是正确的。

我还想赞同文章Guide to Build the app in different environments的观点。

但是,该文章缺少一个重要的步骤。设置个性化环境的步骤如下:

  1. 在项目的environments文件夹中创建一个名为environment.YourEnvName.ts的新文件。
  2. 将环境描述添加到angular-cli.json文件中的“environments”对象中。
"environments": {
    "source": "environments/environment.ts",
    "prod": "environments/environment.prod.ts",
    "dev": "environments/environment.dev.ts", 
    "qa": "environments/environment.qa.ts",
    "YourEnvName": "environments/environment.YourEnvName.ts"
  }

3)一旦您进行了这些更改,您可以使用以下命令为新环境构建应用程序。

ng build --environment=YourEnvName or 

ng serve --environment=YourEnvName 

希望这篇文章对任何新的Angular 2开发者有所帮助。


0

我通过添加一个类方法解决了这个问题

export class config {

    public static getEnvironmentVariable(value) {
        var environment:string;
        var data = {};
        environment = window.location.hostname;
        switch (environment) {
            case'localhost':
                data = {
                    endPoint: 'https://dev.xxxxx.com/'
                };
                break;
             case 'uat.server.com':
                data = {
                    endPoint: 'https://uat.xxxxx.com/'
                };
                break;

            default:
                data = {
                    endPoint: 'https://dev.xxxx.com/'
                };
        }
        return data[value];
    }
}

在我的服务中

private _loginUrl = config.getEnvironmentVariable('endPoint')+'api/v1/login;

27
我不喜欢这种解决方案的原因是它会公开你开发环境的内部细节。我在考虑使用Grunt,在拼接前复制一个特定目标文件到指定位置,然后定义config类。但是,我感觉一定有更好的方法。 - Dave
10
那只是一个不好的解决方案。这不应该成为被接受的答案。 - eav
3
为什么要使用另一个类,而不是使用环境变量?@zavié提供了一个好的解决方案。 - Dave
2
如果您正在采用“一次构建,到处部署”的方法,那么除了类似于这种方法之外,您就没有其他解决方案了。 - user372225
加上+1作为一个已选择的解决方案。请请求所有人根据所提出的问题进行回答。 - Vaibs

0

@cartucho的答案非常好,但是当您尝试使用Heroku或Github actions等服务部署到多个环境时,就会出现问题。这些服务使得使用node环境变量变得容易,但是没有一种方法来配置特定于环境的构建命令。

解决此问题的一种方法是像@cartucho建议的那样设置您的Angular环境变量,然后将构建脚本设置为调用一个小型的node应用程序。该node应用程序读取一个node环境变量,然后决定运行哪个构建命令。

在package.json中:"build": "node build-app.js",

build-app.js:

const { exec } = require('child_process');

let buildScript = 'ng build --configuration=staging';
if (process.env.ANGULAR_ENVIRONMENT_CONFIGURATION === 'production') {
    buildScript = 'ng build --configuration=production';
}
const child = exec(buildScript, function (err, stdout, stderr) {
    if (err) throw err;
    else console.info(stdout);
});

child.stdout.on('data', function (data) {
    process.stdout.write(data);
});

child.stderr.on('data', function (data) {
    process.stdout.write(data);
});

child.on('exit', function (data) {
    process.stdout.write("I'm done!");
});

我在我的博客文章中详细介绍了Angular Universal所需的其他步骤:https://dev.to/jfbloom22/a-better-way-to-deploy-angular-universal-to-multiple-environments-206j


0
export class endPointconfig {

    public static getEnvironmentVariable() {
        let origin = location.origin;
        let path = location.href.split('/')[3];
        let value = origin +'/'+ path + '/api/';`enter code here`       
        return value;
    }
}

只需调用 endPointConfig 类以返回 URL,我们随时为您提供服务。 - Mahesh Kumar Alanka

0

希望能对您有所帮助。

首先,创建 development.ts、staging.ts 和 production.ts 配置文件。 其次,在 index.pug 中以以下方式导入环境文件:

   SystemJS.import("#{settings.env}").then(function(env) {
       System.import("app").catch(console.error.bind(console));
   } // Promise.all also works!

请记住,在nodeJS/Pug/Jade中,settings.env包含NODE_ENV值。
最后,您的system.config.ts映射应该有以下几行:
    "development": "myUrl/configs/development.js",
    "staging": "myUrl/configs/staging.js",
    "production": "myUrl/configs/production.js",

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接