voidzero-dev / voidzero-dev/vite-plus
perf: `oxlint` and `oxfmt` each load `vite.config.ts` twice per invocation
- 主要言語
- Rust
- スター
- 5.8k
- フォーク
- 262
- 平均マージ
- 23時間 18分
- マージ済み PR(30日)
- 139
説明
### 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).
コントリビューションガイド
調査の方向性
リンクされた再現手順から始め、bench.sh を実行して vite.config.ts が繰り返し評価されることを確認します。vp staged と vp check --fix の呼び出しを追跡し、その後、1 回の実行で設定が 1 度だけ評価されるか、必要とするプロセス間でキャッシュされた結果が再利用されることを確認します。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- bun, node.js, typescript
- 領域
- cli, tooling
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 活発
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 55/100