describe:是用來將一至多組有相關的測試組合在一起的區塊。
text()& html()內容物
案例 text()& html()內容物 單元測試
1 | //html |
1 | //引入描述、它、期望 |
describe:是用來將一至多組有相關的測試組合在一起的區塊。
1 | //html |
1 | //引入描述、它、期望 |
1 | import { describe, it} from 'vitest' |
1 | <template> |
1 | /引入描述、它、期望 |
<div><b>classes:</b>語法查詢的話將得到一個陣列的結果</div>
<div>
1
wrapper.find('[data-test="wrap"]').classes()
</div>
</li>
<li><b>expect(value):</b>攥寫每一筆測試時都會使用 expect(value) 和匹配器 (matcher) 來斷言某個值,expect (value) 的參數 value 會是程式碼產生的值</li>
<li><b> toBe </b>是一個匹配器</li>
<li><b> html() </b>回傳元件的 HTML</li>
<li><b> toContain() </b>檢查一個字符串是否是另一個字符串的子字符串,也可檢查一個項目是否在 Array 中。</li>
<li><b> get() </b> get 方法來搜索現有元素:如果 get() 沒有找到目標元素,它會拋出錯誤並導致測試失敗。如果找到的話則會回傳一個 DOMWrapper。</li>
<li><b>find()</b>和 get() 很像,一樣是使用 Document.querySelector() 的語法,不過差別在於 find() 沒有找到目標元素時不會拋出錯誤。</li>
<li><b>exist()</b> 檢查元素是否存在。</li>
<li><b> text() </b> 回傳元素的文本內容 (text content)。</li>
<li><b>isVisible ()</b>專門用來檢查元素是否為隱藏的狀態:元素或元素的祖先中有 display: none、visibility: hidden、opacity:0 的樣式,收合的 <details> 標籤中,具有 hidden 屬性</li>
<li><b>trigger ()</b>可以用來觸發 DOM 事件,例如 click、submit 或 keyup 等操作,值得注意的是, trigger 回傳的是一個 Promise,也因此我使用了 async & await 的方式來等待 promise resolve。</li>
<li><b>emits()</b>事件通常是由子元件向父元件所觸發的</li>
<li><b>vm</b>是 VueWrapper 的一個屬性,我們可以透過 vm 來取得 Vue instance,如此一來就能再透過 vm 取得 count 變數了。</li>
<li><b>emitted() </b>emitted() 會回傳一個紀錄元件發出的所有事件的物件,其中也包含著 emit 的參數。</li>
<li><b>toHaveProperty()</b>jest 有提供一個 toHaveProperty 的匹配器 (matcher),可以用來檢查物件中是否存在某屬性。</li>
<li><b>toEqual()</b>匹配器會去比較物件的所有屬性或陣列的所有元素是否相等。</li>
mount的第二個參數是可以用來定義元件的狀態 (state) 配置,例如 props, data, attrs 等等,因此這次我們就傳入 data 覆蓋掉元件中的預設值。
1 | import { describe, it, expect } from 'vitest' |
1 | import { mount, shallowMount } from '@vue/test-utils' |
執行結果
Unit test透過 get() 或 find() 來尋找目標的元素,在元件內綁定元件
1 | import { mount } from '@vue/test-utils' |
1 | <template> |
測試=>輸入元素的值應該是 my@mail.com
1 | test('輸入元素的值應該是 my@mail.com', async () => { |
測試 =>設定值後,電子郵件的值應為 my@mail.com
1 | test('設定值後,電子郵件的值應為 my@mail.com', async () => { |
1 | <template> |
1 | <template> |
表單測試
Case 1
1 | test('填寫表單', async () => { |
Case 2
1 | test('提交表單', async () => { |
1 | import { ref, computed } from 'vue' |
1 | describe('Props & Computed', () => { |
Vite 安裝與環境變數設定
相容性說明
Vite 需要 Node.js 版本 18+。 20+。 但是,某些模板需要更高的 Node.js 版本才能運作,如果您的套件管理器發出警告,請升級。
1 | npm create vite-extra@latest 專案名稱 |
1 | cd vite-project |
專案架構
1 | ├── .vscode |
安裝完成
gitHub上的說明
gitHub上的說明(vite ^5.4.1”)
安裝 express 與nodemon concurrently
1 | npm install express |
gitHub上的說明:安裝 express 與nodemon concurrently
專案新增server/index.js
1 | import express from "express"; |
修改package.json設定檔,新增一個主檔案並將 dev 命令替換為以下內容
1 | "version": "1.0.1", |
這樣Vite伺服器和Nodemon就會並行運作。
運行來啟動伺服器
1 | npm run dev |
如果我們訪問http://localhost:3000/api/v1/hello
現在有一個前端和一個後端正在運行,但它們還沒有互相溝通
1 | { |
安裝ejs
1 | npm install ejs |
新增server/homepageRouter.js
1 | import express from "express"; |
homepageRouter.js
新增server/assetsRouter.js,靜態圖片
1 | import express from "express"; |
修改server/index.js
1 | import express from "express"; |
修改src/components/HelloWorld.vue
1 | <script setup lang="ts"> |
刪除index.html,在根目錄新增一個 views/index.html.ejs
1 | <!DOCTYPE html> |
1 | import { defineConfig } from "vite"; |
執行打包,
1 | npm run build |
產生dist後,在.vite將manifest.json移動到dist根目錄,並修改manifest.json
1 | { |
Vite 的Pwa功能是在web情況下,開發web就能製作成App的效果,不需要上架app store / google play 也不需要使用安裝 exe檔案,只需要連結就能增加的手機畫面,
Vite PWA
Vite 和生態系統的 PWA 整合零配置和與框架無關的 Vite PWA 插件
做好了網站以後,執行以下指令:
1 | npm i -D vite-plugin-pwa |
vite.config.js增加
1 | import { VitePWA } from "vite-plugin-pwa" |
安裝PWA 資產產生和圖像
1 | npm install --global vue-pwa-asset-generator |
執行指令
剛剛製作的icon路徑產生到public/img/icons檔案夾內
1 | //剛剛製作的icon路徑 =>(產生) => icons |
終端機回應:產生資料到/public/![]()
產生的檔案內會有一個manifest.json檔
index.html載入manifest.json
1 | <!doctype html> |
產生Bug
主要原因是位址路徑錯誤
manifest.json
注意:icons/src路徑必須正確
1 | { |
vite_pwa.js 這個檔案夾 不一定要使用
1 | self.addEventListener("notificationclick", function (event) { |
打包
1 | npm run build |
重新運行測試
1 | npm run dev |
畫面出現標示安裝
1.將你的前端程式碼上傳到伺服器上的某個目錄,例如 /var/www/mywebsite。
2.建立Nginx設定檔:Nginx的設定檔通常位於 /etc/nginx/ 目錄下,特定路徑可能會因伺服器的不同而略有不同。
在該目錄下,你通常會找到一個叫做 sites-available 的目錄
在這個目錄下,你可以為每個網站建立一個設定檔。例如,你可以建立一個新的設定文件,命名為 mywebsite:sudo nano /etc/nginx/sites-available/mywebsite
1 | server { |
應該替換為你的程式碼所在的目錄:/var/www/mywebsite
應該替換為你的網域或IP位址:your_domain_or_IP
listen:此配置意味著Nginx將監聽80端口,並為所有指向你的網域或IP位址的請求提供服務
Nginx將傳回404狀態碼:如果請求的檔案不存在,Nginx將傳回404狀態碼。
4.啟用網站
建立並編輯完設定檔後,你需要建立一個到 sites-enabled 目錄的符號連結來啟用你的網站:
1 | sudo ln -s /etc/nginx/sites-available/mywebsite /etc/nginx/sites-enabled/ |
5.檢查設定檔
重啟Nginx之前,檢查你的設定檔有沒有語法錯誤:
1 | sudo nginx -t |
如果沒有錯誤,你會看到類似這樣的輸出:
1 | nginx: configuration file /etc/nginx/nginx.conf test is successful |
6.重啟Nginx
需要重啟Nginx來讓你的設定生效:
1 | sudo service nginx restart |
前端頁面應該可以透過你的網域名稱或IP位址存取了。
注意,如果你的伺服器有防火牆,你可能需要設定防火牆來允許HTTP和HTTPS流量。
更完整的 Nginx 配置
首先,你需要為你的網域取得一個SSL證書,你可以使用Let’s Encrypt提供的免費證書。
設定檔可能如下:
1 | server { |
這只是一個基本的配置範例,你可以根據你的需求進行修改。
有許多其他的選項可以配置,例如負載平衡,
反向代理,HTTP/2支援等。
使用 Nginx 來做負載平衡的實作非常直接。以下是一個簡單的範例來說明如何設定 Nginx 來實現對多個伺服器的負載平衡。
假設你有兩個或更多的應用程式伺服器實例,它們分別託管在不同的 IP 位址或主機名稱下**。你可以在 Nginx 設定檔中設定一個 upstream 模組,然後在 server 模組中將請求反向代理到這個 upstream。 **
首先,你需要在你的 Nginx 設定檔(一般位於 /etc/nginx/nginx.conf 或 /etc/nginx/conf.d/ 目錄下的某個檔案)中定義一個 upstream。例如:
1 | http { |
在這個例子中,myapp 是你定義的 upstream 的名字,app1.example.com 和 app2.example.com 是你的應用程式伺服器的位址。
然後,在 server 模組中,你可以將來自客戶端的請求代理到這個 upstream:
1 | server { |
在這個範例中,所有來自客戶端的 HTTP 請求(即 :80 連接埠的請求)都會被 Nginx 轉送到定義的 upstream(即 myapp)。 Nginx 預設使用輪詢(round-robin)演算法將請求指派給 upstream 中的伺服器,你也可以設定其他的負載平衡演算法,如最少連接(least_conn)或 IP 雜湊(ip_hash)。
這樣,Nginx 就會把請求平衡地轉送到你的各個應用程式伺服器實例上,實現負載平衡。注意這個配置對於前端靜態頁面來說可能不太必要,因為靜態頁面通常不會對伺服器產生太大負載,但對於動態應用來說是非常有用的。
使用 Docker 來部署前端應用程式是一種很好的方式,因為它可以將你的應用程式及其依賴項打包到一個獨立、可移植的容器中,可以在任何安裝了 Docker 的環境中運行。
以下是使用 Docker 部署一個基本的靜態前端頁面的步驟:
1.建立 Dockerfile
在你的專案根目錄中,建立一個名為”Dockerfile”的檔案。這個檔案是用來定義你的 Docker 映像的,可以看作是一個自動化的腳本。以下是一個簡單的 Dockerfile 範例,其中使用了官方的 Nginx 映像來部署靜態頁面:
1 | # 使用官方的 Nginx 镜像 |
2.建置 Docker 映像
在專案根目錄下,你可以使用 docker build 指令來根據 Dockerfile 建立 Docker 映像:
1 | docker build -t my-frontend-app . |
其中,-t my-frontend-app 參數用於為您的 Docker 映像命名,. 指定了 Dockerfile 所在的位置(在這裡,它在目前目錄下)。
3:运行 Docker 容器
你现在可以使用 docker run 命令来运行你刚刚构建的 Docker 镜像:
1 | docker run -p 80:80 -d my-frontend-app |
參數指定了將容器的 80 端口映射到宿主機的 80 端口,d 參數指定了以後台模式運行容器。
現在你應該可以在你的瀏覽器中透過造訪 http://localhost 來查看你的前端頁面了。
如果你的前端應用更複雜,或者需要與後端服務進行交互,你可能需要進行更複雜的配置,例如使用 Docker Compose 來管理多個服務,或使用環境變數來配置你的應用程式。
負載平衡
如果你的前端應用使用 Docker 部署,有多種方式可以實現負載平衡。以下是一些常見的方法:
Docker Swarm 是 Docker 的原生叢集管理和編排工具。在 Swarm 叢集中,你可以建立一個服務,然後指定服務的副本數量。 Swarm 會自動在叢集的節點間分配這些副本,實現負載平衡。
以下是一個簡單的 Docker Swarm 服務建立指令:
1 | docker service create --name my-frontend-app --publish 80:80 --replicas 3 my-frontend-app |
在這個命令中,–name my-frontend-app 指定了服務的名稱,–publish 80:80 指定了將容器的80 端口映射到宿主機的80 端口,–replicas 3 指定了創建3 個副本,my-frontend-app 是你的Docker 映像的名稱。
2.使用 Kubernetes:
Kubernetes 是一個更強大的容器編排平台,它也支援負載平衡。在 Kubernetes 中,你可以建立一個 Deployment 和一個 Service,Kubernetes 會自動為你的應用提供負載平衡。
以下是一個簡單的 Kubernetes Deployment 和 Service 的定義:
1 | apiVersion: apps/v1 |
在這個定義中,Deployment 建立了 3 個前端應用的副本,Service 為這些副本提供了一個負載平衡器。
如果你的應用程式部署在雲端環境(如 AWS, Google Cloud, Azure 等),你可以使用雲端服務供應商的負載平衡服務。這些負載平衡服務通常提供了更強大的功能,例如自動擴縮容,健康檢查,SSL 終結等。
以上都是實現 Docker 負載平衡的一些方式,你可以根據你的特定需求和環境選擇最合適的方式。
PM2 主要用於管理和維護 Node.js 應用,但你也可以使用 PM2 來運行一個靜態伺服器,用來部署你的前端頁面。
透過使用像 http-server 這樣的簡單的靜態檔案伺服器來完成
1.安装 http-server
1 | npm install http-server --save |
2.建立一個 PM2 的設定文件
你需要建立一個 PM2 的設定文件,例如 ecosystem.config.js。
1 | module.exports = { |
3.使用 PM2 啟動你的前端頁面
利用 PM2 提供的特性,例如應用的自動重啟和負載平衡。
1 | pm2 start ecosystem.config.js |
http-server 是一個非常簡單的靜態檔案伺服器,
如果你需要更複雜的功能(例如SSL、反向代理等),你可能需要考慮使用更強大的伺服器軟體,例如Nginx 或Express .js。
| 技術 | 優點 | 缺點 | 出現時間 | 適合場景 | 不適合場景 |
|---|---|---|---|---|---|
| Nginx | 輕量級,高效能,可作為反向代理和負載平衡器 | 需要手動配置和管理 | 2004年 | 任何需要靜態頁面服務的項目 | 需要動態伺服器端渲染的項目 |
| PM2 Serve | 可以使用PM2來管理靜態服務程序 | 不包含反向代理或負載平衡器 | PM2:2014年 | 需簡單的靜態檔案服務 | 需複雜的HTTP請求處理或負載平衡的項目 |
| Docker | 容器化,跨平台 | 需要手動管理容器和映像 | 2013年 | 任何需要跨平台部署或以統一方式部署多種服務的項目 | 小規模或簡單的項目可能,
引入不必要的複雜性 |
| GitHub | Pages 免費,支援自訂域名,整合GitHub | 功能有限,僅支援靜態內容 | 2008 年 | 簡單的個人、專案或組織頁面 | 複雜的、需要後端的應用 |
| Netlify/Vercel | 提供自動部署,函數即服務等 | 免費版有一些限制 | Netlify:2014年, Vercel:2015年 |
靜態網站和Jamstack應用 | 大規模、複雜的後端應用 |
1 | fetch(url, options) |
在專案src目錄下新增request.js的文件並且 export
1 | export default { |
1 | <template> |
Unit Test官網
Unit Test官網
unit test VUE 3 Composition API methods?
方法 mount
import HelloWorld from ‘../HelloWorld.vue’
const wrapper = mount(HelloWorld, { props: { msg: ‘Hello Vitest’ } })
expect(1 + 1).toBe(2)
expect(wrapper.text()).toContain(‘Hello Vitest’)
1 | import { describe, it, expect } from 'vitest' |
Nav
1 | import { describe, it, expect } from 'vitest' |
form
describe
1 | import { describe, it} from 'vitest' |
允許巢狀的方式來建構測試
1 | describe('父層情境', () => { |
describe & it 輔助 API
1 | describe.only('測試情境 1', () => { /* */ }) |
1 | describe('測試情境 1', () => { |
skip
1 | describe.skip('測試情境 1', () => { |
todo
fails
1 | it.fails(`'1' + '1' should not to be '11'`, () => { |
1 | it(`'1' + '1' should not to be '11'`, () => { |
1 | beforeEach(() => { |
1 | const history = [] |
此時將透過 console.log(history) 查看並歸納整理就能得到以下結果:
1 | --- 進入測試程式碼本身的 Context |
1 | describe('', () => { |
1 | describe('', () => { |
1 | describe('', () => { |
Vite 需要Node.js版本 14.18+、16+。但是,某些模板需要更高的 Node.js 版本才能運作
官網
參考資料
1 | npm create vite-extra@latest 專案名稱 |
Streaming 串流媒體
Non-streaming非串流媒體

1 | ├── node_modules // 安裝的所有套件 |
main.ts
1 | import { createSSRApp } from 'vue' |
1 | "scripts": { |
啟動指令
1 | npm run build:client =>dist/client會多出這個資料夾 |
注意:server.js Constants 的port 如果重複就會出現白幕(完全沒顯示任何…,