Files
twenty/packages/twenty-front/vitest.config.ts
T
Charles Bochet 869680a5a1 fix(deps): esbuild ^0.28.1 floors + vite 7→8 (rolldown) upgrade (#21517)
## What this does

Resolves the remaining esbuild security alerts on packages we own, and
upgrades the repo to **Vite 8** (which drops esbuild entirely in favour
of rolldown/oxc).

### 1. esbuild → `^0.28.1` (security)
- Raised the declared `esbuild` floor in `twenty-sdk` and the
logic-function common-layer (both were `^0.25.0`, which can only resolve
to a vulnerable version). These are our packages, so this is just
declaring the patched version — clears Dependabot **#1467** and
**#1468**.

### 2. Vite 7 → 8
- Bumped `vite` to `^8` in the 5 packages that declare it, and
`@vitejs/plugin-react-swc` to `^4.3.1` (the only plugin that needed a
bump for Vite 8; everything else already supports it).
- `twenty-front` keeps esbuild minification, so esbuild is now an
explicit (patched) devDependency there — Vite 8 no longer ships it.

### Two Vite-8 fallout fixes (bundler internals changed)
- **Storybook tests:** added React to `optimizeDeps.include` so Vite's
dep optimizer doesn't re-bundle React mid-run and break in-flight
imports in browser-mode tests.
- **`hex-rgb`:** it's ESM-only and broke rolldown's CJS interop (a
default import resolved to the wrong thing under jest). Replaced its one
use with a tiny inline hex→rgb parse and dropped the dependency.

## Verified
Vite resolves to a single `8.0.16` with no esbuild in its tree. Builds
pass on Vite 8/rolldown: `twenty-front` production build, the SDKs, and
Storybook; the previously-failing front and storybook test jobs now
pass; `yarn install --immutable` is clean.

## Note
This doesn't close root alert **#1469** — esbuild is still pulled by
other third-party tools (storybook, tsx, lingui, zapier, etc.) that
haven't shipped a patched release. The vulnerable code path (esbuild's
dev server) isn't used here, so that one is best dismissed as
not-affected.
2026-06-13 10:44:22 +00:00

75 lines
2.6 KiB
TypeScript

import { argosVitestPlugin } from '@argos-ci/storybook/vitest-plugin';
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
import { playwright } from '@vitest/browser-playwright';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { defineConfig } from 'vitest/config';
const MINUTES_IN_MS = 60 * 1000;
const shouldCaptureArgosScreenshots = ['modules', 'pages'].includes(
process.env.STORYBOOK_SCOPE ?? '',
);
const dirname =
typeof __dirname !== 'undefined'
? __dirname
: path.dirname(fileURLToPath(import.meta.url));
export default defineConfig({
test: {
coverage: {
provider: 'istanbul',
reporter: ['json', 'text'],
reportsDirectory: './coverage/storybook',
},
projects: [
{
extends: './vite.config.ts',
plugins: [
storybookTest({
configDir: path.join(dirname, '.storybook'),
...(process.env.STORYBOOK_URL
? { storybookUrl: process.env.STORYBOOK_URL }
: { storybookScript: 'yarn storybook --no-open' }),
}),
...(shouldCaptureArgosScreenshots
? [
argosVitestPlugin({
uploadToArgos: !!process.env.ARGOS_TOKEN,
token: process.env.ARGOS_TOKEN,
apiBaseUrl: process.env.ARGOS_API_BASE_URL,
buildName: process.env.ARGOS_BUILD_NAME || undefined,
branch: process.env.ARGOS_BRANCH || undefined,
commit: process.env.ARGOS_COMMIT || undefined,
referenceCommit:
process.env.ARGOS_REFERENCE_COMMIT || undefined,
}),
]
: []),
],
test: {
name: 'storybook',
browser: {
enabled: true,
headless: true,
provider: playwright({}),
instances: [{ browser: 'chromium' }],
},
setupFiles: ['./.storybook/vitest.setup.ts'],
testTimeout: 5 * MINUTES_IN_MS,
// Browser-mode interaction tests are inherently flaky under heavy
// shards (transient image loads, animation/timing). Retry transient
// failures rather than failing the whole shard on one flaky story.
retry: 2,
// Story play functions run as a hook; under vite 8 the modules shard
// is heavier, so the default 30s hook timeout trips multi-step
// interactions (e.g. the Dropdown open/close cycles) on slower CI
// runners. Match testTimeout so play functions get the same budget.
hookTimeout: 5 * MINUTES_IN_MS,
},
},
],
},
});