認(rèn)識(shí)環(huán)境變量
以最熟悉的 import.meta.env.BASE_URL 為例:
// router/index.js
const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL),
routes: [
// ...
]
})
該變量在:
- 開(kāi)發(fā)環(huán)境中,默認(rèn)值通常是 '/'
- 生產(chǎn)環(huán)境中,這個(gè)值可以根據(jù) vite.config.js 文件中的 base 配置項(xiàng)進(jìn)行設(shè)置
Vite 其他內(nèi)置環(huán)境變量:
- import.meta.env.MODE:獲取當(dāng)前應(yīng)用運(yùn)行的模式
- import.meta.env.PROD:應(yīng)用是否運(yùn)行在生產(chǎn)環(huán)境
- import.meta.env.DEV:應(yīng)用是否運(yùn)行在開(kāi)發(fā)環(huán)境
- import.meta.env.SSR:應(yīng)用是否運(yùn)行在 server 上
NODE_ENV和模式
代碼運(yùn)行有不同的環(huán)境:
- 開(kāi)發(fā)環(huán)境
- 測(cè)試環(huán)境
- 生產(chǎn)環(huán)境
不同的環(huán)境,需要不同的配置來(lái)滿足需求。
例如:
數(shù)據(jù)庫(kù)連接
- 開(kāi)發(fā)環(huán)境:通常連接到本地?cái)?shù)據(jù)庫(kù)或開(kāi)發(fā)用的數(shù)據(jù)庫(kù)服務(wù)器,這些數(shù)據(jù)庫(kù)可能包含測(cè)試數(shù)據(jù)或模擬數(shù)據(jù)。
- 測(cè)試環(huán)境:連接到模擬真實(shí)運(yùn)行狀態(tài)的測(cè)試數(shù)據(jù)庫(kù),這些數(shù)據(jù)庫(kù)中的數(shù)據(jù)結(jié)構(gòu)和生產(chǎn)環(huán)境一致,但數(shù)據(jù)通常是匿名化或?qū)闇y(cè)試準(zhǔn)備的。
- 生產(chǎn)環(huán)境:連接到包含真實(shí)用戶數(shù)據(jù)的生產(chǎn)數(shù)據(jù)庫(kù),且通常具有高可用性和額外的安全配置。
API密鑰和憑證
- 開(kāi)發(fā)環(huán)境:可能使用具有限制權(quán)限的API密鑰,這些密鑰用于防止在開(kāi)發(fā)過(guò)程中對(duì)真實(shí)數(shù)據(jù)造成影響。
- 測(cè)試環(huán)境:使用專為測(cè)試設(shè)計(jì)的密鑰,這些密鑰可能允許訪問(wèn)更多的測(cè)試接口或模擬數(shù)據(jù)。
- 生產(chǎn)環(huán)境:使用具有完整訪問(wèn)權(quán)限的API密鑰,這些密鑰通常需要嚴(yán)格保密,以保護(hù)應(yīng)用和用戶數(shù)據(jù)的安全。
錯(cuò)誤處理
- 開(kāi)發(fā)環(huán)境:錯(cuò)誤可能直接顯示詳細(xì)的堆棧信息,便于開(kāi)發(fā)者快速定位問(wèn)題。
- 測(cè)試環(huán)境:錯(cuò)誤處理可能包括將錯(cuò)誤詳細(xì)記錄到日志文件,同時(shí)顯示給定的錯(cuò)誤消息以模擬生產(chǎn)環(huán)境的行為。
- 生產(chǎn)環(huán)境:錯(cuò)誤處理旨在不泄露任何敏感信息,通常只提供一個(gè)用戶友好的錯(cuò)誤消息和一個(gè)錯(cuò)誤代碼,同時(shí)將詳細(xì)信息記錄在服務(wù)器的安全日志中。
如何指定代碼運(yùn)行的環(huán)境呢?
一般可以通過(guò) NODE_ENV 這個(gè)環(huán)境變量,該變量可以指定代碼的運(yùn)行環(huán)境,比如 development、production 或 test
通過(guò)指定運(yùn)行環(huán)境,從而能夠:
控制代碼行為:開(kāi)發(fā)者可以根據(jù) NODE_ENV 的值在代碼中做一些判斷,從而執(zhí)行不同的邏輯
-
影響構(gòu)建工具和庫(kù):很多工具和庫(kù)也會(huì)根據(jù) NODE_ENV 不同的值有不同的行為
if (process.env.NODE_ENV === 'production') { // 生產(chǎn)環(huán)境的特定邏輯 } module.exports = { mode: 'development', // 其他配置... };
那 Vite 中的模式又是什么呢?
一句話總結(jié):在 Vite 中,模式是一個(gè)可以在啟動(dòng)時(shí)設(shè)置的屬性,用來(lái)指導(dǎo) Vite 如何加載 .env 文件。
.env 的文件用來(lái)存放環(huán)境變量,之后在客戶端源碼中就可以通過(guò) import.meta.env 來(lái)訪問(wèn)對(duì)應(yīng)的值。
另外,為了防止意外地將一些環(huán)境變量泄漏到客戶端,只有以 VITE_ 為前綴的變量才會(huì)暴露給經(jīng)過(guò) vite 處理的代碼。
例如:
.env
VITE_SOME_KEY=123
DB_PASSWORD=foobar
這里只有 VITE_SOME_KEY 會(huì)暴露給客戶端源碼:
console.log(import.meta.env.VITE_SOME_KEY) // "123"
console.log(import.meta.env.DB_PASSWORD) // undefined
.env 文件還可以有不同的類型:
.env # 所有情況下都會(huì)加載
.env.local # 所有情況下都會(huì)加載,但會(huì)被 git 忽略
.env.[mode] # 只在指定模式下加載
.env.[mode].local # 只在指定模式下加載,但會(huì)被 git 忽略
這里的 mode 指代的就是 Vite 里面的模式。
例如,我們可以在 .env.development 和 .env.production 文件中定義不同的環(huán)境變量,在使用 Vite 啟動(dòng)應(yīng)用的時(shí)候可以指定對(duì)應(yīng)的模式加載對(duì)應(yīng)的 .env 文件。
my-vite-project/
├── .env # 默認(rèn)的環(huán)境變量
├── .env.development # 開(kāi)發(fā)環(huán)境的環(huán)境變量
├── .env.production # 生產(chǎn)環(huán)境的環(huán)境變量
├── src/
│ └── main.js
└── vite.config.js
.env.development
VITE_API_URL=https://dev.api.example.com
DEBUG=true
.env.production
VITE_API_URL=https://api.example.com
DEBUG=false
之后使用 Vite 啟動(dòng)應(yīng)用的時(shí)候,就可以指定特定的模式,從而加載不同的 .env 文件
# 開(kāi)發(fā)環(huán)境
vite --mode development
# 生產(chǎn)環(huán)境構(gòu)建
vite build --mode production
思考??:為什么有了 NODE_DEV 還需要 mode 模式?
答案:NODE_DEV 是在 Node.js 環(huán)境中最早被支持的一個(gè)環(huán)境變量,廣泛的被用于各大工具和庫(kù)。而模式是特定于某個(gè)構(gòu)建工具,主要就是用于更加細(xì)粒度的場(chǎng)景控制。也就是說(shuō),使用 mode 可以在不影響 NODE_DEV 的前提下具備更高的靈活性。