facebook / facebook/stylex

@stylexjs/unplugin Vite shared-store timer survives Vitest shutdown without httpServer

Open
#1,857 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
10.3k
Forks
481
Avg merge
3d 8h
Merged PRs (30d)
13

Description

### Versions

- `@stylexjs/unplugin`: 0.19.0
- Vite: 6.4.3
- Vitest: 4.1.0
- Node: 24.20.0, macOS arm64

### Reproduction

Use the recommended Vite integration in a shared Vite/Vitest config:

```ts
import { defineConfig } from 'vitest/config';
import stylex from '@stylexjs/unplugin';
export default defineConfig({ plugins: [stylex.vite({ useCSSLayers: false })] });
```

Run `vitest run` against a passing test suite. The tests pass, then Vitest waits ten seconds and reports:

```
close timed out after 10000ms
Tests closed successfully but something prevents Vite server from exiting
```

### Source evidence

`packages/unplugin/src/vite.ts` / published `lib/vite.js` installs a 150ms `setInterval` in `configureServer` when the shared store is present. Cleanup is registered only with `server.httpServer?.once('close', ...)`. Vitest's server does not provide the normal HTTP-server lifecycle, leaving this timer alive.

### Expected

The plugin should release/unref its timer when Vite's plugin container closes even without an HTTP server, so a test run exits normally.

### Local workaround

For `process.env.VITEST`, use the same package's `stylex.rollup({ useCSSLayers: false })` compiler adapter, leaving `stylex.vite(...)` for browser dev/build. The same suite then exits cleanly without changing tests or timeouts. This is a non-blocking upstream follow-up; no dependency patch is needed locally.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.