在 Angular 2 中加载配置 JSON 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42110817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Load Config JSON File In Angular 2
提问by Avinash
I want to load Constant File in Angular 2(which is a Normal TypeScript File) having WebAPI EndPoints. In Angular1.x. we used to have constants for the same. How in Angular 2 I can Implement the Same?
我想在具有 WebAPI 端点的 Angular 2(这是一个普通的 TypeScript 文件)中加载常量文件。在 Angular1.x 中。我们曾经有相同的常量。如何在 Angular 2 中实现相同的功能?
I have created the .ts file.My main concern lies in how to load the file beforehand every Other class File loads.
我已经创建了 .ts 文件。我主要关心的是如何预先加载每个其他类文件加载的文件。
.ts file :
.ts 文件:
export class testAPI {
getAPI = "myUrl";
}
In service file I am using the same by doing Normal Import:
在服务文件中,我通过正常导入使用相同的文件:
constructor(private http: Http) {
//console.log(this.test);
console.log(this.testing.getAPI);
//this.test.load();
}
I am getting the Console as Undefined.(Must be because my Service class is loading before API Class).
我得到的控制台是未定义的。(一定是因为我的服务类在 API 类之前加载)。
Thanks in Advance.
提前致谢。
回答by Karlen
UPDATES
更新
Inspired with the solution for this particular problem created ngx-envconfigpackage and published it on NPM registery. It has the same functionalities as it is provided in this answer and even more.
受这个特定问题的解决方案的启发,创建了ngx-envconfig包并将其发布到 NPM 注册。它具有与此答案中提供的功能相同的功能,甚至更多。
You can have the JSON file somewhere in assets folder like: assets/config. Depending on whether the environment is dev or not you can use two .jsonfiles, one for development and one for production. So you can have development.jsonand production.jsonfiles, where each one will keep the appropriate API endpoints.
您可以将 JSON 文件放在 assets 文件夹中的某处,例如:assets/config. 根据环境是否为 dev,您可以使用两个.json文件,一个用于开发,一个用于生产。因此,您可以拥有development.json和production.json文件,其中每个文件都将保留适当的 API 端点。
Basically you need to go through the following steps:
基本上你需要通过以下步骤:
1. Setting up environment (skip this step if you have it already)
1. 设置环境(如果已经有可以跳过这一步)
Create two files in src/environmentsfolder:
在src/environments文件夹中创建两个文件:
environment.prod.ts
环境.prod.ts
export const environment = {
production: true
};
environment.ts
环境.ts
export const environment = {
production: false
};
2. Create JSON config files
2. 创建 JSON 配置文件
assets/config/production.json
资产/配置/production.json
{
"debugging": false,
"API_ENDPOINTS": {
"USER": "api/v1/user",
...
}
}
assets/config/development.json
资产/配置/development.json
{
"debugging": true,
"API_ENDPOINTS": {
"USER": "api/v1/user",
...
}
}
3. Create a service as follows
3.创建服务如下
Note depending on the environment, the ConfigServicewill load the appropriate file
注意根据环境,ConfigService将加载适当的文件
import { Injectable, APP_INITIALIZER } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs';
import { environment } from 'environments/environment'; //path to your environment files
@Injectable()
export class ConfigService {
private _config: Object
private _env: string;
constructor(private _http: Http) { }
load() {
return new Promise((resolve, reject) => {
this._env = 'development';
if (environment.production)
this._env = 'production';
console.log(this._env)
this._http.get('./assets/config/' + this._env + '.json')
.map(res => res.json())
.subscribe((data) => {
this._config = data;
resolve(true);
},
(error: any) => {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
});
});
}
// Is app in the development mode?
isDevmode() {
return this._env === 'development';
}
// Gets API route based on the provided key
getApi(key: string): string {
return this._config["API_ENDPOINTS"][key];
}
// Gets a value of specified property in the configuration file
get(key: any) {
return this._config[key];
}
}
export function ConfigFactory(config: ConfigService) {
return () => config.load();
}
export function init() {
return {
provide: APP_INITIALIZER,
useFactory: ConfigFactory,
deps: [ConfigService],
multi: true
}
}
const ConfigModule = {
init: init
}
export { ConfigModule };
4. Integrate with app.module.ts
4. 与 app.module.ts 集成
import { NgModule } from '@angular/core';
import { ConfigModule, ConfigService } from './config/config.service';
@NgModule({
imports: [
...
],
providers: [
...
ConfigService,
ConfigModule.init(),
...
]
})
export class AppModule { }
Now you can use ConfigService wherever you want get the necessary API endpoints defined in config .jsonfiles.
现在,您可以在任何需要获取配置.json文件中定义的必要 API 端点的地方使用 ConfigService 。
回答by Alex Po
It is possible to import JSON in TypeScript. You need to add typings:
可以在 TypeScript 中导入 JSON。您需要添加类型:
typings.d.ts:
打字.d.ts:
declare module "*.json" {
const value: any;
export default value;
}
And then import like this:
然后像这样导入:
import config from "../config/config.json";
config.json:
配置文件:
{
"api_url": "http://localhost/dev"
}
回答by Kyler Johnson
In Angular 4+ projects generated with the Angular CLI, you will have the environmentfolder out-of-the-box. Inside of it, you will find the environment.ts files from Karlen's answer. That is a working solution for configuration with one caveat: Your environment variables are captured at build time.
在使用 Angular CLI 生成的 Angular 4+ 项目中,您将拥有environment开箱即用的文件夹。在其中,您会找到来自 Karlen 答案的 environment.ts 文件。这是一个配置的有效解决方案,但有一个警告:您的环境变量是在构建时捕获的。
Why does that matter?When you're setting up a CI/CD pipeline for your Angular app, you will generally have a build tool that builds your project (like Jenkins) and a deployment tool (like Octopus) that will grab that package (the dist folder) and deploy to the selected environment, replacing your environment variables with the correct values in the process. If you use the environment.ts files, your environment variables cannot be replaced this way because the environment.ts files do not get included in the dist folder. There is no file your deployment tool can pick up and edit.
为什么这很重要?当你为你的 Angular 应用程序设置 CI/CD 管道时,你通常会有一个构建你的项目的构建工具(如 Jenkins)和一个部署工具(如 Octopus)将获取该包(dist 文件夹)和部署到选定的环境,在过程中用正确的值替换您的环境变量。如果您使用 environment.ts 文件,则无法以这种方式替换环境变量,因为 environment.ts 文件未包含在 dist 文件夹中。没有您的部署工具可以选择和编辑的文件。
What can we do? we can add a JSON configuration file inside of the assetsfolder. Those files are included by default in the dist folder we will want to deploy. When we want to use an environment variable, we simply import the settings like import config from '[relative/path/to/your/config/file.json]'.
我们可以做什么?我们可以在assets文件夹内添加一个 JSON 配置文件。这些文件默认包含在我们要部署的 dist 文件夹中。当我们想要使用环境变量时,我们只需导入像import config from '[relative/path/to/your/config/file.json]'.
When we do this, we will get something like the following error:
当我们这样做时,我们会得到类似以下错误的信息:
Cannot find module '../../config.json'. Consider using '--resolveJsonModule' to import module with '.json' extension
This is because the typescript compiler tries to import an exported module and cannot find one. We can fix this by adding the following JSON properties/values in our tsconfig.jsonfile.
这是因为打字稿编译器尝试导入导出的模块但找不到。我们可以通过在我们的tsconfig.json文件中添加以下 JSON 属性/值来解决这个问题。
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
resolveJsonModuleallows the typescript compiler to import, extract types from, and generate .json files.
resolveJsonModule允许打字稿编译器导入、提取类型和生成 .json 文件。
allowSyntheticDefaultImportsallows default imports from modules with no default export.
allowSyntheticDefaultImports允许从没有默认导出的模块中默认导入。
With this in place, we can run our project and we will find that our error is gone and we can use our config values without any issues.
有了这个,我们可以运行我们的项目,我们会发现我们的错误消失了,我们可以毫无问题地使用我们的配置值。
Now, because this config file is included in the distfolder that gets deployed on the server, we can configure our deployment tool to replace the variable values with the values specific to the environment to which we want to deploy. With this in place we can build our Angular app once and deploy it anywhere.
现在,因为这个配置文件包含在dist部署在服务器上的文件夹中,我们可以配置我们的部署工具,用特定于我们要部署到的环境的值替换变量值。有了这个,我们可以一次构建我们的 Angular 应用程序并将其部署到任何地方。
Another added benefit is that most deployment tools like Octopus ship with native JSON support so you can configure it to replace environment variables in your JSON file quite easily. The alternative is using a regex solution to replace environment variables in a .tsfile, which is comparatively more complicated and prone to mistakes.
另一个额外的好处是,像 Octopus 这样的大多数部署工具都附带原生 JSON 支持,因此您可以很容易地配置它以替换 JSON 文件中的环境变量。另一种方法是使用正则表达式解决方案来替换.ts文件中的环境变量,这相对更复杂且容易出错。
回答by dev_in_progress
I had same issue and in the end i give up from .ts and put it in .js :D like this:
我遇到了同样的问题,最后我放弃了 .ts 并将其放入 .js :D 中,如下所示:
configuration.js in root
根目录下的 configuration.js
var configuration = {
'apiHost': 'http://localhost:8900',
'enableInMemoryWebApi': false,
'authMode': 'standalone',
'wsUrl': 'ws://localhost:8900/ws'
};
module.exports = configuration;
in .ts file for ex. user.service.ts
例如在 .ts 文件中。用户服务.ts
let configuration = require('../configuration'); //in import section
@Injectable()
export class UserService {
...
getUser(id: number | string): Promise<User> {
console.log(configuration.apiHost) //will get propertye from .js file
return this.http.get(`${configuration.apiHost}/${id}`, this.headers).toPromise().then(this.extractData).catch(this.handleError);
}
}
Hope it helps
希望能帮助到你
回答by Suraj Rao
You can use Opague tokento set constant values as providers
您可以使用Opague 令牌将常量值设置为提供者
Try: In your const file:
尝试:在您的 const 文件中:
import { OpaqueToken } from '@angular/core';
export const CONFIG_TOKEN = new OpaqueToken('config');
export const CONFIG = {
apiUrl: 'myUrl'
};
In your AppModule set to make it a singleton provider for the app:
在您的 AppModule 设置中使其成为应用程序的单例提供程序:
providers:[
//other providers,
{provide: CONFIG_TOKEN, useValue: CONFIG}
]
For injecting in constructor,
对于注入构造函数,
constructor( @Inject(CONFIG_TOKEN) private config)

