|
| 1 | +--- |
| 2 | +title: Comparing Transpiled Output |
| 3 | +category: Contributor Guides |
| 4 | +--- |
| 5 | + |
| 6 | +# Comparing Transpiled Output |
| 7 | + |
| 8 | +When migrating build tooling — Babel → SWC, `tsc` → `tsgo`, a Babel preset |
| 9 | +bump, a TypeScript upgrade — you want to know whether the change actually |
| 10 | +altered the emitted code. `transpile-diff` builds two git refs in isolation |
| 11 | +and diffs their `es/`, `lib/` and `types/` output. |
| 12 | + |
| 13 | +```bash |
| 14 | +pnpm run transpile-diff [refA] [refB] |
| 15 | +``` |
| 16 | + |
| 17 | +- `refA` defaults to `master`, `refB` to the current branch (`HEAD`). |
| 18 | +- **Any git ref works** — a branch, a tag (`v9.0.0`), or a commit SHA. |
| 19 | + |
| 20 | +```bash |
| 21 | +pnpm run transpile-diff # current branch vs master |
| 22 | +pnpm run transpile-diff master my-swc-branch # two branches |
| 23 | +pnpm run transpile-diff v9.0.0 HEAD # a release vs now |
| 24 | +``` |
| 25 | + |
| 26 | +## How it works |
| 27 | + |
| 28 | +For each ref the command: |
| 29 | + |
| 30 | +1. checks it out into a temporary git worktree under `.transpile-diff/`, |
| 31 | +2. runs `pnpm install --frozen-lockfile` then `pnpm run bootstrap` (a clean, |
| 32 | + full build — so `types/` declarations are included), |
| 33 | +3. snapshots the built output, passing each file through a normalization step |
| 34 | + that strips the license banner, sourcemap comments and whitespace noise. |
| 35 | + |
| 36 | +It then diffs the two snapshots, prints a `changed / added / removed` summary, |
| 37 | +writes an HTML report to `.transpile-diff/report-<a>-<b>.html` (opened |
| 38 | +automatically), and exits non-zero if anything differs. |
| 39 | + |
| 40 | +Snapshots are cached by commit SHA, so re-running against an unchanged ref |
| 41 | +(e.g. `master`) skips its rebuild. |
| 42 | + |
| 43 | +## Options |
| 44 | + |
| 45 | +| Option | Default | Description | |
| 46 | +| ------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 47 | +| `--modules` | `es,lib,types` | Which output dirs to compare. | |
| 48 | +| `--semantic` | `false` | Reprint each file with the repo's `dprint` config before diffing, so pure-formatting differences are ignored. **Recommended for Babel→SWC / tsc→tsgo**, where output is never byte-identical but should be semantically equivalent. | |
| 49 | +| `--raw` | `false` | Skip normalization entirely — compare raw bytes (banner, whitespace included). | |
| 50 | +| `--no-frozen` | _(off)_ | Allow lockfile changes when installing. Useful for old refs whose lockfile no longer resolves under the current toolchain. | |
| 51 | +| `--no-open` | _(off)_ | Don't open the HTML report automatically. | |
| 52 | + |
| 53 | +### Which mode to use |
| 54 | + |
| 55 | +- **Same compiler, config bump** (e.g. a TypeScript version upgrade): the default normalization is enough — output formatting is stable, so any diff is a real change. |
| 56 | +- **Different compiler** (Babel→SWC, tsc→tsgo): add `--semantic`. Babel and SWC will never produce byte-identical output, but after reprinting through `dprint` the diff reduces to genuine code differences. |
| 57 | + |
| 58 | +`--semantic` uses `dprint`, which is already a ui-scripts dependency — it adds no new packages. |
| 59 | + |
| 60 | +## Notes |
| 61 | + |
| 62 | +- A full `bootstrap` runs per ref, so a cold run takes several minutes — this |
| 63 | + is meant to be run occasionally, not in CI. |
| 64 | +- Comparing very old commits can fail at the **build** step (lockfile or Node |
| 65 | + version drift), not the diff step. The command aborts with a clear message |
| 66 | + identifying which ref failed to build rather than reporting a misleading diff. |
0 commit comments