我並非專職寫前端框架, 但 Vue 我還挺喜歡用的, 因非專職所以之前一直懶的去看看 Vite 的用法, 但最近在寫 Quartz.Net 的 Dashboard 介面頻繁的對 UI 介面除錯, 讓我受不了 Vue CLI 的龜速, 還是乖乖的看看 Vite 如何用如何轉換﹐用過之後果然讓人無法回頭, 我怎麼不早點換呢~
這裏就將 Vue CLI 轉換 Vite 時的一些筆記留下﹐紀錄 CLI 和 Vite 不同之處, 做為日後的參考。
一﹑建立專案
Vue CLI
需要先透過 npm 安裝 vue
npm install -g @vue/cli
再執行
vue create <專案名稱>
專案建立過程會詢問一些問題﹐例如是否使用 Router﹑Vuex﹑Linter﹑Sass/SCSS...再安裝過程中是否一併安裝
Vite
建立 Vite 專案
npm init vite@latest
過程中會詢問的只有專案名稱﹑使用那一種 Framework(不只有支援 Vue)﹑使用那一種語言(Javascript or TypeScript)
如果要使用如 router﹑Sass﹑Linter...之類的都必須另外安裝﹐不會再建立專案時詢問及安裝
另外, Vite 專案建置後會發現檔案結構中並沒有 node_modules 的資料夾, 所以需要先安裝相關的套件
npm install
執行後再檢視就有 node_modules 的資料夾
二﹑ config 檔(Vue.config.js & vite.config.js)
檔案結構對比
vue.config.js
const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
  transpileDependencies: true,
  outputDir: "../wwwwroot",
  configureWebpack: {
    devtool: "source-map"
  },
  //頁面 title
  chainWebpack: config => {
    config.plugin("html").tap(args => {
      args[0].title = "Quartz.Net Dashboard";
      return args;
    });
  }
});
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    {
      name: 'html-transform',
      transformIndexHtml(html) {
        return html.replace(/<title>(.*?)<\/title>/, '<title>Quartz.Net Dashboard</title>')  // 頁面 title 修改標題
      }
    }
  ],
  build: {
    outDir: '../wwwroot2',  // 指定輸出目錄
    emptyOutDir: true,      // 在 build 之前清空輸出目錄
    sourcemap: true,   // 生成 source map 可以進行前端 browser debug
    // rollupOptions: {
    //   output: {  // build 後的輸出的檔案不帶有哈希值
    //     entryFileNames: 'assets/[name].js',
    //     chunkFileNames: 'assets/[name].js',
    //     assetFileNames: 'assets/[name].[ext]'
    //   }
    // }
  },
  resolve: {
    alias: {
      '@': resolve(__dirname, './src')  // 設置 @ 指向 src
    }
  }
  // server: {
  //   port: 3000   // 可以根據需要修改開發時使用的 port, 若沒有設置則預設為 5173
  // }
})
輸出目錄
vue.config.js
outputDir: "../wwwroot"
vite.config.js
build.outDir: "../wwwroot"
source map
vue.config.js
configureWebpack.devtool: "source-map"
vite.config.js
build.sourcemap: true
頁面 title
vue.config.js
  chainWebpack: config => {
    config.plugin("html").tap(args => {
      args[0].title = "Quartz.Net Dashboard";
      return args;
    });
  }
vite.config.js
import vue from '@vitejs/plugin-vue'
...
  plugins: [
    vue(),
    {
      name: 'html-transform',
      transformIndexHtml(html) {
        return html.replace(/<title>(.*?)<\/title>/, '<title>Quartz.Net Dashboard</title>')  // 頁面 title 修改標題
      }
    }
  ],
...
build 後檔案不產生雜湊值(Hash)
vue.config.js
transpileDependencies: true
vite.config.js
build: {
  rollupOptions: {
    output: {
      entryFileNames: 'assets/[name].js',
      chunkFileNames: 'assets/[name].js',
      assetFileNames: 'assets/[name].[ext]'
    }
  }
}
三﹑ package.json
vue cli
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
所以在 vue cli 要進行 debug 或 build 時的指令是
npm run serve
npm run build
vite
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
  },
