Vue腳手架模式與環境變量

在真實項目裏,「如果每次切換環境都手動改代碼,不僅低效,還極易把測試地址帶到線上。Vue CLI 把「模式 + 環境變量」做成了一套約定大於配置的體系,只要理解規則,就能讓同一份源碼在任意環境自動作出正確的行為。

一、模式(mode)

image-20210323133209659

Vue CLI 把「運行命令」抽象成三種默認模式:

  • development:對應 vue-cli-service serve
  • production:對應 vue-cli-service build
  • test:對應 vue-cli-service test:unit

模式本身不攜帶任何變量,它只是約定文件名前綴。

當你執行:

npm run serve        # 實際等價於 vue-cli-service serve --mode development
npm run build:staging # 自定義命令,等價於 vue-cli-service build --mode staging

CLI 會按以下順序尋找文件:

  1. .env.[mode].local
  2. .env.[mode]
  3. .env.local(永遠被 git ignore)
  4. .env

同名變量後者覆蓋前者,因此你可以把公共值寫在 .env,把敏感值寫在 .env.local,把環境特有值寫在 .env.staging,一條命令即可切換。

二、環境變量

  1. 只有 VUE_APP_ 開頭的變量才會被打包

任何機器級環境變量(PATHHOME …)都會被忽略,避免污染前端運行時。

想讓變量進 bundle,必須加前綴:

# .env.staging
VUE_APP_API_BASE=https://staging.api.example.com

在代碼裏直接用:

axios.defaults.baseURL = process.env.VUE_APP_API_BASE

構建時 CLI 會把 process.env.VUE_APP_API_BASE 替換為字符串字面量,零運行時開銷。

  1. 運行時不可動態修改

變量在 npm run build 那一刻就被寫死,前端無法通過 process.env.XXX = 'new' 去改。

需要運行時可變配置?把變量寫成 JSON 文件或接口返回,再在前端異步加載即可。

三、一個文件,一條命令,三種環境

假設我們要同時支持 dev / staging / prod

根目錄
├─ .env                 # 公共配置
├─ .env.development     # 本地開發
├─ .env.staging         # 預發
├─ .env.production      # 線上
└─ package.json

文件內容示例:

# .env
VUE_APP_TITLE=MyApp

# .env.development
VUE_APP_API_BASE=http://localhost:3000

# .env.staging
VUE_APP_API_BASE=https://staging.api.example.com

# .env.production
VUE_APP_API_BASE=https://api.example.com

自定義腳本:

"scripts": {
  "serve": "vue-cli-service serve",
  "build:staging": "vue-cli-service build --mode staging",
  "build": "vue-cli-service build"
}

執行:

npm run build:staging

CLI 自動讀取 .env.staging.env 合併,輸出包裏只有 https://staging.api.example.com

四、CI/CD 中的最佳實踐

  1. 不把敏感密鑰寫進倉庫

    .env*.local 加入 .gitignore,在 CI 裏用環境變量注入:

   echo $STAGING_KEY >> .env.staging.local
  1. 單一 Dockerfile,多階段構建

    通過 ARG MODE 動態決定 --mode,同一份鏡像可在測試、預發、生產之間漂移。

  2. 可視化差異

    在構建日誌裏打印 console.log('Build mode:', process.env.NODE_ENV, process.env.VUE_APP_API_BASE),一眼確認變量是否生效。

五、常見問題

  • 變量名可以改前綴嗎?

    可以,在 vue.config.js 裏設置 envPrefix: 'APP_' 即可。

  • 為什麼本地 .env 改了值不生效?

    vue-cli-service serve 會緩存舊進程,重啓 dev-server 或加 --no-cache 即可。

  • 如何讀取非 VUE_APP 變量?

    vue.config.jschainWebpack 手動注入:

  config.plugin('define').tap(args => {
    args[0]['process.env.CUSTOM'] = JSON.stringify(process.env.CUSTOM)
    return args
  })