# [學習筆記] .env 環境變數
## .env 環境變數是什麼?
:::info
:bulb: Env 全名是 Environment 中文又稱環境變數,不論是前端或者後端開發上都是非常常見的東西。
:::
Env 主要是拿來做什麼呢?通常是拿來存放一些比較敏感的資訊,例如常見的…
* key(金鑰)
* secret(密碼)
* token(權杖)
* …等等
因為我們的程式碼裡面絕對不能出現任何敏感資訊,因此我們會把這些敏感資訊放在 Env 裡面,然後在程式碼中使用 Env 來取得這些敏感資訊。
通常 Env 的檔案會叫做 .env,而你有可能會看到以下類型的 .env 檔案。
* .env
* .env.development
* .env.production
* .env.test
<br>
## 舉例來說
這些都是不同的 Env 檔案,可以在不同的環境下取用不同的 Env,例如在開發環境下使用 .env.development,而在正式環境下使用 .env.production。
重點在於不同的 .env 可以自由切換,如果要換環境,那就要一直改code會很麻煩。
<br>
以 Vite來舉例的話,.env 是vite提供的環境配置。
###### => 執行 npm run dev 的時候,vite會吃「env.development」
###### => 執行 npm run build 的時候,vite會吃「env.production」或「.env」
###### => 執行 npm test 的時候,vite會吃「env.testing」
<br>
伺服器上面以點開頭的檔案都是隱藏檔案,不會暴露給外部,它不會參與打包。

<br>
通常來講我們不會把 .env 加入到 Git 版本控制內,如前面所說 .env 檔案主要是放置敏感資訊,因此 .env 通常會被加入到 .gitignore,這樣子才不會不小心把敏感資訊上傳到遠端儲存庫上。
如果不小心傳上去,趕快上去刪掉你的遠端儲存庫,並把 .env 內的資訊更換掉 ([文章來源](https://israynotarray.com/other/20230218/3618693250/))
<br>
## 應用
先創建一個.env⬇︎
```javascript!
// .env
VITE_APP_NAME=example
VITE_API_URL=https://api.example.com
```
<br>
1. 可以這樣用⬇︎
```javascript!
// @/src/http/config.js
/**
* @description: http请求配置
*/
export default {
baseURL: import.meta.env.VITE_API_URL,
timeout: 20000,
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
},
}
```
<br>
2. 可以這樣用⬇︎
```javascript!
// App.vue
<template>
<div>
這是一句話
</div>
</template>
<script setup>
fetch(import.meta.env.VITE_API_URL)
.then(response => response.json())
.then(json => console.log(json))
</script>
```
<br>
我們可以這樣做,在 javascript 去讀取這個環境變數。⬇︎

<br>
:::warning
因此其實前端的 Env 並不適合放一些敏感資訊,比較適合作為一些常用的設定管理。
例如:API Url、網站標題等,比較重複性高,未來若要調整可以一次調整的設定。
而這也是為什麼我在前面說「後端的 Env 非常的安全」,因為後端的程式碼是運行在伺服器上,而前端的程式碼是直接在瀏覽器上執行的,所以使用者只要將你的程式碼下載下來,就可以直接看到你的 Env 內容。
:::
<br>
## しかし (但是呢!
這樣的話,難道變數一定都會被看光光嗎?
不是嗲,請繼續看 ☟
<br>
加載的環境變數也會通過 `import.meta.env` 以字符串形式暴露給客戶端源碼。
為了防止意外將一些環境變數洩漏到客戶端,假設目前使用是 Vite 的話,以 `VITE_`為**前綴變量**,是經過 vite 處理的代碼(被vite解析後注入 javascript 中),只有加上這個前綴才會暴露給客戶端。
```javascript!
// .env
VITE_SOME_KEY=123
DC_PASSWORD=foobar
```
* 只有 `VITE_SOME_KEY` 會暴露為 `import.meta.env.VITE_SOME_KEY` 提供給客戶端碼。
* `VITE_SOME_KEY` 則不會,反而會當成機密變數。
<br>
:::danger
**環境加載優先級**
指定模式的文件(ex: .env.production)會比通用形式的優先級更高(ex: .env)。
Vite 執行時,已經存在的環境變數有最高優先度,不會被 `.env` 類文件覆蓋。
(ex: 當運行到`VITE_SOME_KEY=123 vite build` 的時候)
.env 類文件會在 Vite 啟動一開始時自動被加載,而改動的話會再重啟服務器後生效。
:::
<br>
## 那麼機密變數要怎麼用呢?
因為在 javascript 上用,會被看光光,且如果是靜態部署,基本上就不會用到機密變數。
前端開發也可能會涉及到金鑰存取,比如說密鑰路徑,一些秘密參數、串接金流、第三方api、身份認證、圖片影片上傳加解密。
如果你是用像 Vite 這樣有支援 SSR 的框架工具,就可以在服務器端設置環境變量,把機密變數運用在這個服務器上。
> 剛剛問了 ChatGPT,他是說可以 `const { createServerRenderer } = require('vite')` 或是 裝 `vite-ssr` 外掛,目前還沒試過,所以不知道XD
<br>
## 有其他類似的框架也提供.env環境配置能嗎?
除了Vite之外的許多,前端框架和工具也提供了類似的一些環境配置功能,方便在不同的開發環境中配置不同的參數和選項。以下是其他前端框架和工具提供的環境配置選項:
1. Create React App (CRA) : CRA是一個用於快速創建React應用程序的腳手架工具,它使用.env文件來配置環境變量。您可以創建.env、.env.local、.env.development、.env.test等.env.production文件來分別不同的配置環境變量。
3. Vue CLI:Vue CLI是Vue.js官方提供的腳手架工具,類似Vite,它也支持.env文件來配置環境變量。您可以創建.env、.env.local、.env.development、.env.production等文件來配置不同環境的變量。
5. Webpack:Webpack是一個強大的資源工具,它也支持使用.env文件來配置環境變量。您可以使用.env、.env.development、.env.production等文件來配置不同的環境變量。
3. Next.js : Next.js是一個React框架,它提供了.env文件來配置環境變量。您可以創建.env、.env.local、.env.development、.env.production等文件來配置不同環境的變量。
5. 這些工具在項目中提供了一種靈活的方式來配置不同環境的變量,方便在開發、測試和生產環境中管理應用程序的配置。根據您使用的工具和框架,您可以選擇適合您項目的環境配置方式。