Skip to content

Commit 5df3a55

Browse files
authored
fix(pack): replace "tsdown" with "vp pack" in error messages (#642)
Add brandTsdown() build-time patching to replace upstream "tsdown" branding in the bundled error message when no input files are found. Follows the same post-build branding pattern as brandVitest().
1 parent f6c223d commit 5df3a55

6 files changed

Lines changed: 65 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "command-pack-no-input",
3+
"version": "1.0.0",
4+
"type": "module"
5+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[1]> vp pack # should not mention tsdown in error
2+
3+
ERROR Error: undefined No input files, try "vp pack <your-file>" or create src/index.ts
4+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"ignoredPlatforms": ["win32"],
3+
"env": {
4+
"VITE_DISABLE_AUTO_INSTALL": "1"
5+
},
6+
"commands": ["vp pack # should not mention tsdown in error"]
7+
}

packages/core/build.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ await bundleRolldownPluginutils();
4949
await bundleRolldown();
5050
await buildVite();
5151
await bundleTsdown();
52+
await brandTsdown();
5253
await bundleVitepress();
5354
await mergePackageJson();
5455
await syncLicenseFromRoot();
@@ -350,6 +351,33 @@ async function bundleTsdown() {
350351
});
351352
}
352353

354+
async function brandTsdown() {
355+
const tsdownDistDir = join(projectDir, 'dist/tsdown');
356+
const buildFiles = await glob(toPosixPath(join(tsdownDistDir, 'build-*.js')), { absolute: true });
357+
if (buildFiles.length === 0) {
358+
throw new Error('brandTsdown: no build chunk found in dist/tsdown/');
359+
}
360+
361+
const search = '"tsdown <your-file>"';
362+
const replacement = '"vp pack <your-file>"';
363+
let patched = false;
364+
365+
for (const buildFile of buildFiles) {
366+
let content = await readFile(buildFile, 'utf-8');
367+
if (!content.includes(search)) {
368+
continue;
369+
}
370+
content = content.replace(search, replacement);
371+
await writeFile(buildFile, content, 'utf-8');
372+
console.log(`Branded tsdown → vp pack in ${buildFile}`);
373+
patched = true;
374+
}
375+
376+
if (!patched) {
377+
throw new Error(`brandTsdown: pattern ${search} not found in any build chunk`);
378+
}
379+
}
380+
353381
// Actually do nothing now, we will polish it in the future when `vitepress` is ready
354382
async function bundleVitepress() {
355383
const vitepressSourceDir = resolve(projectDir, 'node_modules/vitepress');

packages/tools/src/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ export function replaceUnstableOutput(output: string, cwd?: string) {
132132
// [PLUGIN_TIMINGS] Warning: Your build spent significant time in plugins. Here is a breakdown:
133133
// - externalize-deps (74%)
134134
.replaceAll(/\[PLUGIN_TIMINGS\] Warning:.*?\n(?:\s+-\s+.+?\n)*/g, '')
135+
// remove JS stack traces (lines starting with " at ")
136+
.replaceAll(/\n\s+at .+/g, '')
135137
);
136138
}
137139

rfcs/cli-output-polish.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,18 @@ These are straightforward string replacements in the source, verified by snap te
325325

326326
For oxlint and oxfmt, pre-spawn banners or build-time patching can follow the same pattern once their source/dist is bundled.
327327

328+
### Phase 3.5: Rebrand tsdown Output
329+
330+
tsdown is bundled via `@voidzero-dev/vite-plus-core`. Its build script (`packages/core/build.ts`) bundles tsdown's dist files via rolldown.
331+
332+
#### 3.5.1 Approach: Build-time patching of bundled build chunk
333+
334+
After `bundleTsdown()` rebuilds tsdown, a `brandTsdown()` step patches the build chunk (`dist/tsdown/build-*.js`) with string replacements:
335+
336+
1. `"tsdown <your-file>"``"vp pack <your-file>"` — error message when no input files found
337+
338+
Internal identifiers are left unchanged: debug namespaces (`tsdown:*`), plugin names (`tsdown:external`), config prefix (`tsdown.config`), temp dirs (`tsdown-pack-`).
339+
328340
### Phase 4: JS-Side Output Consistency
329341

330342
The JS code in `packages/cli/src/utils/terminal.ts` already has `accent()`, `headline()`, `muted()`, `success()`, `error()` functions. Extend it with prefix functions matching the Rust convention:
@@ -435,6 +447,12 @@ These are internal identifiers, API references, or project name references:
435447
8. Migrate `vite_install/src/commands/*.rs` Warning/Note messages
436448
9. Update snap tests
437449

450+
### Phase 2.5: tsdown Branding
451+
452+
1. Add `brandTsdown()` in `packages/core/build.ts` after `bundleTsdown()`
453+
2. Patch `dist/tsdown/build-*.js` with string replacement: `"tsdown <your-file>"``"vp pack <your-file>"`
454+
3. Update snap tests
455+
438456
### Phase 3: Sub-tool Banners
439457

440458
1. Add `print_banner()` for vitest, oxlint, oxfmt in `packages/cli/binding/src/cli.rs`
@@ -459,6 +477,7 @@ Many existing snap tests will need updates due to prefix and branding changes:
459477
- `snap-tests/command-dev-*/snap.txt` — vite banner change
460478
- `snap-tests/command-build-*/snap.txt` — build banner change
461479
- All `Warning:`/`Note:` snap outputs across global snap tests
480+
- `snap-tests/command-pack-no-input/snap.txt` — tsdown error message branding
462481

463482
**Process:** Run `pnpm -F vite-plus snap-test` after each phase, review `git diff` on `snap.txt` files, and verify the new formatting matches expectations.
464483

0 commit comments

Comments
 (0)