Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

A chained command is split into independently cached sub-tasks, but `output` stays task-level — a hit replays a stale output over a fresh one

未关闭
#589 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
48/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
冷清
技术栈
rust

调研方向

使用 vite.config.ts 任务和 vp run gen 复现该问题,每次运行之间只修改 src-a.txt。首先跟踪链式子任务和共享 output 的缓存归档与恢复行为;当部分命中无法恢复兄弟任务的输出,或该任务因明确的警告而被拒绝缓存时,即表示完成。

由索引模型根据 Issue 内容生成。

描述

Summary

When a task's command chains several commands (a && b, or an array), Vite+ caches each sub-command independently, but the task declares a single, task-level output. Every sub-task therefore claims every output file.

On a partially-cached run this is unsound: a sub-task that hits restores its archived copy of the shared outputs over the file a sub-task that missed has just regenerated. The task exits 0 and the artifact on disk is stale.

Ordering makes it visible: with 3 hits and 1 miss on the same task, the missing sub-task in position 2 of 4 leaves a stale output, while the same sub-task in position 4 of 4 leaves the correct one. Clearing the cache (no replay at all) is always correct.

This is not an input-declaration problem. Fixing input so the miss fires correctly does not fix it: the sub-task runs, writes the right file, and a later hit overwrites it.

Reproduction

mkdir vp-chained-output && cd vp-chained-output
npm init -y
npm i -D vite-plus@0.2.7
mkdir -p out

vite.config.ts:

import { defineConfig } from 'vite-plus';

export default defineConfig({
  run: {
    tasks: {
      gen: {
        command: [
          'node -e "require(\'fs\').writeFileSync(\'out/a.txt\', require(\'fs\').readFileSync(\'src-a.txt\',\'utf8\'))"',
          'node -e "require(\'fs\').writeFileSync(\'out/b.txt\', require(\'fs\').readFileSync(\'src-b.txt\',\'utf8\'))"',
        ],
        output: ['out/**'],
      },
    },
  },
});

Automatic tracking matters here: it is what gives each sub-task a different input set, so one can hit
while another misses. With a single explicit input list, every sub-task invalidates together and the bug
stays hidden.

echo v1 > src-a.txt && echo v1 > src-b.txt
npx vp run gen          # miss, out/a.txt = v1, out/b.txt = v1
npx vp run gen          # hit

echo v2 > src-a.txt     # only the first sub-command's input changes
npx vp run gen          # -> "cache miss: 'src-a.txt' modified" for sub-task 1
                        # -> "cache hit"                        for sub-task 2

cat out/a.txt           # expected v2 - observed v1, exit code 0

Observed exactly as above on vite-plus 0.2.7.

Expected

Each sub-task restores only the outputs it produced, or the task is treated as a single cache unit.

Actual

The archive of a hitting sub-task contains files written by its siblings and replays them, silently reverting fresher output. Exit code is 0.

Why it matters in practice

In our monorepo the pattern is common: a generator followed by a fixer, e.g.

kubb generate ./swagger.yml -c=kubb.config.mock.js && npm run fix-generated-mock-imports

Both write under src/gen/mocks/**, which is the task's only declared output. A partial hit yields a half-regenerated SDK with no signal. We found 14 tasks in this shape and had to disable caching on all of them.

Splitting them into one task per command — the obvious workaround, and the one we could apply to a Panda ship chain — is not possible when the second command fixes the output of the first: the fixer has the same files as input and output, so the tracker declines to cache it (Not cached: read and wrote …).

Suggested directions

  • track outputs per sub-task rather than per task, so a sub-task only restores what it wrote; or
  • treat a task with a chained command and more than one output as a single cache unit; or
  • at minimum, refuse to cache (or warn) when a task chains commands and declares outputs that several sub-tasks can write — a loud refusal is far better than a silent stale artifact.

Environment

  • vite-plus 0.2.7
  • macOS darwin 25.5.0, arm64; Node 22.22.0, pnpm 9.15.0

Related

  • voidzero-dev/vite-task#587 — the tracker not observing reads made by a Go binary. Different mechanism, same consequence: a cache hit that hides a wrong result.
主要语言
Rust
星标
466
派生
42
平均合并
1 天 20 小时
30 天内合并 PR
21

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

voidzero-dev/vite-task 的其他 Issue

查看 voidzero-dev/vite-task 的全部 Issue

相似的 Issue

更多 Rust Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。