Angular 4 で Connection String や Secret を Environment Variables から取得する
The twelve-factor app にある通り、環境依存の情報は、環境変数から設定するようにしたい。しかし、SPA の Angular とかだったらどうするんだろう?きっとこれは基礎的なことなのだけど、意外と自分には難しかったので、今まで学んだことを自分のために、ブログにしておきたい。
Environment Variables を Angular (4) から使う
ベストプラクティス的なものがないのかなぁ。と色々調べて見たけど、Facebook でなきを入れていたらヒントをもらえた。
- Request: Method to pass environment variables during build vs file. #4318
- How to pass environment variables?
環境変数を取り込む仕組みのあれこれ。
ちなみに、Angular では、環境変数は取り込めない。よくよく考えると、SPA は、ブラウザにダウンロードされて使うのだから、そらそうだ。
上記の記事を読んでいると、どうやら、Angular には、environment
という仕組みがあるらしい。そのenvironmentを環境によって変えられる様子。
src/environments/
├── environment.prod.ts
└── environment.ts
ここを、プロジェクトをビルドする時に切り替える。例えばこんな感じ。
_environment.prod.ts
export const environment = {
production: true,
hostUrl: "http://some.prod"
};
_environment.ts
export const environment = {
production: false,
hostUrl: "http://some.dev"
}
app.component.html に 下記のコードを入れておく。
<h2> ServerName: {{hostUrl}}</h2>
$ ng serve
だと、デフォルトが起動する。
$ ng serve --environment prod
これでプロダクションが起動した。
環境変数を埋め込む
少なくとも Angular CLIを使っている時はこの方式で行けそう。いきなり本物のプロジェクトに盛り込むより、プロジェクトを生成してみよう。
$ ng new host-inject
この状態から、環境変数を取り込んで見たい。環境変数は Angular では直接取り込めない。色々読んでいると、ビルド時に、プリコンパイルして盛り込むというのが良さげ。
NOTE: 最初、process.env を直接実行しようとしたけど、これは見つかららないと言われる。ちなみにこれは、tsconfig.app.json
の下記の部分を追加すると、解消された。
"CompilerOptions": {
typs["node"],
:
}
scripts/prebuild.ts というファイルを作ってみる。 テンプレート environment.ts.template を元に、環境変数を取り込んで作成をするシンプルなもの。
import * as fs from 'fs';
import * as path from 'path';
import * as ejs from 'ejs';
const environmentFilesDirectory = path.join(__dirname, '../src/environments');
const targetEnvironmentTemplateFileName = 'environment.ts.template';
const targetEnvironemntFileName = 'environment.ts';
const defaultEnvValues = {
SOME_HOST: "http://default.com"
}
const environmentTemplate = fs.readFileSync(
path.join(environmentFilesDirectory, targetEnvironmentTemplateFileName),
{encoding: 'utf-8'}
);
let obj:any = (<any>Object).assign({}, defaultEnvValues, process.env);
const output = ejs.render(environmentTemplate, obj);
fs.writeFileSync(path.join(environmentFilesDirectory, targetEnvironemntFileName), output);
process.exit(0);
ちなみに、(<any>Object).assign
の部分は当初、Object に assign が見つからないと怒られた。<any>
をつけて解決。
enviornment.ts.template
export const environment = {
production: false,
hostUrl: "<%= SOME_HOST %>"
};
これを実行するために、package.json に、
"prebuild": "tsc scripts/prebuild.ts && node scripts/prebuild.js",
を追加した。
プリビルドする。
$ npm run prebuild
しっかり、ファイルがジェネレートされた。
$ env
SOME_HOST=http://some.com
environment.ts
export const environment = {
production: false,
hostUrl: "http://some.com"
};
バッチリできている。先ほど紹介してもらった記事を見ても、ジェネレートする方法が一番スッキリきた。
本当にこの方式で問題ないのか?
問題は、この方式だと、結局のところ、ブラウザから URL が見れちゃったりするんじゃないの?と思ったが、意外に見えないようだ。もちろん、enviornments の下をうっかり公開する設定にしてないことが大切だとは思うが。よく、SPA を Blob Storage に置くとかの例があるが、ああいうのはどうしているんだろう。Azure Functions Proxy などで制限する感じだろうか。次はその辺をやってみたい。
ちなみに、全てのソースコードはこちらに置いています。
Resource
Author And Source
この問題について(Angular 4 で Connection String や Secret を Environment Variables から取得する), 我々は、より多くの情報をここで見つけました https://qiita.com/TsuyoshiUshio@github/items/4243ee860b217534c0d2著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .