refactor: use vite-node to load globalSetup (#624)

This commit is contained in:
Dominik G 2022-01-27 01:04:21 +01:00 committed by GitHub
parent 5887fb7aca
commit 5eebd60475
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 59 additions and 37 deletions

9
.editorconfig Normal file
View File

@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto eol=lf

View File

@ -1,4 +1,6 @@
import type { Plugin, ViteDevServer } from 'vite'
import type { Plugin } from 'vite'
import { ViteNodeRunner } from 'vite-node/client'
import type { Vitest } from '../core'
import { toArray } from '../../utils'
interface GlobalSetupFile {
@ -7,13 +9,25 @@ interface GlobalSetupFile {
teardown?: Function
}
async function loadGlobalSetupFiles(server: ViteDevServer): Promise<GlobalSetupFile[]> {
async function loadGlobalSetupFiles(ctx: Vitest): Promise<GlobalSetupFile[]> {
const node = ctx.vitenode
const server = ctx.server
const runner = new ViteNodeRunner({
root: server.config.root,
base: server.config.base,
fetchModule(id) {
return node.fetchModule(id)
},
resolveId(id, importer) {
return node.resolveId(id, importer)
},
})
const globalSetupFiles = toArray(server.config.test?.globalSetup)
return Promise.all(globalSetupFiles.map(file => loadGlobalSetupFile(file, server)))
return Promise.all(globalSetupFiles.map(file => loadGlobalSetupFile(file, runner)))
}
async function loadGlobalSetupFile(file: string, server: ViteDevServer): Promise<GlobalSetupFile> {
const m = await server.ssrLoadModule(file)
async function loadGlobalSetupFile(file: string, runner: ViteNodeRunner): Promise<GlobalSetupFile> {
const m = await runner.executeFile(file)
for (const exp of ['default', 'setup', 'teardown']) {
if (m[exp] != null && typeof m[exp] !== 'function')
throw new Error(`invalid export in globalSetup file ${file}: ${exp} must be a function`)
@ -36,33 +50,17 @@ async function loadGlobalSetupFile(file: string, server: ViteDevServer): Promise
}
}
export const GlobalSetupPlugin = (): Plugin => {
let server: ViteDevServer
export const GlobalSetupPlugin = (ctx: Vitest): Plugin => {
let globalSetupFiles: GlobalSetupFile[]
return {
name: 'vitest:global-setup-plugin',
enforce: 'pre',
// @ts-expect-error ssr is still flagged as alpha
config(config) {
if (config.test?.globalSetup) {
return {
ssr: {
noExternal: true, // needed so ssrLoadModule call doesn't initialize server._ssrExternals
},
}
}
},
configureServer(_server) {
server = _server
},
async buildStart() {
if (!server.config.test?.globalSetup)
if (!ctx.server.config.test?.globalSetup)
return
globalSetupFiles = await loadGlobalSetupFiles(server)
globalSetupFiles = await loadGlobalSetupFiles(ctx)
for (const globalSetupFile of globalSetupFiles) {
const teardown = await globalSetupFile.setup?.()
if (teardown == null || !!globalSetupFile.teardown)

View File

@ -55,7 +55,7 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest())
},
},
MocksPlugin(),
GlobalSetupPlugin(),
GlobalSetupPlugin(ctx),
options.ui
? await UIPlugin()
: null,

View File

@ -0,0 +1 @@
Hello Vitest

View File

@ -0,0 +1,16 @@
import { createServer } from 'vite'
import { resolve } from 'pathe'
export async function setup() {
const server = await createServer({
root: resolve(__dirname, '..'),
server: {
port: 9988,
},
})
await server.listen(9988)
return async() => {
await server.close()
}
}

View File

@ -1,16 +1,12 @@
import http from 'http'
async function sendRequest(host: string, port: number) {
return new Promise<string>((resolve) => {
http.request({ host, port }, (res) => {
let data = ''
res.on('data', d => data += d)
res.on('end', () => resolve(data))
}).end()
})
}
import fetch from 'node-fetch'
test('server running', async() => {
const res = await sendRequest('127.0.0.1', 9876)
const res = await (await fetch('http://localhost:9876')).text()
expect(res).toBe('Hello Vitest\n')
})
test('vite instance running', async() => {
const res = await (await fetch('http://localhost:9988')).text()
expect(res).toContain('<script type="module" src="/@vite/client">')
expect(res).toContain('Hello Vitest\n')
})

View File

@ -9,6 +9,7 @@ export default defineConfig({
'./setupFiles/default-export.js',
'./setupFiles/named-exports.js',
'./setupFiles/ts-with-imports.ts',
'./setupFiles/another-vite-instance.ts',
],
},
})