test(web): prove Vite never binds a port
This commit is contained in:
@@ -2,11 +2,28 @@
|
|||||||
|
|
||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
import { join } from 'node:path'
|
import { join } from 'node:path'
|
||||||
|
import { createServer } from 'node:net'
|
||||||
import { execa } from 'execa'
|
import { execa } from 'execa'
|
||||||
import { describe, expect, it } from 'vitest'
|
import { describe, expect, it } from 'vitest'
|
||||||
|
|
||||||
const WEB_ROOT = fileURLToPath(new URL('..', import.meta.url))
|
const WEB_ROOT = fileURLToPath(new URL('..', import.meta.url))
|
||||||
|
|
||||||
|
/** Reserve an available loopback port, then release it for the child invocation. */
|
||||||
|
async function freePort(): Promise<number> {
|
||||||
|
const server = createServer()
|
||||||
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
server.once('error', reject)
|
||||||
|
server.listen(0, '127.0.0.1', resolve)
|
||||||
|
})
|
||||||
|
const address = server.address()
|
||||||
|
if (address === null || typeof address === 'string') throw new Error('port probe returned no address')
|
||||||
|
await new Promise<void>((resolve, reject) => server.close((error) => {
|
||||||
|
if (error === undefined) resolve()
|
||||||
|
else reject(error)
|
||||||
|
}))
|
||||||
|
return address.port
|
||||||
|
}
|
||||||
|
|
||||||
describe('Web development entry', () => {
|
describe('Web development entry', () => {
|
||||||
it('rejects the package dev alias with the full-host correction', async () => {
|
it('rejects the package dev alias with the full-host correction', async () => {
|
||||||
const result = await execa('pnpm', ['run', 'dev'], { cwd: WEB_ROOT, reject: false })
|
const result = await execa('pnpm', ['run', 'dev'], { cwd: WEB_ROOT, reject: false })
|
||||||
@@ -16,14 +33,24 @@ describe('Web development entry', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('rejects the standalone Vite server with the full-host correction', async () => {
|
it('rejects the standalone Vite server with the full-host correction', async () => {
|
||||||
const result = await execa(join(WEB_ROOT, 'node_modules/.bin/vite'), ['--host', '127.0.0.1', '--port', '0'], {
|
const port = await freePort()
|
||||||
|
const result = await execa(join(WEB_ROOT, 'node_modules/.bin/vite'), ['--host', '127.0.0.1', '--port', String(port)], {
|
||||||
cwd: WEB_ROOT,
|
cwd: WEB_ROOT,
|
||||||
reject: false,
|
reject: false,
|
||||||
timeout: 2_000,
|
timeout: 10_000,
|
||||||
})
|
})
|
||||||
|
expect(result.timedOut).toBe(false)
|
||||||
expect(result.exitCode).not.toBe(0)
|
expect(result.exitCode).not.toBe(0)
|
||||||
expect(result.stderr).toContain('apps/web is not a standalone application')
|
expect(result.stderr).toContain('apps/web is not a standalone application')
|
||||||
expect(result.stderr).toContain('dsh web')
|
expect(result.stderr).toContain('dsh web')
|
||||||
expect(result.stderr).toContain('window.__DSH_BOOT__')
|
expect(result.stderr).toContain('window.__DSH_BOOT__')
|
||||||
|
await expect(new Promise<void>((resolve, reject) => {
|
||||||
|
const probe = createServer()
|
||||||
|
probe.once('error', reject)
|
||||||
|
probe.listen(port, '127.0.0.1', () => probe.close((error) => {
|
||||||
|
if (error === undefined) resolve()
|
||||||
|
else reject(error)
|
||||||
|
}))
|
||||||
|
})).resolves.toBeUndefined()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,12 +10,11 @@ const STANDALONE_ERROR = 'apps/web is not a standalone application: bare Vite ca
|
|||||||
|
|
||||||
/** Fail before a Vite dev or preview server can expose the boot-manifest-free shell. */
|
/** Fail before a Vite dev or preview server can expose the boot-manifest-free shell. */
|
||||||
function rejectStandaloneServe(): Plugin {
|
function rejectStandaloneServe(): Plugin {
|
||||||
const reject = (): never => { throw new Error(STANDALONE_ERROR) }
|
|
||||||
return {
|
return {
|
||||||
name: 'dsh-reject-standalone-web-serve',
|
name: 'dsh-reject-standalone-web-serve',
|
||||||
apply: 'serve',
|
config(_config, env) {
|
||||||
configureServer: reject,
|
if (env.command === 'serve') throw new Error(STANDALONE_ERROR)
|
||||||
configurePreviewServer: reject,
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user