Skip to content

Commit 4b946ca

Browse files
sheremet-vaeryue0220
andauthoredAug 1, 2023
feat: add preact example, remove optimizer experimental status, enable by default (#3854)
Co-authored-by: eryue0220 <eryue0220@gmail.com>
1 parent b092985 commit 4b946ca

21 files changed

+717
-133
lines changed
 

‎docs/config/index.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,17 @@ Directory to save cache files.
177177

178178
### deps
179179

180-
- **Type:** `{ experimentalOptimizer?, registerNodeLoader?, ... }`
180+
- **Type:** `{ optimizer?, registerNodeLoader?, ... }`
181181

182182
Handling for dependencies resolution.
183183

184-
#### deps.experimentalOptimizer
184+
#### deps.optimizer
185185

186186
- **Type:** `{ ssr?, web? }`
187-
- **Version:** Since Vitest 0.29.0
187+
- **Version:** Since Vitest 0.34.0
188188
- **See also:** [Dep Optimization Options](https://vitejs.dev/config/dep-optimization-options.html)
189189

190-
Enable dependency optimization. If you have a lot of tests, this might improve their performance.
190+
Enable dependency optimization. If you have a lot of tests, this might improve their performance. Before Vitest 0.34.0, it was named as `deps.experimentalOptimizer`.
191191

192192
When Vitest encounters the external library listed in `include`, it will be bundled into a single file using esbuild and imported as a whole module. This is good for several reasons:
193193

@@ -196,12 +196,12 @@ When Vitest encounters the external library listed in `include`, it will be bund
196196
- Your `alias` configuration is now respected inside bundled packages
197197
- Code in your tests is running closer to how it's running in the browser
198198

199-
Be aware that only packages in `deps.experimentalOptimizer?.[mode].include` option are bundled (some plugins populate this automatically, like Svelte). You can read more about available options in [Vite](https://vitejs.dev/config/dep-optimization-options.html) docs. By default, Vitest uses `experimentalOptimizer.web` for `jsdom` and `happy-dom` environments, and `experimentalOptimizer.ssr` for `node` and `edge` environments, but it is configurable by [`transformMode`](#transformmode).
199+
Be aware that only packages in `deps.optimizer?.[mode].include` option are bundled (some plugins populate this automatically, like Svelte). You can read more about available options in [Vite](https://vitejs.dev/config/dep-optimization-options.html) docs. By default, Vitest uses `optimizer.web` for `jsdom` and `happy-dom` environments, and `optimizer.ssr` for `node` and `edge` environments, but it is configurable by [`transformMode`](#transformmode).
200200

201-
This options also inherits your `optimizeDeps` configuration (for web Vitest will extend `optimizeDeps`, for ssr - `ssr.optimizeDeps`). If you redefine `include`/`exclude` option in `deps.experimentalOptimizer` it will extend your `optimizeDeps` when running tests. Vitest automatically removes the same options from `include`, if they are listed in `exclude`.
201+
This options also inherits your `optimizeDeps` configuration (for web Vitest will extend `optimizeDeps`, for ssr - `ssr.optimizeDeps`). If you redefine `include`/`exclude` option in `deps.optimizer` it will extend your `optimizeDeps` when running tests. Vitest automatically removes the same options from `include`, if they are listed in `exclude`.
202202

203203
::: tip
204-
You will not be able to edit your `node_modules` code for debugging, since the code is actually located in your `cacheDir` or `test.cache.dir` directory. If you want to debug with `console.log` statements, edit it directly or force rebundling with `deps.experimentalOptimizer?.[mode].force` option.
204+
You will not be able to edit your `node_modules` code for debugging, since the code is actually located in your `cacheDir` or `test.cache.dir` directory. If you want to debug with `console.log` statements, edit it directly or force rebundling with `deps.optimizer?.[mode].force` option.
205205
:::
206206

207207
#### deps.registerNodeLoader<NonProjectOption />
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Preact Example</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="src/main.tsx"></script>
11+
</body>
12+
</html>
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "@vitest/example-preact-testing-lib",
3+
"private": true,
4+
"scripts": {
5+
"build": "tsc && vite build",
6+
"coverage": "vitest run --coverage",
7+
"dev": "vite",
8+
"preview": "vite preview",
9+
"test": "vitest",
10+
"test:ui": "vitest --ui"
11+
},
12+
"dependencies": {
13+
"preact": "^10.15.1",
14+
"react": "npm:@preact/compat",
15+
"react-dom": "npm:@preact/compat",
16+
"react-router-dom": "^6.3.0"
17+
},
18+
"devDependencies": {
19+
"@preact/preset-vite": "^2.5.0",
20+
"@testing-library/jest-dom": "^5.16.4",
21+
"@testing-library/preact": "^3.2.3",
22+
"@vitest/ui": "latest",
23+
"less": "^4.1.3",
24+
"typescript": "^4.8.4",
25+
"vite": "latest",
26+
"vitest": "latest"
27+
}
28+
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.app {
2+
text-align: center;
3+
4+
header {
5+
display: flex;
6+
flex-direction: column;
7+
align-items: center;
8+
justify-content: center;
9+
min-height: 100vh;
10+
background-color: #282c34;
11+
font-size: calc(10px + 2vmin);
12+
color: white;
13+
14+
.app-link {
15+
color: white;
16+
text-decoration: none;
17+
18+
&:hover {
19+
color: #747bff;
20+
}
21+
}
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { fireEvent, render, screen } from '@testing-library/preact'
3+
import { BrowserRouter } from 'react-router-dom'
4+
5+
import App from './App'
6+
7+
describe('Preact Demo Test Suite', () => {
8+
it('basic', () => {
9+
render(<BrowserRouter><App /></BrowserRouter>)
10+
expect(screen.getByText(/Hello Vite & Preact!/i)).toBeInTheDocument()
11+
})
12+
13+
it('click event', async () => {
14+
render(<BrowserRouter><App /></BrowserRouter>)
15+
fireEvent.click(screen.getByRole('button'))
16+
expect(await screen.findByText(/count is: 1/i)).toBeInTheDocument()
17+
})
18+
})
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { useCount } from './hooks/useCount'
2+
import './App.less'
3+
4+
export default function App() {
5+
const { count, inc } = useCount()
6+
7+
return (
8+
<div class="app">
9+
<header>
10+
<h1>Hello Vite & Preact!</h1>
11+
<p>
12+
<button onClick={inc}>Count is: {count}</button>
13+
</p>
14+
<p>
15+
<a
16+
className="app-link"
17+
href="https://preactjs.com/"
18+
target="_blank"
19+
rel="noopener noreferrer"
20+
>
21+
Learn Preact
22+
</a>
23+
{' | '}
24+
<a
25+
className="app-link"
26+
href="https://vitejs.dev/guide/features.html"
27+
target="_blank"
28+
rel="noopener noreferrer"
29+
>
30+
Vite Docs
31+
</a>
32+
</p>
33+
</header>
34+
</div>
35+
)
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { act, renderHook } from '@testing-library/preact'
2+
import { useCount } from './useCount'
3+
4+
describe('useCount hook', () => {
5+
it('should increment', () => {
6+
const { result } = renderHook(() => useCount())
7+
act(() => {
8+
result.current.inc()
9+
})
10+
expect(result.current.count).toBe(1)
11+
})
12+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { useCallback, useState } from 'preact/hooks'
2+
3+
export function useCount() {
4+
const [count, setCount] = useState(0)
5+
const inc = useCallback(() => setCount(x => x + 1), [])
6+
return {
7+
count,
8+
inc,
9+
}
10+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
body {
2+
margin: 0;
3+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4+
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5+
sans-serif;
6+
-webkit-font-smoothing: antialiased;
7+
-moz-osx-font-smoothing: grayscale;
8+
}
9+
10+
code {
11+
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12+
monospace;
13+
}
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { render } from 'preact'
2+
import App from './App'
3+
import './main.less'
4+
5+
render(<App />, document.getElementById('root'))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { afterEach } from 'vitest'
2+
import { cleanup } from '@testing-library/preact'
3+
import '@testing-library/jest-dom'
4+
5+
afterEach(() => cleanup())
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ESNext",
4+
"useDefineForClassFields": true,
5+
"lib": ["DOM", "DOM.Iterable", "ESNext"],
6+
"allowJs": false,
7+
"skipLibCheck": true,
8+
"esModuleInterop": false,
9+
"allowSyntheticDefaultImports": true,
10+
"strict": true,
11+
"forceConsistentCasingInFileNames": true,
12+
"module": "ESNext",
13+
"moduleResolution": "Node",
14+
"resolveJsonModule": true,
15+
"isolatedModules": true,
16+
"noEmit": true,
17+
"jsx": "preserve",
18+
"jsxFactory": "h",
19+
"jsxFragmentFactory": "Fragment",
20+
"types": ["vitest/globals"]
21+
},
22+
"include": ["src"],
23+
"references": [{ "path": "./tsconfig.node.json" }]
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"compilerOptions": {
3+
"composite": true,
4+
"module": "ESNext",
5+
"moduleResolution": "Node",
6+
"allowSyntheticDefaultImports": true
7+
},
8+
"include": ["vite.config.ts"]
9+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/// <reference types="vitest" />
2+
/// <reference types="vite/client" />
3+
4+
import { defineConfig } from 'vite'
5+
import preact from '@preact/preset-vite'
6+
7+
export default defineConfig({
8+
plugins: [preact()],
9+
resolve: {
10+
// react-router-dom specifies "module" field in package.json for ESM entry
11+
// if it's not mapped, it uses the "main" field which is CommonJS that redirects to CJS preact
12+
mainFields: ['module'],
13+
},
14+
test: {
15+
globals: true,
16+
environment: 'jsdom',
17+
setupFiles: './test/setup.ts',
18+
css: true,
19+
},
20+
})

‎packages/vitest/src/node/create.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export async function createVitest(mode: VitestRunMode, options: UserConfig, vit
2828
const server = await createServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root })))
2929

3030
// optimizer needs .listen() to be called
31-
if (ctx.config.api?.port || ctx.config.deps?.experimentalOptimizer?.web?.enabled || ctx.config.deps?.experimentalOptimizer?.ssr?.enabled)
31+
if (ctx.config.api?.port || ctx.config.deps?.optimizer?.web?.enabled || ctx.config.deps?.optimizer?.ssr?.enabled)
3232
await server.listen()
3333
else
3434
await server.pluginContainer.buildStart({})

‎packages/vitest/src/node/plugins/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('t
109109
}
110110
}
111111

112-
const webOptimizer = resolveOptimizerConfig(testConfig.deps?.experimentalOptimizer?.web, viteConfig.optimizeDeps, testConfig)
113-
const ssrOptimizer = resolveOptimizerConfig(testConfig.deps?.experimentalOptimizer?.ssr, viteConfig.ssr?.optimizeDeps, testConfig)
112+
const webOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.web, viteConfig.optimizeDeps, testConfig)
113+
const ssrOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.ssr, viteConfig.ssr?.optimizeDeps, testConfig)
114114

115115
config.cacheDir = webOptimizer.cacheDir || ssrOptimizer.cacheDir || config.cacheDir
116116
config.optimizeDeps = webOptimizer.optimizeDeps

‎packages/vitest/src/node/plugins/utils.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ import { version as viteVersion } from 'vite'
33
import type { DepOptimizationOptions, UserConfig as ViteConfig } from 'vite'
44
import type { DepsOptimizationOptions, InlineConfig } from '../../types'
55

6-
export function resolveOptimizerConfig(testOptionc: DepsOptimizationOptions | undefined, viteOptions: DepOptimizationOptions | undefined, testConfig: InlineConfig) {
6+
export function resolveOptimizerConfig(_testOptions: DepsOptimizationOptions | undefined, viteOptions: DepOptimizationOptions | undefined, testConfig: InlineConfig) {
7+
const testOptions = _testOptions || {}
78
const newConfig: { cacheDir?: string; optimizeDeps: DepOptimizationOptions } = {} as any
89
const [major, minor] = viteVersion.split('.').map(Number)
910
const allowed = major >= 5 || (major === 4 && minor >= 3)
10-
if (!allowed && testOptionc?.enabled === true)
11+
if (!allowed && testOptions?.enabled === true)
1112
console.warn(`Vitest: "deps.optimizer" is only available in Vite >= 4.3.0, current Vite version: ${viteVersion}`)
12-
if (!allowed || testOptionc?.enabled !== true) {
13+
else
14+
// enable by default
15+
testOptions.enabled ??= true
16+
if (!allowed || testOptions?.enabled !== true) {
1317
newConfig.cacheDir = undefined
1418
newConfig.optimizeDeps = {
1519
// experimental in Vite >2.9.2, entries remains to help with older versions
@@ -22,12 +26,12 @@ export function resolveOptimizerConfig(testOptionc: DepsOptimizationOptions | un
2226
newConfig.cacheDir = cacheDir ?? 'node_modules/.vitest'
2327
newConfig.optimizeDeps = {
2428
...viteOptions,
25-
...testOptionc,
29+
...testOptions,
2630
noDiscovery: true,
2731
disabled: false,
2832
entries: [],
29-
exclude: ['vitest', ...builtinModules, ...(testOptionc.exclude || viteOptions?.exclude || [])],
30-
include: (testOptionc.include || viteOptions?.include || []).filter((n: string) => n !== 'vitest'),
33+
exclude: ['vitest', ...builtinModules, ...(testOptions.exclude || viteOptions?.exclude || [])],
34+
include: (testOptions.include || viteOptions?.include || []).filter((n: string) => n !== 'vitest'),
3135
}
3236
}
3337
return newConfig

‎packages/vitest/src/node/plugins/workspace.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ export function WorkspaceVitestPlugin(project: WorkspaceProject, options: Worksp
8989
}
9090
}
9191

92-
const webOptimizer = resolveOptimizerConfig(testConfig.deps?.experimentalOptimizer?.web, viteConfig.optimizeDeps, testConfig)
93-
const ssrOptimizer = resolveOptimizerConfig(testConfig.deps?.experimentalOptimizer?.ssr, viteConfig.ssr?.optimizeDeps, testConfig)
92+
const webOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.web, viteConfig.optimizeDeps, testConfig)
93+
const ssrOptimizer = resolveOptimizerConfig(testConfig.deps?.optimizer?.ssr, viteConfig.ssr?.optimizeDeps, testConfig)
9494

9595
config.cacheDir = webOptimizer.cacheDir || ssrOptimizer.cacheDir || config.cacheDir
9696
config.optimizeDeps = webOptimizer.optimizeDeps

‎packages/vitest/src/node/workspace.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export async function initializeProject(workspacePath: string | number, ctx: Vit
5252
const server = await createServer(config)
5353

5454
// optimizer needs .listen() to be called
55-
if (ctx.config.api?.port || project.config.deps?.experimentalOptimizer?.web?.enabled || project.config.deps?.experimentalOptimizer?.ssr?.enabled)
55+
if (ctx.config.api?.port || project.config.deps?.optimizer?.web?.enabled || project.config.deps?.optimizer?.ssr?.enabled)
5656
await server.listen()
5757
else
5858
await server.pluginContainer.buildStart({})
@@ -293,10 +293,10 @@ export class WorkspaceProject {
293293
...this.config.deps,
294294
optimizer: {
295295
web: {
296-
enabled: this.config.deps?.experimentalOptimizer?.web?.enabled ?? false,
296+
enabled: this.config.deps?.optimizer?.web?.enabled ?? false,
297297
},
298298
ssr: {
299-
enabled: this.config.deps?.experimentalOptimizer?.ssr?.enabled ?? false,
299+
enabled: this.config.deps?.optimizer?.ssr?.enabled ?? false,
300300
},
301301
},
302302
},

‎packages/vitest/src/types/config.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ interface SequenceOptions {
7777
}
7878

7979
export type DepsOptimizationOptions = Omit<DepOptimizationConfig, 'disabled' | 'noDiscovery'> & {
80-
enabled: boolean
80+
enabled?: boolean
8181
}
8282

8383
export interface TransformModePatterns {
@@ -102,7 +102,7 @@ interface DepsOptions {
102102
/**
103103
* Enable dependency optimization. This can improve the performance of your tests.
104104
*/
105-
experimentalOptimizer?: {
105+
optimizer?: {
106106
web?: DepsOptimizationOptions
107107
ssr?: DepsOptimizationOptions
108108
}

‎pnpm-lock.yaml

+475-110
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.