跳至主要内容

[note] Vite & Vitest

TL;DR

$ npx vite --help

# 建立 vite 專案
$ npm create vite@latest # 等同於 npm exec create-vite@latest

# 等同於 npm exec create-vite@latest react-ts-vite --template react-ts
$ npm create vite@latest react-ts-vite -- --template react-ts

Cache

caching @ Vite > Dependency Pre-Bundling

File System Cache

Vite 預設會 cache 所有 pre-bundled 的套件到 node_modules/.vite 中,只有在下述檔案有變化時,才會重新執行 pre-build:

  • package.json 中的 dependencies 有改變
  • package-lock.jsonyarn.lock 這類檔案有改變
  • vite.config.js 中的相關欄位有變更

如果因為某些原因需要讓 vite 重新 bundle 這些 dependencies 的話,可以:

  • 在啟動專案時加上 --force
  • 或手動刪除 node_modules/.vite

Browser Cache

Vite 會透過 HTTP headers max-age 來促使瀏覽器做到 cache 的動作。有些情況下,如果你需要直接改 dependencies 的程式碼來 debug,你可以:

  • 在瀏覽器 Network 面板勾起 "disable cache"
  • 在啟動專案時加上 --force
  • 重新整理該頁面

Vitest

Config

global

預設的情況下, Vitest 並沒有暴露 API(例如,describetestit)到 global,所以一種是在使用到時手動 import:

// foo.test.js
import { describe, test, expect } from 'vitest';

另一種是在 vitest 的設定中,將 global 改成 true

// vitest.config.ts
/// <reference types="vitest" />

import { defineConfig } from 'vite'

export default defineConfig({
test: {
globals: true,
environment: 'jsdom',
},
})

Setup React Testing Library with Vitest

安裝所需套件

$ npm install --save-dev vitest jsdom
$ npm install --save-dev @testing-library/react @testing-library/jest-dom

設定 globals

官方文件

globals @ vitest

首先,如果不希望每次都要手動 import Jest API(例如,test, describe, it 等等),可以將設定檔中的 globals 設為 true

// vite.config.ts

/// <reference types="vitest" />
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: 'src/setupTests.ts',
},
});

如果要讓 TypeScript 也能吃到這個設定,需要在 tsconfig.json 中加上:

// tsconfig.json
{
"compilerOptions": {
"types": ["vitest/globals"]
}
}

設定 environments

vitest 的 config 中,可以將 environment 設定成 jsdom

// vite.config.ts
/// <reference types="vitest" />
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: 'src/setupTests.ts',
},
});

設定 setupFiles

這時候如果執行測試的話,會出現「Error: Invalid Chai property: toBeInTheDocument」的錯誤:

Setup React Testing Library with Vitest

要解決這個問題只需要測試的檔案中 import @testing-library/jest-dom 即可:

信息

/jest-dom 會擴充 Jest 提供的 matcher,讓我們可以使用 toBeInTheDocument 這個 matcher。

import { describe, expect, it } from 'vitest';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import App from './App';

describe('counter', () => {
it('counter existed in the DOM', () => {
render(<App />);
const button = screen.getByRole('button', {
name: /count is 0/i,
});
expect(button).toBeInTheDocument();
});
});

但每一次都需要額外 import 這個套件不只麻煩,還很容易忘記,所以比較好的方式是透過設定,讓測試執行時自動載入這個套件。

首先,建立在 setupTests.ts

// ./src/setupTests.ts
import '@testing-library/jest-dom';

接著在 vite.config.ts 中透過 setupFiles 讓測試執行時就會自動載入該套件,而不用每次都手動 import:

// vite.config.ts
/// <reference types="vitest" />
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: 'src/setupTests.ts',
},
});

如此就可以成功執行測試了:

Setup React Testing Library with Vitest

Giscus