[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

refactor(browser): move client code into src (#2367)

* fix: refactor browser package

* chore:fix CI

* chore: move public folder inside src/client

* chore: revert lock file

* chore: .

authored by

Joaquín Sánchez and committed by
GitHub
(Nov 23, 2022, 4:27 PM +0100) aa6ee0f9 4b21c595

+228 -228
+3 -3
pnpm-lock.yaml
··· 6935 6935 dev: true 6936 6936 6937 6937 /@types/form-data/0.0.33: 6938 - resolution: {integrity: sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=} 6938 + resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} 6939 6939 dependencies: 6940 6940 '@types/node': 18.11.9 6941 6941 dev: true ··· 7925 7925 dependencies: 7926 7926 '@volar/code-gen': 0.40.13 7927 7927 '@volar/source-map': 0.40.13 7928 - '@vue/compiler-core': 3.2.41 7928 + '@vue/compiler-core': 3.2.45 7929 7929 '@vue/compiler-dom': 3.2.45 7930 7930 '@vue/compiler-sfc': 3.2.45 7931 - '@vue/reactivity': 3.2.41 7931 + '@vue/reactivity': 3.2.45 7932 7932 '@vue/shared': 3.2.45 7933 7933 dev: true 7934 7934
+1 -1
tsconfig.json
··· 16 16 "paths": { 17 17 "@vitest/ws-client": ["./packages/ws-client/src/index.ts"], 18 18 "@vitest/ui": ["./packages/ui/node/index.ts"], 19 - "@vitest/browser": ["./packages/browser/node/index.ts"], 19 + "@vitest/browser": ["./packages/browser/src/node/index.ts"], 20 20 "#types": ["./packages/vitest/src/index.ts"], 21 21 "~/*": ["./packages/ui/client/*"], 22 22 "vitest": ["./packages/vitest/src/index.ts"],
-29
packages/browser/index.html
··· 1 - <!DOCTYPE html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="UTF-8" /> 5 - <link rel="icon" href="/favicon.svg" type="image/svg+xml"> 6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 - <title>Vitest Browser Runner</title> 8 - <style> 9 - html { 10 - overflow: hidden; 11 - padding: 0; 12 - margin: 0; 13 - } 14 - body { 15 - padding: 0; 16 - margin: 0; 17 - } 18 - #vitest-ui { 19 - width: 100vw; 20 - height: 100vh; 21 - border: none; 22 - } 23 - </style> 24 - </head> 25 - <body> 26 - <iframe id="vitest-ui" src=""></iframe> 27 - <script type="module" src="./client/main.ts"></script> 28 - </body> 29 - </html>
+2 -2
packages/browser/package.json
··· 25 25 ], 26 26 "scripts": { 27 27 "build": "rimraf dist && pnpm build:node && pnpm build:client && pnpm copy", 28 - "build:client": "vite build", 28 + "build:client": "vite build src/client", 29 29 "build:node": "rollup -c", 30 - "dev:client": "vite build --watch", 30 + "dev:client": "vite build src/client --watch", 31 31 "dev:node": "rollup -c --watch --watch.include=node", 32 32 "dev": "rimraf dist && run-p dev:node dev:client", 33 33 "copy": "esno scripts/copy-ui-to-browser.ts",
+2 -2
packages/browser/rollup.config.js
··· 29 29 export default () => [ 30 30 { 31 31 input: [ 32 - './node/index.ts', 32 + './src/node/index.ts', 33 33 ], 34 34 output: { 35 35 dir: 'dist', ··· 39 39 plugins, 40 40 }, 41 41 { 42 - input: './node/index.ts', 42 + input: './src/node/index.ts', 43 43 output: { 44 44 file: 'dist/index.d.ts', 45 45 format: 'esm',
-12
packages/browser/vite.config.ts
··· 1 - import { defineConfig } from 'vite' 2 - 3 - export default defineConfig({ 4 - server: { 5 - watch: { ignored: ['**/**'] }, 6 - }, 7 - build: { 8 - minify: false, 9 - outDir: './dist/client', 10 - emptyOutDir: false, 11 - }, 12 - })
-88
packages/browser/client/main.ts
··· 1 - import type { VitestClient } from '@vitest/ws-client' 2 - import { createClient } from '@vitest/ws-client' 3 - // eslint-disable-next-line no-restricted-imports 4 - import type { ResolvedConfig } from 'vitest' 5 - 6 - // @ts-expect-error mocking some node apis 7 - globalThis.process = { env: {}, argv: [], stdout: { write: () => {} } } 8 - globalThis.global = globalThis 9 - 10 - export const PORT = import.meta.hot ? '51204' : location.port 11 - export const HOST = [location.hostname, PORT].filter(Boolean).join(':') 12 - export const ENTRY_URL = `${ 13 - location.protocol === 'https:' ? 'wss:' : 'ws:' 14 - }//${HOST}/__vitest_api__` 15 - 16 - let config: ResolvedConfig | undefined 17 - const browserHashMap = new Map<string, string>() 18 - 19 - export const client = createClient(ENTRY_URL, { 20 - handlers: { 21 - async onPathsCollected(paths) { 22 - if (!paths) 23 - return 24 - 25 - // const config = __vitest_worker__.config 26 - const now = `${new Date().getTime()}` 27 - paths.forEach((i) => { 28 - browserHashMap.set(i, now) 29 - }) 30 - 31 - await runTests(paths, config, client) 32 - }, 33 - }, 34 - }) 35 - 36 - const ws = client.ws 37 - 38 - async function loadConfig() { 39 - let retries = 5 40 - do { 41 - try { 42 - await new Promise(resolve => setTimeout(resolve, 150)) 43 - config = await client.rpc.getConfig() 44 - return 45 - } 46 - catch (_) { 47 - // just ignore 48 - } 49 - } 50 - while (--retries > 0) 51 - 52 - throw new Error('cannot load configuration after 5 retries') 53 - } 54 - 55 - ws.addEventListener('open', async () => { 56 - await loadConfig() 57 - 58 - // @ts-expect-error mocking vitest apis 59 - globalThis.__vitest_worker__ = { 60 - config, 61 - browserHashMap, 62 - rpc: client.rpc, 63 - } 64 - 65 - // @ts-expect-error mocking vitest apis 66 - globalThis.__vitest_mocker__ = {} 67 - const paths = await client.rpc.getPaths() 68 - 69 - const now = `${new Date().getTime()}` 70 - paths.forEach(i => browserHashMap.set(i, now)) 71 - 72 - const iFrame = document.getElementById('vitest-ui') as HTMLIFrameElement 73 - iFrame.setAttribute('src', '/__vitest__/') 74 - 75 - await runTests(paths, config, client) 76 - }) 77 - 78 - async function runTests(paths: string[], config: any, client: VitestClient) { 79 - const name = '/__vitest_index__' 80 - const { startTests, setupGlobalEnv } = (await import(name)) as unknown as typeof import('vitest/browser') 81 - 82 - await setupGlobalEnv(config as any) 83 - 84 - await startTests(paths, config as any) 85 - 86 - await client.rpc.onFinished() 87 - await client.rpc.onWatcherStart() 88 - }
-86
packages/browser/node/index.ts
··· 1 - import { fileURLToPath } from 'url' 2 - // eslint-disable-next-line no-restricted-imports 3 - import { resolve } from 'path' 4 - import { builtinModules } from 'module' 5 - import { polyfillPath } from 'modern-node-polyfills' 6 - import sirv from 'sirv' 7 - import type { Plugin } from 'vite' 8 - import { resolvePath } from 'mlly' 9 - 10 - const stubs = [ 11 - 'fs', 12 - 'local-pkg', 13 - 'module', 14 - 'noop', 15 - 'perf_hooks', 16 - 'console', 17 - ] 18 - 19 - const polyfills = [ 20 - 'util', 21 - 'tty', 22 - 'process', 23 - 'path', 24 - 'buffer', 25 - ] 26 - 27 - export default (base = '/'): Plugin[] => { 28 - const pkgRoot = resolve(fileURLToPath(import.meta.url), '../..') 29 - const distRoot = resolve(pkgRoot, 'dist') 30 - 31 - return [ 32 - { 33 - enforce: 'pre', 34 - name: 'vitest:browser', 35 - async resolveId(id, _, ctx) { 36 - if (ctx.ssr) 37 - return 38 - 39 - if (id === '/__vitest_index__') { 40 - const result = await resolvePath('vitest/browser') 41 - return result 42 - } 43 - 44 - if (stubs.includes(id)) 45 - return resolve(pkgRoot, 'stubs', id) 46 - 47 - if (polyfills.includes(id)) 48 - return polyfillPath(normalizeId(id)) 49 - 50 - return null 51 - }, 52 - async configureServer(server) { 53 - server.middlewares.use( 54 - base, 55 - sirv(resolve(distRoot, 'client'), { 56 - single: false, 57 - dev: true, 58 - }), 59 - ) 60 - }, 61 - }, 62 - { 63 - name: 'modern-node-polyfills', 64 - async resolveId(id, _, ctx) { 65 - if (ctx.ssr || !builtinModules.includes(id)) 66 - return 67 - 68 - id = normalizeId(id) 69 - return { id: await polyfillPath(id), moduleSideEffects: false } 70 - }, 71 - }, 72 - ] 73 - } 74 - 75 - function normalizeId(id: string, base?: string): string { 76 - if (base && id.startsWith(base)) 77 - id = `/${id.slice(base.length)}` 78 - 79 - return id 80 - .replace(/^\/@id\/__x00__/, '\0') // virtual modules start with `\0` 81 - .replace(/^\/@id\//, '') 82 - .replace(/^__vite-browser-external:/, '') 83 - .replace(/^node:/, '') 84 - .replace(/[?&]v=\w+/, '?') // remove ?v= query 85 - .replace(/\?$/, '') // remove end query mark 86 - }
-5
packages/browser/public/favicon.svg
··· 1 - <svg width="165" height="165" viewBox="0 0 165 165" fill="none" xmlns="http://www.w3.org/2000/svg"> 2 - <path d="M120.831 57.2543L84.693 109.505C84.3099 110.059 83.7558 110.474 83.1148 110.687C82.4738 110.9 81.7809 110.898 81.1412 110.684C80.5015 110.469 79.95 110.052 79.5702 109.497C79.1905 108.941 79.0032 108.277 79.037 107.606L80.4833 78.7582L57.1343 73.8064C56.6353 73.7007 56.1704 73.474 55.7807 73.1465C55.391 72.8191 55.0885 72.4009 54.9001 71.929C54.7117 71.4571 54.6432 70.9461 54.7006 70.4412C54.758 69.9364 54.9395 69.4532 55.2291 69.0345L91.3675 16.7837C91.7507 16.2294 92.3048 15.8145 92.9458 15.6018C93.5869 15.3891 94.2798 15.3902 94.9196 15.6051C95.5593 15.8199 96.1109 16.2367 96.4906 16.7923C96.8703 17.3478 97.0575 18.0117 97.0236 18.6833L95.5773 47.5314L118.926 52.4828C119.425 52.5885 119.89 52.8152 120.28 53.1426C120.67 53.4701 120.972 53.8883 121.16 54.3602C121.349 54.8321 121.417 55.3431 121.36 55.8479C121.303 56.3528 121.121 56.836 120.831 57.2547L120.831 57.2543Z" fill="#FCC72B"/> 3 - <path d="M82.9866 153.343C82.0254 153.344 81.0735 153.156 80.1855 152.788C79.2975 152.42 78.4909 151.88 77.8122 151.2L43.6658 117.056C42.2998 115.683 41.5341 113.824 41.5366 111.887C41.5392 109.95 42.3098 108.092 43.6796 106.723C45.0493 105.353 46.9064 104.582 48.8435 104.579C50.7807 104.577 52.6399 105.342 54.0134 106.708L82.9866 135.678L146.105 72.5626C147.481 71.2088 149.336 70.4536 151.266 70.4615C153.197 70.4693 155.046 71.2396 156.41 72.6045C157.775 73.9695 158.546 75.8184 158.554 77.7487C158.561 79.679 157.806 81.5342 156.452 82.9101L88.1597 151.2C87.4811 151.881 86.6747 152.42 85.7869 152.788C84.8992 153.156 83.9475 153.344 82.9866 153.343Z" fill="#729B1B"/> 4 - <path d="M82.9572 153.343C83.9184 153.344 84.8703 153.156 85.7583 152.788C86.6463 152.42 87.4528 151.88 88.1316 151.2L122.278 117.056C123.644 115.683 124.41 113.824 124.407 111.887C124.405 109.95 123.634 108.092 122.264 106.723C120.894 105.353 119.037 104.582 117.1 104.579C115.163 104.577 113.304 105.342 111.93 106.708L82.9572 135.678L19.8389 72.5626C18.4629 71.2088 16.6077 70.4536 14.6775 70.4615C12.7472 70.4693 10.8982 71.2396 9.53331 72.6045C8.16839 73.9695 7.39811 75.8184 7.39025 77.7487C7.38239 79.679 8.13759 81.5342 9.49135 82.9101L77.784 151.2C78.4627 151.881 79.2691 152.42 80.1568 152.788C81.0446 153.156 81.9963 153.344 82.9572 153.343Z" fill="#729B1B" fill-opacity="0.5"/> 5 - </svg>
+29
packages/browser/src/client/index.html
··· 1 + <!DOCTYPE html> 2 + <html lang="en"> 3 + <head> 4 + <meta charset="UTF-8" /> 5 + <link rel="icon" href="/favicon.svg" type="image/svg+xml"> 6 + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 + <title>Vitest Browser Runner</title> 8 + <style> 9 + html { 10 + overflow: hidden; 11 + padding: 0; 12 + margin: 0; 13 + } 14 + body { 15 + padding: 0; 16 + margin: 0; 17 + } 18 + #vitest-ui { 19 + width: 100vw; 20 + height: 100vh; 21 + border: none; 22 + } 23 + </style> 24 + </head> 25 + <body> 26 + <iframe id="vitest-ui" src=""></iframe> 27 + <script type="module" src="/main.ts"></script> 28 + </body> 29 + </html>
+88
packages/browser/src/client/main.ts
··· 1 + import type { VitestClient } from '@vitest/ws-client' 2 + import { createClient } from '@vitest/ws-client' 3 + // eslint-disable-next-line no-restricted-imports 4 + import type { ResolvedConfig } from 'vitest' 5 + 6 + // @ts-expect-error mocking some node apis 7 + globalThis.process = { env: {}, argv: [], stdout: { write: () => {} } } 8 + globalThis.global = globalThis 9 + 10 + export const PORT = import.meta.hot ? '51204' : location.port 11 + export const HOST = [location.hostname, PORT].filter(Boolean).join(':') 12 + export const ENTRY_URL = `${ 13 + location.protocol === 'https:' ? 'wss:' : 'ws:' 14 + }//${HOST}/__vitest_api__` 15 + 16 + let config: ResolvedConfig | undefined 17 + const browserHashMap = new Map<string, string>() 18 + 19 + export const client = createClient(ENTRY_URL, { 20 + handlers: { 21 + async onPathsCollected(paths) { 22 + if (!paths) 23 + return 24 + 25 + // const config = __vitest_worker__.config 26 + const now = `${new Date().getTime()}` 27 + paths.forEach((i) => { 28 + browserHashMap.set(i, now) 29 + }) 30 + 31 + await runTests(paths, config, client) 32 + }, 33 + }, 34 + }) 35 + 36 + const ws = client.ws 37 + 38 + async function loadConfig() { 39 + let retries = 5 40 + do { 41 + try { 42 + await new Promise(resolve => setTimeout(resolve, 150)) 43 + config = await client.rpc.getConfig() 44 + return 45 + } 46 + catch (_) { 47 + // just ignore 48 + } 49 + } 50 + while (--retries > 0) 51 + 52 + throw new Error('cannot load configuration after 5 retries') 53 + } 54 + 55 + ws.addEventListener('open', async () => { 56 + await loadConfig() 57 + 58 + // @ts-expect-error mocking vitest apis 59 + globalThis.__vitest_worker__ = { 60 + config, 61 + browserHashMap, 62 + rpc: client.rpc, 63 + } 64 + 65 + // @ts-expect-error mocking vitest apis 66 + globalThis.__vitest_mocker__ = {} 67 + const paths = await client.rpc.getPaths() 68 + 69 + const now = `${new Date().getTime()}` 70 + paths.forEach(i => browserHashMap.set(i, now)) 71 + 72 + const iFrame = document.getElementById('vitest-ui') as HTMLIFrameElement 73 + iFrame.setAttribute('src', '/__vitest__/') 74 + 75 + await runTests(paths, config, client) 76 + }) 77 + 78 + async function runTests(paths: string[], config: any, client: VitestClient) { 79 + const name = '/__vitest_index__' 80 + const { startTests, setupGlobalEnv } = (await import(name)) as unknown as typeof import('vitest/browser') 81 + 82 + await setupGlobalEnv(config as any) 83 + 84 + await startTests(paths, config as any) 85 + 86 + await client.rpc.onFinished() 87 + await client.rpc.onWatcherStart() 88 + }
+12
packages/browser/src/client/vite.config.ts
··· 1 + import { defineConfig } from 'vite' 2 + 3 + export default defineConfig({ 4 + server: { 5 + watch: { ignored: ['**/**'] }, 6 + }, 7 + build: { 8 + minify: false, 9 + outDir: '../../dist/client', 10 + emptyOutDir: false, 11 + }, 12 + })
+86
packages/browser/src/node/index.ts
··· 1 + import { fileURLToPath } from 'url' 2 + // eslint-disable-next-line no-restricted-imports 3 + import { resolve } from 'path' 4 + import { builtinModules } from 'module' 5 + import { polyfillPath } from 'modern-node-polyfills' 6 + import sirv from 'sirv' 7 + import type { Plugin } from 'vite' 8 + import { resolvePath } from 'mlly' 9 + 10 + const stubs = [ 11 + 'fs', 12 + 'local-pkg', 13 + 'module', 14 + 'noop', 15 + 'perf_hooks', 16 + 'console', 17 + ] 18 + 19 + const polyfills = [ 20 + 'util', 21 + 'tty', 22 + 'process', 23 + 'path', 24 + 'buffer', 25 + ] 26 + 27 + export default (base = '/'): Plugin[] => { 28 + const pkgRoot = resolve(fileURLToPath(import.meta.url), '../..') 29 + const distRoot = resolve(pkgRoot, 'dist') 30 + 31 + return [ 32 + { 33 + enforce: 'pre', 34 + name: 'vitest:browser', 35 + async resolveId(id, _, ctx) { 36 + if (ctx.ssr) 37 + return 38 + 39 + if (id === '/__vitest_index__') { 40 + const result = await resolvePath('vitest/browser') 41 + return result 42 + } 43 + 44 + if (stubs.includes(id)) 45 + return resolve(pkgRoot, 'stubs', id) 46 + 47 + if (polyfills.includes(id)) 48 + return polyfillPath(normalizeId(id)) 49 + 50 + return null 51 + }, 52 + async configureServer(server) { 53 + server.middlewares.use( 54 + base, 55 + sirv(resolve(distRoot, 'client'), { 56 + single: false, 57 + dev: true, 58 + }), 59 + ) 60 + }, 61 + }, 62 + { 63 + name: 'modern-node-polyfills', 64 + async resolveId(id, _, ctx) { 65 + if (ctx.ssr || !builtinModules.includes(id)) 66 + return 67 + 68 + id = normalizeId(id) 69 + return { id: await polyfillPath(id), moduleSideEffects: false } 70 + }, 71 + }, 72 + ] 73 + } 74 + 75 + function normalizeId(id: string, base?: string): string { 76 + if (base && id.startsWith(base)) 77 + id = `/${id.slice(base.length)}` 78 + 79 + return id 80 + .replace(/^\/@id\/__x00__/, '\0') // virtual modules start with `\0` 81 + .replace(/^\/@id\//, '') 82 + .replace(/^__vite-browser-external:/, '') 83 + .replace(/^node:/, '') 84 + .replace(/[?&]v=\w+/, '?') // remove ?v= query 85 + .replace(/\?$/, '') // remove end query mark 86 + }
+5
packages/browser/src/client/public/favicon.svg
··· 1 + <svg width="165" height="165" viewBox="0 0 165 165" fill="none" xmlns="http://www.w3.org/2000/svg"> 2 + <path d="M120.831 57.2543L84.693 109.505C84.3099 110.059 83.7558 110.474 83.1148 110.687C82.4738 110.9 81.7809 110.898 81.1412 110.684C80.5015 110.469 79.95 110.052 79.5702 109.497C79.1905 108.941 79.0032 108.277 79.037 107.606L80.4833 78.7582L57.1343 73.8064C56.6353 73.7007 56.1704 73.474 55.7807 73.1465C55.391 72.8191 55.0885 72.4009 54.9001 71.929C54.7117 71.4571 54.6432 70.9461 54.7006 70.4412C54.758 69.9364 54.9395 69.4532 55.2291 69.0345L91.3675 16.7837C91.7507 16.2294 92.3048 15.8145 92.9458 15.6018C93.5869 15.3891 94.2798 15.3902 94.9196 15.6051C95.5593 15.8199 96.1109 16.2367 96.4906 16.7923C96.8703 17.3478 97.0575 18.0117 97.0236 18.6833L95.5773 47.5314L118.926 52.4828C119.425 52.5885 119.89 52.8152 120.28 53.1426C120.67 53.4701 120.972 53.8883 121.16 54.3602C121.349 54.8321 121.417 55.3431 121.36 55.8479C121.303 56.3528 121.121 56.836 120.831 57.2547L120.831 57.2543Z" fill="#FCC72B"/> 3 + <path d="M82.9866 153.343C82.0254 153.344 81.0735 153.156 80.1855 152.788C79.2975 152.42 78.4909 151.88 77.8122 151.2L43.6658 117.056C42.2998 115.683 41.5341 113.824 41.5366 111.887C41.5392 109.95 42.3098 108.092 43.6796 106.723C45.0493 105.353 46.9064 104.582 48.8435 104.579C50.7807 104.577 52.6399 105.342 54.0134 106.708L82.9866 135.678L146.105 72.5626C147.481 71.2088 149.336 70.4536 151.266 70.4615C153.197 70.4693 155.046 71.2396 156.41 72.6045C157.775 73.9695 158.546 75.8184 158.554 77.7487C158.561 79.679 157.806 81.5342 156.452 82.9101L88.1597 151.2C87.4811 151.881 86.6747 152.42 85.7869 152.788C84.8992 153.156 83.9475 153.344 82.9866 153.343Z" fill="#729B1B"/> 4 + <path d="M82.9572 153.343C83.9184 153.344 84.8703 153.156 85.7583 152.788C86.6463 152.42 87.4528 151.88 88.1316 151.2L122.278 117.056C123.644 115.683 124.41 113.824 124.407 111.887C124.405 109.95 123.634 108.092 122.264 106.723C120.894 105.353 119.037 104.582 117.1 104.579C115.163 104.577 113.304 105.342 111.93 106.708L82.9572 135.678L19.8389 72.5626C18.4629 71.2088 16.6077 70.4536 14.6775 70.4615C12.7472 70.4693 10.8982 71.2396 9.53331 72.6045C8.16839 73.9695 7.39811 75.8184 7.39025 77.7487C7.38239 79.679 8.13759 81.5342 9.49135 82.9101L77.784 151.2C78.4627 151.881 79.2691 152.42 80.1568 152.788C81.0446 153.156 81.9963 153.344 82.9572 153.343Z" fill="#729B1B" fill-opacity="0.5"/> 5 + </svg>