在 Angular 2 中加载配置 JSON 文件
Posted
技术标签:
【中文标题】在 Angular 2 中加载配置 JSON 文件【英文标题】:Load Config JSON File In Angular 2 【发布时间】:2017-06-25 22:26:15 【问题描述】:我想在具有 WebAPI 端点的 Angular 2(这是一个普通的 TypeScript 文件)中加载常量文件。 在 Angular1.x 中。我们曾经有相同的常数。 我如何在 Angular 2 中实现相同的功能?
我已经创建了 .ts 文件。我主要关心的是如何在每次加载其他类文件时预先加载文件。
.ts 文件:
export class testAPI
getAPI = "myUrl";
在服务文件中,我通过正常导入使用相同的文件:
constructor(private http: Http)
//console.log(this.test);
console.log(this.testing.getAPI);
//this.test.load();
我将控制台设置为未定义。(一定是因为我的服务类在 API 类之前加载)。
提前致谢。
【问题讨论】:
如果涉及到ts
文件,你可以简单地导入它
【参考方案1】:
您可以使用Opague token 将常量值设置为提供者
尝试: 在你的 const 文件中:
import OpaqueToken from '@angular/core';
export const CONFIG_TOKEN = new OpaqueToken('config');
export const CONFIG =
apiUrl: 'myUrl'
;
在您的 AppModule 设置中使其成为应用程序的单例提供程序:
providers:[
//other providers,
provide: CONFIG_TOKEN, useValue: CONFIG
]
在构造函数中注入,
constructor( @Inject(CONFIG_TOKEN) private config)
【讨论】:
【参考方案2】:我有同样的问题,最后我放弃了 .ts 并把它放在 .js 中:D 像这样:
根目录下的configuration.js
var configuration =
'apiHost': 'http://localhost:8900',
'enableInMemoryWebApi': false,
'authMode': 'standalone',
'wsUrl': 'ws://localhost:8900/ws'
;
module.exports = configuration;
在 .ts 文件中,例如。 user.service.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);
希望对你有帮助
【讨论】:
一些错误?你是怎么放的?你把它放在哪里了? 在应用程序的主文件夹中添加 typing.d.ts 并在那里声明您每次要使用的变量。例如:声明 var System: any;声明 var 要求:任何; 我试过这个并且工作正常。但是移动 build 后 json 更改没有给出正确的结果。请帮助我【参考方案3】:可以在 TypeScript 中导入 JSON。您需要添加类型:
typings.d.ts:
declare module "*.json"
const value: any;
export default value;
然后像这样导入:
import config from "../config/config.json";
config.json:
"api_url": "http://localhost/dev"
【讨论】:
如何在文件中调用它?告诉我无法解析 api_url... angular5 尝试使用import * as configuration from '../config/config.json';
并使用(<any>configuration)['api_url'];
【参考方案4】:
更新
受此特定问题的解决方案的启发,创建了ngx-envconfig 包并将其发布在 NPM 注册表上。它具有与此答案中提供的相同的功能,甚至更多。
您可以将 JSON 文件放在资产文件夹中的某个位置,例如:assets/config
。根据环境是否为开发环境,您可以使用两个.json
文件,一个用于开发,一个用于生产。因此,您可以拥有 development.json
和 production.json
文件,每个文件都将保留适当的 API 端点。
基本上你需要经过以下步骤:
1。设置环境(如果已经有,请跳过此步骤)
在src/environments
文件夹中创建两个文件:
environment.prod.ts
export const environment =
production: true
;
environment.ts
export const environment =
production: false
;
2。创建 JSON 配置文件
assets/config/production.json
"debugging": false,
"API_ENDPOINTS":
"USER": "api/v1/user",
...
assets/config/development.json
"debugging": true,
"API_ENDPOINTS":
"USER": "api/v1/user",
...
3。如下创建服务
注意根据环境,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。与 app.module.ts 集成
import NgModule from '@angular/core';
import ConfigModule, ConfigService from './config/config.service';
@NgModule(
imports: [
...
],
providers: [
...
ConfigService,
ConfigModule.init(),
...
]
)
export class AppModule
现在,您可以在任何想要获取配置.json
文件中定义的必要 API 端点的地方使用 ConfigService。
【讨论】:
感谢 Karlen。这更有帮助。你能告诉我,我如何在组件中访问此配置值 @kamalav 您只需要在您的组件中使用 ConfigService 并调用该服务所需的功能 很好的答案!如果您想升级到 Angular 6 和 rxjs 6 API,请查看此内容:metaltoad.com/blog/angular-6-upgrading-api-calls-rxjs-6 在我的例子中,整个应用程序已经使用 AppConfiguration 类从一些变量中加载值。所有其他服务都在构造函数中注入了 AppConfiguration。因此,我遵循上述模式并尝试使用服务设置 AppConfiguration 中的值。但是,这些值不会加载,因为其他服务会在 AppConfiguration 从文件加载之前尝试注入该值。有什么建议吗? @Ayush 你用过APP_INITIALIZER吗?您应该强制您的应用程序等待配置文件,为此您需要使用如上所述的 APP_INITIALIZER。【参考方案5】:在使用 Angular CLI 生成的 Angular 4+ 项目中,您将拥有开箱即用的 environment
文件夹。在其中,您会从 Karlen 的回答中找到 environment.ts 文件。这是一个有效的配置解决方案,但需要注意:您的环境变量是在构建时捕获的。
这有什么关系? 当您为 Angular 应用程序设置 CI/CD 管道时,通常会有一个构建工具(如 Jenkins)和一个部署工具(如 Octopus)来获取该包(dist 文件夹)和部署到选定的环境,在过程中用正确的值替换您的环境变量。如果您使用 environment.ts 文件,则无法以这种方式替换您的环境变量,因为 environment.ts 文件不会包含在 dist 文件夹中。没有您的部署工具可以选择和编辑的文件。
我们能做什么?我们可以在assets
文件夹中添加一个 JSON 配置文件。这些文件默认包含在我们要部署的 dist 文件夹中。当我们想使用环境变量时,我们只需导入import config from '[relative/path/to/your/config/file.json]'
之类的设置。
当我们这样做时,我们会得到类似以下的错误:
Cannot find module '../../config.json'. Consider using '--resolveJsonModule' to import module with '.json' extension
这是因为 typescript 编译器尝试导入导出的模块但找不到。我们可以通过在 tsconfig.json
文件中添加以下 JSON 属性/值来解决此问题。
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
resolveJsonModule
允许 typescript 编译器导入、提取类型和生成 .json 文件。
allowSyntheticDefaultImports
允许从没有默认导出的模块进行默认导入。
有了这个,我们可以运行我们的项目,我们会发现我们的错误消失了,我们可以毫无问题地使用我们的配置值。
现在,由于此配置文件包含在部署在服务器上的dist
文件夹中,我们可以配置我们的部署工具,将变量值替换为特定于我们要部署到的环境的值。有了这个,我们就可以构建我们的 Angular 应用一次并将其部署到任何地方。
另一个额外的好处是,像 Octopus 这样的大多数部署工具都附带原生 JSON 支持,因此您可以将其配置为非常轻松地替换 JSON 文件中的环境变量。另一种方法是使用正则表达式解决方案来替换.ts
文件中的环境变量,这相对更复杂且容易出错。
【讨论】:
我已经关注了您的 cmets 更改,但在某些情况下它不会起作用,您可以看看这个问题。我遇到的问题被注入身份验证服务会引发错误,并且在工作正常的组件中***.com/questions/62768885/… 注意:以上配置项需要在tsconfig.json的compilerOptions部分,而不是根部分。 我必须包括:“esModuleInterop”:tsconfig.json 上的真实属性才能工作以上是关于在 Angular 2 中加载配置 JSON 文件的主要内容,如果未能解决你的问题,请参考以下文章
ng build 后,字体真棒字体未在 Angular 中加载
在 Angular-fullstack 中加载 local.env.js
在一个活动中加载单个片段两次,从本地json文件中加载2个问题