# [學習筆記] .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> 伺服器上面以點開頭的檔案都是隱藏檔案,不會暴露給外部,它不會參與打包。 ![](https://hackmd.io/_uploads/SyRUcXm62.jpg) <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 去讀取這個環境變數。⬇︎ ![](https://hackmd.io/_uploads/Bk_wG77p3.png) <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. 這些工具在項目中提供了一種靈活的方式來配置不同環境的變量,方便在開發、測試和生產環境中管理應用程序的配置。根據您使用的工具和框架,您可以選擇適合您項目的環境配置方式。