進行 debug 或 build 的指令
npm run dev
npm run build
四﹑env 環境變數檔
在 vue cli 和 vite 都一樣可以建立 env 環境變檔, 但有一些地方有一些差異, 一般來說會建置類似以下的檔案
- .env:適用於所有環境
- .env.local:用於本地環境
- .env.development:用於開發環境
- .env.production:用於正式環境
 在每個檔案裏根據不同的環境設定環境變數的值
檔名
在 vue cli 設定 .env.local 這個檔案, 然後在 package.json 的 scripts 中加入
  "scripts": {
    ...
    "serve:local": "vue-cli-service serve --mode local",
    "build:local": "vue-cli-service build --mode local",
    ...
  },
在執行時可以以 npm run server:local 或 npm run build:local 做本地環境變數的執行或建置。
但是, 在 vite 不可以使用 .env.local 這個檔名, 如果像 vue cli 的方式使用﹐在執行 npm run build:local 會出現以下的錯誤
error during build:
Error: "local" cannot be used as a mode name because it conflicts with the .local postfix for .env files.
這是因為 Vite 使用 .local 後綴來處理本地環境變數檔案(例如 .env.local)。當你使用 --mode local 時,Vite 會嘗試加載 .env.local 檔案,但由於 local 是保留的後綴名稱,這會導致衝突。
所以在 Vite 就是避免使用 local 這個關鍵字, 可以將檔名改為 .env.devlocal, 然後在 package.json 中
  "scripts": {
    ...
    "dev:devlocal": "vite --mode devlocal",
    "build:devlocal": "vite build --mode devlocal",
    "preview:devlocal": "vite preview --mode devlocal"
  },
然後指令就是 npm run build:devlocal
環境變數的命名
以 .env.devlocal 為例
Vue CLI
- 變數名稱命名必須以 VUE_APP_為開頭
- 使用方式為 process.env.變數名稱
 例如:
Vite
- 變數名稱命必須以 VITE_為開頭
- 使用方式為 import.meta.env.變數名稱
 例如:
五﹑安裝其它套件
Vite 建立專案時不像 Vue CLI 會詢問而安裝一些相關套件﹐所以如果在 Vite 專案中有需要使用的話都要另外手動安裝, 手動安裝其實跟 Vue CLI 都相同, 這裏做個紀錄只是因為以下這些在過去Vue CLI 都在建置專案時都能選好後自動安裝而 Vite 沒有, 當然在 CLI 建置時沒有選也一樣的方式手動安裝
router
使用以下命令安裝 Vue Router
npm install vue-router@4
設置:
創建資料夾:在 src 資料夾下建立一個 router 資料夾, 在之下建立一個 index.js 檔案
配置 router:在 src/router/index.js 中設置 router
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue')
  }
]
const router = createRouter({
  history: createWebHistory(),
  routes
})
export default router
- 在 main.js 使用 router:在 src/man.js 中引入 vue router
Lint
使用以下命令安裝 ESLint
npm install eslint --save-dev
建立 .eslintrc.js 配置檔案
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
  ],
  parserOptions: {
    ecmaVersion: 12,
    sourceType: 'module',
  },
  plugins: [
    'vue',
  ],
  rules: {
    // 你的規則
  },
};
Sass
使用以下指令安裝
npm install sass
六﹑參考資料
ChatGPT
开始 | Vite 官方中文文档 (vitejs.dev)
配置 Vite | Vite 官方中文文档 (vitejs.dev)
Vite + Vue 3 第一個網站 - HackMD
前端黑洞計畫 (一) : 讓 Vite 來開啟你的Vue :: 2021 iThome 鐵人賽
為什麼前端不愛用 Webpack 了? Vite 簡介 | Vivian Yeh