@cfxlabsinc/nx-bun-testInfers a test target for every package, running bun test.
Replaces the test target @nx/vitest used to contribute. Nx's
targetDefaults can only augment a target that already exists, so without an
inference plugin every package would need to declare "test": {} by hand.
bun test <projectRoot>/ --pass-with-no-tests [--preload ./<projectRoot>/<preload>]
plus a coverage configuration that adds --coverage --coverage-reporter=lcov.
--pass-with-no-tests — the target is inferred for every package, the
same way the vitest one was; a package with no tests is not a failure.--parallel / --isolate. bun already runs one package's files
sequentially in a single process, which is what the surfpool and Temporal
suites need — they previously spelled it pool: "forks" +
fileParallelism: false in their vite configs. Adding either for speed would
silently reintroduce those collisions.inputs: default
^production
{workspaceRoot}/bunfig.toml
{workspaceRoot}/tools/test/**/*
outputs: {workspaceRoot}/coverage/{projectRoot}
default, not production — production drops *.test.ts, which is the
one thing this target exists to run. ^production on the dependency side is
right, though: an upstream package's own tests can't change this one's result.{workspaceRoot} entries. The command runs with cwd = workspace
root, so the root bunfig.toml is the only one bun reads, and it decides both
what gets collected (pathIgnorePatterns) and what runs before every file
([test].preload → tools/test/). Neither is reachable from default —
that's {projectRoot}/**/* plus sharedGlobals, and sharedGlobals is only
tsconfig.base.json. Without them, dropping the global timeout or changing an
ignore pattern leaves every test cache warm and wrong.outputs is declared for both configurations because only the coverage
one writes it and Nx configurations carry executor options alone — outputs
is target-level and can't be narrowed per configuration. A plain test run
captures nothing.Not covered: the root package.json / bun.lock. A dependency bump doesn't
invalidate any test cache — that's a workspace-wide gap (build has it too) and
belongs in sharedGlobals, not here.
A package opts in by having the file; there is no per-package project.json
wiring.
| File | Used by |
|---|---|
test/preload.ts |
surfpool / Temporal packages — the module body replaces vitest's globalSetup |
test/setup.ts |
packages/ui — happy-dom's GlobalRegistrator must run before anything touches document |
A preload's module body executes once per bun test invocation, and a
top-level afterAll fires after the final test file — the same
once-per-package-with-teardown contract globalSetup provided.
The per-test timeout is set once in tools/test/preload.ts, wired via
[test].preload in bunfig.toml, rather than testTimeout: 0 in every
package.