voidzero-dev / voidzero-dev/vite-plus
perf: `oxlint` and `oxfmt` each load `vite.config.ts` twice per invocation
- Dominant language
- Rust
- Stars
- 5.8k
- Forks
- 262
- Avg merge
- 1d 34m
- Merged PRs (30d)
- 135
Description
### Describe the bug
A single `vp staged` run evaluates the project's `vite.config.ts` 8 times.
The repro puts a side effect at the top of the config that appends one line per evaluation, recording timestamp, pid and argv:
```ts
import { appendFileSync } from 'node:fs';
appendFileSync(
new URL('./config-loads.log', import.meta.url),
`load ${Date.now()} pid=${process.pid} argv=${process.argv.slice(1).join(' ')}\n`,
);
export default {
staged: { '*.ts': 'vp check --fix' },
};
```
With 3 staged `.ts` files, one `vp staged` run produces 8 lines (paths and arguments elided for width):
```log
load ... pid=137436 argv=.bin/vp staged
load ... pid=137479 argv=.bin/vp check --fix f1.ts f2.ts f3.ts
load ... pid=137513 argv=oxfmt/bin/oxfmt --no-error-on-unmatched-pattern f1.ts f2.ts f3.ts
load ... pid=137513 argv=oxfmt/bin/oxfmt --no-error-on-unmatched-pattern f1.ts f2.ts f3.ts
load ... pid=137573 argv=oxlint/bin/oxlint --fix --format=default --no-error-on-unmatched-pattern f1.ts f2.ts f3.ts
load ... pid=137573 argv=oxlint/bin/oxlint --fix --format=default --no-error-on-unmatched-pattern f1.ts f2.ts f3.ts
load ... pid=137654 argv=oxfmt/bin/oxfmt --no-error-on-unmatched-pattern f1.ts f2.ts f3.ts
load ... pid=137654 argv=oxfmt/bin/oxfmt --no-error-on-unmatched-pattern f1.ts f2.ts f3.ts
```
Four processes load the config, and `oxfmt` and `oxlint` each load it twice within the same pid.
Timings from the same repo and the same 3 staged files, averaged over 3 runs (`vp` v0.3.1, Node v26.8.2, bun 1.4.2):
| | Time |
| --- | --- |
| `oxfmt` then `oxlint`, invoked directly | 0.045s |
| `vp check --fix`, no `vite.config.ts` present | 0.156s |
| `vp check --fix`, one-line static `vite.config.ts` | 0.957s |
| `vp check --fix`, instrumented `vite.config.ts` | 0.917s |
| `vp staged`, no-op task | 0.274s |
| `vp staged`, running `vp check --fix` | 1.004s |
The config used for the 0.957s row has no imports, no plugins and no side effects:
```ts
export default { staged: { '*.ts': 'vp check --fix' } };
```
So the difference between the 0.156s and 0.957s rows is attributable to the presence of the config file rather than to plugin evaluation, and `lazyPlugins` does not apply since there is nothing to lazy-load. The instrumented config measures the same as the one-line one, so the `appendFileSync` is not contributing meaningfully.
Adding `.oxlintrc.json` and `.oxfmtrc.json` reduces `vp check --fix` to 0.680s but does not eliminate the loads: the config is still evaluated 7 times in a single run.
`vite.config.ts` is expected to evaluate once per `vp staged` run, or the result is cached and reused across the processes that need it.
### Reproduction
https://github.com/ryansuhartanto/vite-plus-staged-perf
### Steps to reproduce
After cloning:
```sh
bun install
./bench.sh
```
### System Info
```shell
VITE+ - The Unified Toolchain for the Web
vp v0.3.0
Local vite-plus:
vite-plus v0.3.1
Tools:
vite v8.2.2
rolldown v1.2.7
vitest v4.1.11
oxfmt v0.66.0
oxlint v1.81.0
oxlint-tsgolint v7.0.2001
tsdown v0.23.0
```
### Used Package Manager
bun
### Logs
```shell
```
### Validations
- [x] Read the [Contributing Guidelines](https://github.com/voidzero-dev/vite-plus/blob/main/CONTRIBUTING.md).
- [x] Check that there isn't [already an issue](https://github.com/voidzero-dev/vite-plus/issues) for the same bug.
- [x] Confirm this is a Vite+ issue and not an upstream issue (Vite, Vitest, tsdown, Rolldown, or Oxc).
- [x] The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example).
Contributor guide
Research direction
Start with the linked reproduction and run bench.sh to observe the repeated evaluation of vite.config.ts. Trace the vp staged and vp check --fix invocations, then verify that a single run evaluates the config once or reuses a cached result across the processes that need it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bun, node.js, typescript
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100