mirror of
https://github.com/hanzoai/vitest.git
synced 2026-09-24 17:04:25 +00:00
142 lines
4.4 KiB
TypeScript
142 lines
4.4 KiB
TypeScript
import type { Plugin } from 'vite'
|
|
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import Vue from '@vitejs/plugin-vue'
|
|
import { resolve } from 'pathe'
|
|
import { presetAttributify, presetIcons, presetWind3, transformerDirectives } from 'unocss'
|
|
import Unocss from 'unocss/vite'
|
|
import { defineConfig } from 'vite'
|
|
import { resolveApiToken } from '../vitest/src/node/config/apiToken'
|
|
|
|
export default defineConfig({
|
|
base: './',
|
|
resolve: {
|
|
// TODO: keep manual alias for vite 7 CI
|
|
// tsconfigPaths: true,
|
|
alias: {
|
|
'~/': `${resolve(import.meta.dirname, 'client')}/`,
|
|
},
|
|
},
|
|
plugins: [
|
|
Vue(),
|
|
Unocss({
|
|
presets: [presetWind3(), presetAttributify(), presetIcons()],
|
|
content: {
|
|
pipeline: {
|
|
include: [
|
|
// by default .ts is excluded
|
|
/\/client\/.*\.(ts|vue)($|\?)/,
|
|
],
|
|
},
|
|
},
|
|
shortcuts: {
|
|
'bg-base': 'bg-white dark:bg-[#111]',
|
|
'bg-overlay': 'bg-[#eee]:50 dark:bg-[#222]:50',
|
|
'bg-header': 'bg-gray-500:5',
|
|
'bg-active': 'bg-gray-500:8',
|
|
'bg-hover': 'bg-gray-500:20',
|
|
'border-base': 'border-gray-500:10',
|
|
'focus-base': 'border-gray-500 dark:border-gray-400',
|
|
'highlight': 'bg-[#eab306] text-[#323238] dark:bg-[#323238] dark:text-[#eab306]',
|
|
|
|
'tab-button': 'font-light op50 hover:op80 h-full px-4',
|
|
'tab-button-active': 'op100 bg-gray-500:10',
|
|
},
|
|
transformers: [
|
|
transformerDirectives(),
|
|
],
|
|
safelist: 'absolute origin-top mt-[8px]'.split(' '),
|
|
}),
|
|
process.env.HTML_REPORT_DIR
|
|
? devHtmlReportPlugin({ htmlDir: process.env.HTML_REPORT_DIR })
|
|
: devUiScriptPlugin(),
|
|
{
|
|
// workaround `crossorigin` issues on some browsers
|
|
// https://github.com/vitejs/vite/issues/6648
|
|
name: 'no-crossorigin-for-same-assets',
|
|
apply: 'build',
|
|
transformIndexHtml(html) {
|
|
return html
|
|
.replace('crossorigin src="./assets/', 'src="./assets/')
|
|
.replace('crossorigin href="./assets/', 'href="./assets/')
|
|
},
|
|
},
|
|
],
|
|
build: {
|
|
outDir: './dist/client',
|
|
},
|
|
})
|
|
|
|
function devUiScriptPlugin(): Plugin {
|
|
const BROWSER_SCRIPT_RE = /<script type="module">([\s\S]*?window\.__vitest_browser_runner__\s*=\s*\{[\s\S]*?window\.VITEST_API_TOKEN\s*=[\s\S]*?)<\/script>/
|
|
|
|
const browserUrl = `http://localhost:${process.env.BROWSER_DEV_PORT || '63315'}/__vitest_test__/`
|
|
|
|
return {
|
|
name: 'dev-ui-script',
|
|
apply(_config, env) {
|
|
return env.command === 'serve' && env.mode !== 'test'
|
|
},
|
|
async transformIndexHtml() {
|
|
if (process.env.BROWSER_DEV) {
|
|
const response = await fetch(browserUrl)
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to fetch browser runner HTML from ${browserUrl}`)
|
|
}
|
|
const browserHtml = await response.text()
|
|
const browserScript = browserHtml.match(BROWSER_SCRIPT_RE)?.[1]
|
|
if (!browserScript) {
|
|
throw new Error('Failed to extract browser runner state from the response')
|
|
}
|
|
return [
|
|
{
|
|
tag: 'script',
|
|
attrs: { type: 'module' },
|
|
children: browserScript,
|
|
injectTo: 'head-prepend',
|
|
},
|
|
]
|
|
}
|
|
|
|
const token = resolveApiToken(process.cwd()).token
|
|
return [
|
|
{
|
|
tag: 'script',
|
|
children: `window.VITEST_API_TOKEN = ${JSON.stringify(token)}`,
|
|
injectTo: 'head-prepend',
|
|
},
|
|
]
|
|
},
|
|
}
|
|
}
|
|
|
|
function devHtmlReportPlugin({ htmlDir }: { htmlDir: string }): Plugin {
|
|
const REPORT_FILE = 'html.meta.json.gz'
|
|
return {
|
|
name: 'dev-html-report',
|
|
apply(_config, env) {
|
|
return !!htmlDir && env.command === 'serve' && env.mode !== 'test'
|
|
},
|
|
async transformIndexHtml() {
|
|
const metadataCode = `window.HTML_REPORT_METADATA=fetch(new URL("./${REPORT_FILE}", window.location.href)).then(async res => new Uint8Array(await res.arrayBuffer()))`
|
|
return [
|
|
{
|
|
tag: 'script',
|
|
children: metadataCode,
|
|
},
|
|
]
|
|
},
|
|
configureServer(server) {
|
|
server.middlewares.use(async (req, res, next) => {
|
|
const url = new URL(req.url || '', `http://localhost`)
|
|
if (url.pathname === `/${REPORT_FILE}`) {
|
|
const data = fs.readFileSync(path.join(htmlDir, 'ui', REPORT_FILE))
|
|
res.end(data)
|
|
return
|
|
}
|
|
next()
|
|
})
|
|
},
|
|
}
|
|
}
|