紀錄一下使用 vite.js 建立 vue3 練習專案的步驟
基礎語法及使用請參閱其他教學資源,此處僅簡單紀錄提示一些我覺得較為重要、容易忘記或者是方便複製貼上使用的部分,相對的 vue3 的練習主要放在專案內的 about
、monster
、teams
這三個路由,練習範例是依照udemy
課程下去改的,有興趣了解課程也可以參考一下我的文章學習紀錄-Vue - The Complete Guide (incl. Router & Composition API) (只是到今天我還沒看完就是了,但目前為止的感想是適合初學者,有中文字幕,買了不虧)
- vite 線上試用:StackBlitz
建立專案
# 新建專案
npm create vite@latest
練習專案目錄結構
- 練習範例程式碼 github:lab-vite-spa
路徑 | 說明 |
---|---|
/dist: | 編譯產出路徑 |
/src: | 前端原始碼路徑 |
/src/components: | 全站共用元件 |
/pages/*.vue: | 主要頁面元件 |
/pages/*/.vue: | 各頁面非公用元件 |
/src/router.js: | 路由設定 |
/src/App.vue: | 網站進入點 |
/vite.config.js: | vite 設定檔 |
路徑別名設定
- 專案原始碼路徑放置於專案根目錄下的
src
內,可依需要自行設定 - 前端編譯
production
時的產出路徑為/dist
resolve.alias
設定宣告了@
表示為src
,便於引用資源時不必再使用../../Home.vue
的相對路徑語法
// vite.config.js
import { resolve } from "path"
import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"
const root = resolve(__dirname, "src")
const outputDir = resolve(__dirname, "dist")
export default defineConfig({
root,
plugins: [vue()],
build: {
outDir: outputDir,
},
optimizeDeps: {
include: ["vue", "vue-router"],
},
resolve: {
alias: {
"@": resolve(__dirname, "src"),
},
},
})
前端路由設定 & 動態引用元件
- 透過
()=>import("@/pages/Home.vue")
即可動態引用元件,第一次使用該元件會另外發出請求取得元件 js 檔案;進入頁面不需要再將所有的資源全數載入,優化頁面速度 linkActiveClass
設定會在使用者點擊路由連結後,添加所設定的類別樣式名稱,此處設定會添加一個active
的樣式- 路由設定指定
name
可用於router-link
- 指定
HTML5 mode
處理前端路由 (createWebHistory()
)
// src/main.js
import { createApp } from "vue"
import App from "./App.vue"
import router from "@/router.js"
createApp(App).use(router).mount("#app")
// src/router.js
import { createRouter, createWebHistory } from "vue-router"
export const routes = [
{ name: "home", path: "/", component: () => import("@/pages/Home.vue") },
{ name: "about", path: "/about", component: () => import("@/pages/About.vue") },
]
const router = createRouter({
linkActiveClass: "active",
history: createWebHistory(),
routes,
})
export default router
導航條(路由連結範例)
basic sample
<router-link to="/">Go to Home</router-link> <router-link to="/about">Go to About</router-link>
navBar sample
<template>
<header>
<ul>
<li v-for="m in menu">
<router-link :to="m.to">{{ m.text }}</router-link>
</li>
</ul>
</header>
</template>
<script setup>
import { routes } from "@/router"
const menu = routes.filter((r) => r.name).map((r) => ({ to: r.path, text: r.name }))
</script>
透過 docker 佈署網站
npm ci
會依照package-lock.json
安裝套件,npm install
則是依照package.json
。- 在
docker
內複製檔案COPY
,會略過在.dockerignore
內的檔案 - 第二段
docker
命令在建構production
的時候,是將第一段的編譯成果,複製到nginx
的預設網站目錄下 nginx
設定檔也從專案目錄複製到image
內的nginx
設定目錄下,請特別注意此處設定檔spa.conf
的編碼應為ASCII
,不要用UTF8
.dockerignore
.dockerignore
node_modules
dist
.vscode
.run
.idea
.git
README.md
Dockerfile
FROM node:alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine as production-build
COPY --from=builder /app/dist /usr/share/nginx/html
COPY ./.nginx/spa.conf /etc/nginx/conf.d/
docker cli commands
# build docker image
docker build -t lab-vite-spa .
# create container
docker run -d --name=lab-vite-spa -p 80:80 lab-vite-spa
nginx 設定
開發階段採用 npm run dev
不會發現,但若將程式碼佈署於 IIS
就會發現無法正確的顯示畫面,因為在重新整理過後,IIS
接收到的網址請求的資源是不存在的,此時應該是要吃首頁的路由設定。IIS
可以透過 UrlReWrite
處理;若佈署於 linux
則可以利用 nginx
解決,請參閱下方設定檔內容
# /etc/nginx/conf.d/spa.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
root /usr/share/nginx/html;
index index.html;
# server_name you.server.com;
location / {
try_files $uri $uri/ @rewrites;
}
location @rewrites {
rewrite ^(.+)$ /index.html last;
}
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
# Some basic cache-control for static files to be sent to the browser
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
結論
這篇主要應該都不是在說 vue3、或 composition API 怎麼寫,記錄下來的重點反而都比較偏向佈署、開發過程。寫這一篇之前其實我也寫了 MPA,就是因為原始需求是前後端整合開發,到後面發現分離會比較好,而分離之後採用MPA也難以達成需求,也因此才會有 SPA + 動態載入的練習 PoC,目前這樣的開發配置是我覺得很不錯的,比起以往前後端混合,利用 webpack 編譯,每改一次都要等編譯很久,希望之後也能慢慢應用在工作上