Skip to content

Commit 3fc2e8b

Browse files
authored
Merge branch 'main' into i18n-ja-typescript-0
2 parents 127d56d + a7c01c9 commit 3fc2e8b

3 files changed

Lines changed: 385 additions & 37 deletions

File tree

Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
---
2+
title: 環境変数を使う
3+
sidebar:
4+
label: 環境変数
5+
description: Astroプロジェクトで環境変数を使う方法を学びます。
6+
i18nReady: true
7+
---
8+
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'
9+
import ReadMore from '~/components/ReadMore.astro';
10+
11+
Astroでは、[Viteに組み込まれた環境変数のサポート](#viteの組み込みサポート)を利用できます。また、いくつかの[デフォルト環境変数](#デフォルト環境変数)が用意されており、現在のプロジェクトの設定値(`site``base`など)や、プロジェクトが開発・本番のどちらで実行されているかなどにアクセスできます。
12+
13+
さらにAstroは、[型安全に環境変数を使い、整理する方法](#型安全な環境変数)も提供しています。これはAstroのコンテキスト内(Astroコンポーネント、ルートやエンドポイント、UIフレームワークコンポーネント、ミドルウェアなど)で利用でき、[Astro設定内のスキーマ](/ja/reference/configuration-reference/#env)で管理します。
14+
15+
## Viteの組み込みサポート
16+
17+
Astroは、Viteに組み込まれた環境変数のサポートを利用します。これらの環境変数はビルド時に静的に置き換えられ、[Viteが提供する環境変数を扱うためのさまざまな機能](https://vite.dev/guide/env-and-mode.html)を利用できます。
18+
19+
なお、すべての環境変数はサーバーサイドのコードから利用できますが、セキュリティ上の理由から、クライアントサイドのコードで利用できるのは`PUBLIC_`で始まる環境変数のみです。
20+
21+
```ini title=".env"
22+
SECRET_PASSWORD=password123
23+
PUBLIC_ANYBODY=there
24+
```
25+
26+
この例では、`PUBLIC_ANYBODY``import.meta.env.PUBLIC_ANYBODY`でアクセス可能)はサーバーコードでもクライアントコードでも利用できますが、`SECRET_PASSWORD``import.meta.env.SECRET_PASSWORD`でアクセス可能)はサーバーサイドでのみ利用できます。
27+
28+
:::caution
29+
`.env`ファイルは[設定ファイル](#astro設定ファイル内)の中では読み込まれません。
30+
:::
31+
32+
### TypeScriptのIntelliSense
33+
34+
デフォルトでは、Astroは`astro/client.d.ts`内に`import.meta.env`の型定義をあらかじめ用意しています。
35+
36+
`.env.[mode]`ファイルでその他のカスタム環境変数を定義できますが、`PUBLIC_`で始まるユーザー定義の環境変数についてTypeScriptのIntelliSenseを効かせたい場合があります。
37+
38+
そのためには、`src/``env.d.ts`を作成して[グローバルな型を拡張](/ja/guides/typescript/#extending-global-types)し、次のように`ImportMetaEnv`を設定します。
39+
40+
```ts title="src/env.d.ts"
41+
interface ImportMetaEnv {
42+
readonly DB_PASSWORD: string;
43+
readonly PUBLIC_POKEAPI: string;
44+
// その他の環境変数...
45+
}
46+
47+
interface ImportMeta {
48+
readonly env: ImportMetaEnv;
49+
}
50+
```
51+
52+
## デフォルト環境変数
53+
54+
Astroには、いくつかの環境変数が標準で組み込まれています。
55+
56+
- `import.meta.env.MODE`: サイトが実行されているモードです。`astro dev`の実行時は`development``astro build`の実行時は`production`になります。
57+
- `import.meta.env.PROD`: サイトが本番環境で実行されている場合は`true`、それ以外は`false`になります。
58+
- `import.meta.env.DEV`: サイトが開発環境で実行されている場合は`true`、それ以外は`false`になります。常に`import.meta.env.PROD`の逆の値です。
59+
- `import.meta.env.BASE_URL`: サイトが配信されるベースURLです。[`base`設定オプション](/ja/reference/configuration-reference/#base)によって決まります。
60+
- `import.meta.env.SITE`: プロジェクトの`astro.config`で指定された[`site`オプション](/ja/reference/configuration-reference/#site)が設定されます。
61+
62+
これらは、他の環境変数と同じように使えます。
63+
64+
```ts utils.ts
65+
const isProd = import.meta.env.PROD;
66+
const isDev = import.meta.env.DEV;
67+
```
68+
69+
## 環境変数を設定する
70+
71+
### `.env`ファイル
72+
73+
環境変数は、プロジェクトディレクトリにある`.env`ファイルから読み込まれます。
74+
75+
プロジェクトディレクトリに`.env`ファイルを作成し、変数をいくつか追加してみましょう。
76+
77+
```ini title=".env"
78+
# これはサーバー上で実行されるときのみ利用できます!
79+
DB_PASSWORD="foobar"
80+
81+
# これはどこでも利用できます!
82+
PUBLIC_POKEAPI="https://pokeapi.co/api/v2"
83+
```
84+
85+
ファイル名に`.production``.development`、あるいはカスタムモード名(例: `.env.testing``.env.staging`)を加えることもできます。これにより、状況に応じて異なる環境変数のセットを使い分けられます。
86+
87+
`astro dev``astro build`コマンドは、それぞれデフォルトで`"development"`モードと`"production"`モードになります。これらのコマンドを[`--mode`フラグ](/ja/reference/cli-reference/#--mode-string)付きで実行すると、`mode`に別の値を渡し、対応する`.env`ファイルを読み込めます。
88+
89+
これにより、APIの接続先を変えて開発サーバーを起動したり、サイトをビルドしたりできます。
90+
91+
<PackageManagerTabs>
92+
<Fragment slot="npm">
93+
```shell
94+
# 「staging」APIに接続した状態で開発サーバーを起動する
95+
npm run astro dev -- --mode staging
96+
97+
# 「production」APIに接続し、追加のデバッグ情報を含めてサイトをビルドする
98+
npm run astro build -- --devOutput
99+
100+
# 「testing」APIに接続した状態でサイトをビルドする
101+
npm run astro build -- --mode testing
102+
```
103+
</Fragment>
104+
<Fragment slot="pnpm">
105+
```shell
106+
# 「staging」APIに接続した状態で開発サーバーを起動する
107+
pnpm astro dev --mode staging
108+
109+
# 「production」APIに接続し、追加のデバッグ情報を含めてサイトをビルドする
110+
pnpm astro build --devOutput
111+
112+
# 「testing」APIに接続した状態でサイトをビルドする
113+
pnpm astro build --mode testing
114+
```
115+
</Fragment>
116+
<Fragment slot="yarn">
117+
```shell
118+
# 「staging」APIに接続した状態で開発サーバーを起動する
119+
yarn astro dev --mode staging
120+
121+
# 「production」APIに接続し、追加のデバッグ情報を含めてサイトをビルドする
122+
yarn astro build --devOutput
123+
124+
# 「testing」APIに接続した状態でサイトをビルドする
125+
yarn astro build --mode testing
126+
```
127+
</Fragment>
128+
</PackageManagerTabs>
129+
130+
`.env`ファイルの詳細については、[Viteのドキュメント](https://vite.dev/guide/env-and-mode.html#env-files)を参照してください。
131+
132+
### Astro設定ファイル内
133+
134+
Astroは、他のファイルを読み込む前に設定ファイルを評価します。そのため、`astro.config.mjs`内で`import.meta.env`を使って、`.env`ファイルに設定された環境変数にアクセスすることはできません。
135+
136+
設定ファイル内では、[CLIで設定した値](#cliを使う)など、その他の環境変数に`process.env`でアクセスできます。
137+
138+
また、[Viteの`loadEnv`ヘルパー](https://main.vite.dev/config/#using-environment-variables-in-config)を使って、`.env`ファイルを手動で読み込むことも可能です。
139+
140+
```js title="astro.config.mjs"
141+
import { loadEnv } from "vite";
142+
143+
const { SECRET_PASSWORD } = loadEnv(process.env.NODE_ENV, process.cwd(), "");
144+
```
145+
146+
:::note
147+
`pnpm`では、プロジェクトに直接インストールされていないモジュールをインポートできません。`pnpm`を使っている場合は、`loadEnv`ヘルパーを使うために`vite`をインストールする必要があります。
148+
149+
```sh
150+
pnpm add -D vite
151+
```
152+
:::
153+
154+
### CLIを使う
155+
156+
プロジェクトの実行時に環境変数を追加することもできます。
157+
158+
<PackageManagerTabs>
159+
<Fragment slot="yarn">
160+
```shell
161+
PUBLIC_POKEAPI=https://pokeapi.co/api/v2 yarn run dev
162+
```
163+
</Fragment>
164+
<Fragment slot="npm">
165+
```shell
166+
PUBLIC_POKEAPI=https://pokeapi.co/api/v2 npm run dev
167+
```
168+
</Fragment>
169+
<Fragment slot="pnpm">
170+
```shell
171+
PUBLIC_POKEAPI=https://pokeapi.co/api/v2 pnpm run dev
172+
```
173+
</Fragment>
174+
</PackageManagerTabs>
175+
176+
## 環境変数を取得する
177+
178+
Astroでは、環境変数へのアクセスに`process.env`ではなく、[ES2020で追加された`import.meta`機能](https://tc39.es/ecma262/2020/#prod-ImportMeta)を利用した`import.meta.env`を使います。
179+
180+
たとえば、`PUBLIC_POKEAPI`環境変数を取得するには`import.meta.env.PUBLIC_POKEAPI`を使います。
181+
182+
```js /(?<!//.*)import.meta.env.[A-Z_]+/
183+
// import.meta.env.SSR === true のとき
184+
const data = await db(import.meta.env.DB_PASSWORD);
185+
186+
// import.meta.env.SSR === false のとき
187+
const data = fetch(`${import.meta.env.PUBLIC_POKEAPI}/pokemon/squirtle`);
188+
```
189+
190+
SSRを使う場合、環境変数は使用しているSSRアダプターに応じて実行時にアクセスできます。ほとんどのアダプターでは`process.env`で環境変数にアクセスできますが、一部のアダプターは動作が異なります。たとえばDenoアダプターでは`Deno.env.get()`を使います。Cloudflareアダプターを使う場合に環境変数を扱う方法については、[Cloudflareランタイムへのアクセス方法](/ja/guides/integrations-guide/cloudflare/#cloudflare-runtime)を参照してください。Astroはまずサーバー環境に変数があるか確認し、存在しない場合は`.env`ファイル内を探します。
191+
192+
## 型安全な環境変数
193+
194+
`astro:env` APIを使うと、[設定した環境変数](#環境変数を設定する)に対して型安全なスキーマを定義できます。これにより、各変数をサーバーとクライアントのどちらで利用できるようにするかを指定したり、データ型や追加のプロパティを定義したりできます。
195+
196+
<ReadMore>アダプターを開発していますか?[アダプターを`astro:env`に対応させる方法](/ja/reference/adapter-reference/#envgetsecret)を参照してください。</ReadMore>
197+
198+
### 基本的な使い方
199+
200+
#### スキーマを定義する
201+
202+
スキーマを設定するには、Astroの設定に`env.schema`オプションを追加します。
203+
204+
```js title="astro.config.mjs" ins={4-8}
205+
import { defineConfig } from "astro/config";
206+
207+
export default defineConfig({
208+
env: {
209+
schema: {
210+
// ...
211+
}
212+
}
213+
})
214+
```
215+
216+
続いて、`envField`ヘルパーを使って[変数を文字列、数値、列挙型、真偽値として登録](#データ型)できます。各変数に`context``"client"`または`"server"`)と`access``"secret"`または`"public"`)を指定して[環境変数の種類](#変数の種類)を定義し、`optional``default`といった追加のプロパティをオブジェクトで渡します。
217+
218+
```js title="astro.config.mjs" ins="envField"
219+
import { defineConfig, envField } from "astro/config";
220+
221+
export default defineConfig({
222+
env: {
223+
schema: {
224+
API_URL: envField.string({ context: "client", access: "public", optional: true }),
225+
PORT: envField.number({ context: "server", access: "public", default: 4321 }),
226+
API_SECRET: envField.string({ context: "server", access: "secret" }),
227+
}
228+
}
229+
})
230+
```
231+
232+
型は`astro dev``astro build`の実行時に自動生成されますが、`astro sync`を実行して型のみを生成することもできます。
233+
234+
#### スキーマで定義した変数を使う
235+
236+
定義した変数を、`/client`または`/server`モジュールからインポートして使います。
237+
238+
```astro
239+
---
240+
import { API_URL } from "astro:env/client";
241+
import { API_SECRET_TOKEN } from "astro:env/server";
242+
243+
const data = await fetch(`${API_URL}/users`, {
244+
method: "GET",
245+
headers: {
246+
"Content-Type": "application/json",
247+
"Authorization": `Bearer ${API_SECRET_TOKEN}`
248+
},
249+
})
250+
---
251+
252+
<script>
253+
import { API_URL } from "astro:env/client";
254+
255+
fetch(`${API_URL}/ping`)
256+
</script>
257+
```
258+
259+
### 変数の種類
260+
261+
環境変数には、スキーマで定義する`context``"client"`または`"server"`)と`access``"secret"`または`"public"`)の設定の組み合わせによって決まる、3つの種類があります:
262+
263+
- **パブリックなクライアント変数**: この変数は最終的なクライアントバンドルとサーバーバンドルの両方に含まれ、`astro:env/client`モジュールを通じてクライアントとサーバーの両方からアクセスできます。
264+
265+
```js
266+
import { API_URL } from "astro:env/client";
267+
```
268+
269+
- **パブリックなサーバー変数**: この変数は最終的なサーバーバンドルに含まれ、`astro:env/server`モジュールを通じてサーバー上でアクセスできます。
270+
271+
```js
272+
import { PORT } from "astro:env/server";
273+
```
274+
275+
- **シークレットサーバー変数**: この変数は最終的なバンドルには含まれず、`astro:env/server`モジュールを通じてサーバー上でアクセスできます。
276+
277+
```js
278+
import { API_SECRET } from "astro:env/server";
279+
```
280+
281+
デフォルトでは、`astro:env/server`モジュールから何かがインポートされるたびに、すべてのシークレットが検証されます。つまり、インポートされていないシークレットも検証される場合があります。ビルド時にこの検証を満たすために、[ダミーの環境変数を渡す](#環境変数を設定する)必要があるかもしれません。
282+
283+
また、[`validateSecrets: true`を設定](/ja/reference/configuration-reference/#envvalidatesecrets)することで、起動時にシークレットを検証するようにもできます。
284+
285+
:::note
286+
**シークレットクライアント変数**は、データを安全にクライアントへ送信する方法がないためサポートされていません。したがって、スキーマで`context: "client"``access: "secret"`の両方を設定することはできません。
287+
:::
288+
289+
### データ型
290+
291+
現在、文字列、数値、列挙型、真偽値の4つのデータ型がサポートされています。
292+
293+
```js
294+
import { envField } from "astro/config";
295+
296+
envField.string({
297+
// context と access
298+
optional: true,
299+
default: "foo",
300+
})
301+
302+
envField.number({
303+
// context と access
304+
optional: true,
305+
default: 15,
306+
})
307+
308+
envField.boolean({
309+
// context と access
310+
optional: true,
311+
default: true,
312+
})
313+
314+
envField.enum({
315+
// context と access
316+
values: ["foo", "bar", "baz"],
317+
optional: true,
318+
default: "baz",
319+
})
320+
```
321+
322+
<ReadMore>`envField`で指定できる検証用フィールドの完全な一覧については、[`envField` APIリファレンス](/ja/reference/modules/astro-config/#envfield)を参照してください。</ReadMore>
323+
324+
### シークレットを動的に取得する
325+
326+
スキーマを定義していても、特定のシークレットの生の値を取得したい場合や、スキーマで定義されていないシークレットを取得したい場合があります。そのような場合は、`astro:env/server`からエクスポートされている`getSecret()`を使えます。
327+
328+
```js
329+
import {
330+
FOO, // boolean
331+
getSecret
332+
} from "astro:env/server";
333+
334+
getSecret("FOO"); // string | undefined
335+
```
336+
337+
<ReadMore>詳しくは[APIリファレンス](/ja/reference/modules/astro-env/#getsecret)を参照してください。</ReadMore>
338+
339+
### 制限事項
340+
341+
`astro:env`は仮想モジュールであり、Astroコンテキスト内でのみ使えます。たとえば、以下の場所で使えます。
342+
343+
- ミドルウェア
344+
- Astroのルートとエンドポイント
345+
- Astroコンポーネント
346+
- フレームワークコンポーネント
347+
- モジュール
348+
349+
以下の場所では利用できないため、`process.env`を使う必要があります。
350+
351+
- `astro.config.mjs`
352+
- スクリプト

0 commit comments

Comments
 (0)