點燈坊

失くすものさえない今が強くなるチャンスよ

在 Vue 實現 Compilation Variable

Sam Xiao's Avatar 2023-01-13

實務上如每個廠區的 route 與 page 都不相同,而每個廠區的 變數 都在編譯時期就決定了,這些變數就是 compilation variable,可將這些變數定義在不同的 .env 中,當使用 vue-cli-service 編譯時,可加上 --mode 參數指定使用不同的 .env

Version

Vue 2.7

Environment Variable

.env.tj

VUE_APP_MODE=TJ
  • 在專案根目錄下建立 .env.tj 定義 tj 模式下的編譯時期變數,檔名命名方式需以 .env 開頭,後面加上自己的 模式名稱
  • 變數名稱須以 VUE_APP_ 開頭,Webpack 才會接受

.env.zz

VUE_APP_MODE=ZZ
  • 以相同方式建立 .env.zz 定義 zz 模式下的編譯時期變數

NPM Script

package.json

{
  "name": "vue27-route",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve-tj": "vue-cli-service --mode tj serve",
    "serve-zz": "vue-cli-service --mode zz serve",
    "build-tj": "vue-cli-service --mode tj build",
    "build-zz": "vue-cli-service --mode zz build"
  },
  "dependencies": {
    "core-js": "^3.8.3",
    "vue": "^2.6.14",
    "vue-router": "^3.5.1"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-router": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "vue-template-compiler": "^2.6.14"
  }
}

Line 5

"scripts": {
  "serve-tj": "vue-cli-service --mode tj serve",
  "serve-zz": "vue-cli-service --mode zz serve",
  "build-tj": "vue-cli-service --mode tj build",
  "build-zz": "vue-cli-service --mode zz build"
},
  • 使用 vue-cli-service 進行 servebuild 時,特別加上 --mode 指定使用哪個 .env,不需指定完整的 .env 檔案名稱,只需指定 .env 之後的自訂名稱即可

JavaScript

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

console.log('mode in main.js', process.env.VUE_APP_MODE)

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

Line 7

console.log('mode in main.js', process.env.VUE_APP_MODE)

可在 main.jsprocess.env.VUE_APP_MODE 讀取到自訂的編譯時期變數。

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

console.log('mode in router/index.js', process.env.VUE_APP_MODE)

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

Line 7

console.log('mode in router/index.js', process.env.VUE_APP_MODE)

亦可在 router/index.jsprocess.env.VUE_APP_MODE 讀取到自訂的編譯時期變數。

Vue

App.vue

<template>
  <div>Hello World</div>
</template>

<script>
export default {
  mounted() {
    console.log('mode in Vue', process.env.VUE_APP_MODE)
  }
}
</script>

Line 7

mounted() {
  console.log('mode in Vue', process.env.VUE_APP_MODE)
}

亦可在 Vue 以 process.env.VUE_APP_MODE 讀取到自訂的編譯時期變數

Conclusion

  • 直覺可能會想在 package.json 定義自訂變數,不過由於 Vue 2 需經過 Webpack 處理,所以實作上並沒有這麼簡單;但透過 .env 則可巧妙地透過 Vue CLI 處理,不必直接面對 Webpack