一文詳細(xì)聊聊import.meta.env和process.env的區(qū)別
前言
這是一個前端構(gòu)建環(huán)境里非常核心、也非常容易混淆的問題。下面我們從來源、使用場景、編譯時機、安全性四個維度來談?wù)?import.meta.env 和 process.env 的區(qū)別。
一句話結(jié)論
process.env是 Node.js 的環(huán)境變量接口import.meta.env是 Vite(ESM)在構(gòu)建期注入的前端環(huán)境變量
一、process.env是什么?
本質(zhì)
- 來自 Node.js
- 運行時讀取 服務(wù)器 / 構(gòu)建機的系統(tǒng)環(huán)境變量
- 本身 瀏覽器里不存在
console.log(process.env.NODE_ENV);
使用場景
- Node 服務(wù)
- 構(gòu)建工具(Webpack / Vite / Rollup)
- SSR(Node 端)
前端能不能用?
?? 不能直接用
瀏覽器里沒有 process:
// 瀏覽器原生環(huán)境 ? Uncaught ReferenceError: process is not defined
為什么 Webpack 項目里能用?
因為 Webpack 幫你“編譯期替換”了
process.env.NODE_ENV // ?? 構(gòu)建時被替換成 "production"
本質(zhì)是 字符串替換,不是運行時讀取。
二、import.meta.env是什么?
本質(zhì)
- Vite 提供
- 基于 ES Module 的 import.meta
- 構(gòu)建期 + 運行期可用(但值是構(gòu)建期確定的)
console.log(import.meta.env.MODE);
特點
- 瀏覽器里 原生支持
- 不依賴 Node 的
process - 更符合現(xiàn)代 ESM 規(guī)范
三、兩者核心區(qū)別對比(重點)
| 維度 | process.env | import.meta.env |
|---|---|---|
| 來源 | Node.js | Vite |
| 標(biāo)準(zhǔn) | Node API | ESM 標(biāo)準(zhǔn)擴展 |
| 瀏覽器可用 | ?(需編譯替換) | ? |
| 注入時機 | 構(gòu)建期 | 構(gòu)建期 |
| 是否運行時讀取 | ? | ? |
| 推薦前端使用 | ? | ? |
?? 兩者都不是“前端運行時讀取服務(wù)器環(huán)境變量”
四、Vite 中為什么不用process.env?
因為 Vite 不再默認(rèn)注入process
// Vite 項目中 ? process.env.API_URL
會直接報錯。
官方設(shè)計選擇
- 避免 Node 全局污染
- 更貼近瀏覽器真實環(huán)境
- 更利于 Tree Shaking
五、Vite 環(huán)境變量的正確用法(非常重要)
必須以VITE_開頭
# .env VITE_API_URL=https://api.example.com console.log(import.meta.env.VITE_API_URL);
? 否則 不會注入到前端
內(nèi)置變量
import.meta.env.MODE // development / production import.meta.env.DEV // true / false import.meta.env.PROD // true / false import.meta.env.BASE_URL
六、安全性
重要警告
import.meta.env 里的變量 ≠ 私密
它們會:
- 被 打進(jìn) JS Bundle
- 可在 DevTools 直接看到
不要這樣做
VITE_SECRET_KEY=xxxx
正確做法
- 前端:只放“公開配置”(API 域名、開關(guān))
- 私密變量:只放在 Node / 服務(wù)端
七、SSR / 全棧項目里怎么區(qū)分?
在 Vite + SSR(如 Nuxt / 自建 SSR):
Node 端
process.env.DB_PASSWORD
瀏覽器端
import.meta.env.VITE_API_URL
兩套環(huán)境變量是刻意分開的。
為什么必須分成兩套?(設(shè)計原因)
執(zhí)行環(huán)境不同(這是根因)
| 位置 | 運行在哪 | 能訪問什么 |
|---|---|---|
| SSR Server | Node.js | process.env |
| Client Bundle | 瀏覽器 | import.meta.env |
瀏覽器里 永遠(yuǎn)不可能安全地訪問服務(wù)器環(huán)境變量。
SSR ≠ 瀏覽器
很多人誤解:
“SSR 是不是瀏覽器代碼先在 Node 跑一遍?”
? 不完全對
SSR 實際是:
Node.js 先跑一份 → 生成 HTML 瀏覽器再跑一份 → hydrate
這兩次執(zhí)行:
- 環(huán)境不同
- 變量來源不同
- 安全級別不同
在 Vite + SSR 中,變量的“真實流向”
Node 端(SSR Server)
// server.ts / entry-server.ts const dbPassword = process.env.DB_PASSWORD;
?? 真實運行時讀取
?? 不會進(jìn) bundle
?? 只存在于服務(wù)器內(nèi)存
Client 端(瀏覽器)
// entry-client.ts / React/Vue 組件 const apiUrl = import.meta.env.VITE_API_URL;
?? 構(gòu)建期注入
?? 會打進(jìn) JS
?? 用戶可見
中間那條“禁止通道”
// ? 絕對禁止 process.env.DB_PASSWORD → 瀏覽器
SSR 不會、也不允許,自動幫你“透傳”環(huán)境變量
SSR 中最容易踩的 3 個坑(重點)
坑 1:在“共享代碼”里直接用process.env
// utils/config.ts(被 server + client 共用) export const API = process.env.API_URL; // ?
問題:
- Server OK
- Client 直接炸(或被錯誤替換)
? 正確方式:
export const API = import.meta.env.VITE_API_URL;
或者:
export const API =typeof window === 'undefined'
? process.env.INTERNAL_API
: import.meta.env.VITE_API_URL;
坑 2:誤以為 SSR 可以“順手用數(shù)據(jù)庫變量”
// Vue/React 組件里 console.log(process.env.DB_PASSWORD); // ?
哪怕你在 SSR 模式下,這段代碼:
- 最終仍會跑在瀏覽器
- 會被打包
- 是嚴(yán)重安全漏洞
坑 3:把“環(huán)境變量”當(dāng)成“運行時配置”
// ? 想通過部署切換 API import.meta.env.VITE_API_URL
?? 這是 構(gòu)建期值:
build 時確定 → CDN 緩存 → 所有用戶共享
想運行期切換?只能:
- 接口返回配置
- HTML 注入 window.CONFIG
- 拉 JSON 配置文件
SSR 項目里“正確的分層模型”(工程視角)
┌──────────────────────────┐
│ 瀏覽器 Client │
│ import.meta.env.VITE_* │ ← 公開配置
└───────────▲──────────────┘
│
HTTP / HTML
│
┌───────────┴──────────────┐
│ Node SSR Server │
│ process.env.* │ ← 私密配置
└───────────▲──────────────┘
│
內(nèi)部訪問
│
┌───────────┴──────────────┐
│ DB / Redis / OSS │
└──────────────────────────┘
這是一條 單向、安全的數(shù)據(jù)流。
Nuxt / 自建 SSR 的對應(yīng)關(guān)系
| 類型 | 用途 |
|---|---|
| runtimeConfig | Server-only |
| runtimeConfig.public | Client 可見 |
| process.env | 僅 server |
?? Nuxt 本質(zhì)也是在幫你維護(hù)這條邊界
八、常見誤區(qū)總結(jié)
誤區(qū) 1
import.meta.env是運行時讀取
? 錯,仍是構(gòu)建期注入
誤區(qū) 2
可以用它動態(tài)切換環(huán)境
? 不行,想動態(tài)只能:
- 接口返回配置
- 或運行時請求 JSON
誤區(qū) 3
Vite 里還能繼續(xù)用
process.env
? 除非你手動 polyfill(不推薦)
九、總結(jié)
- 前端(Vite)只認(rèn)
import.meta.env.VITE_* - 服務(wù)端(Node)只認(rèn)
process.env - 永遠(yuǎn)不要把秘密放進(jìn)前端 env
到此這篇關(guān)于import.meta.env和process.env區(qū)別的文章就介紹到這了,更多相關(guān)import.meta.env和process.env區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Node.js創(chuàng)建一個Express服務(wù)的方法詳解
這篇文章主要介紹了Node.js創(chuàng)建一個Express服務(wù)的方法,結(jié)合實例形式分析了node.js創(chuàng)建Express服務(wù)的具體步驟、實現(xiàn)方法及相關(guān)操作技巧,需要的朋友可以參考下2020-01-01
windows 下安裝nodejs 環(huán)境變量設(shè)置
windows 下安裝nodejs 了,也安裝了npm, 但是有時候切不能直接用request(‘ws’)這一類的東西.我覺得是確實環(huán)境變量或其他設(shè)置有問題,能否給個完整的設(shè)置方案:2017-02-02
了不起的node.js讀書筆記之node的學(xué)習(xí)總結(jié)
這篇文章主要介紹了了不起的node.js讀書筆記之node的學(xué)習(xí)總結(jié),需要的朋友可以參考下2014-12-12
一文教你學(xué)會Nodejs中puppeteer的簡單使用
Puppeteer是一個控制headless Chrome的Node.js API ,是一個 Node.js庫,在瀏覽器中手動完成的大多數(shù)事情都可以通過使用 Puppeteer完成,本文主要介紹了Puppeteer的簡單使用,希望對大家有所幫助2024-01-01
WebSocket+node.js創(chuàng)建即時通信的Web聊天服務(wù)器
這篇文章主要為大家詳細(xì)介紹了WebSocket+node.js創(chuàng)建即時通信的Web聊天服務(wù)器的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-08-08

