Skip to content

chore: migrate from yarn to pnpm - #1711

Closed
johnnyreilly wants to merge 2 commits into
mainfrom
migrate-to-pnpm
Closed

johnnyreilly wants to merge 2 commits into
mainfrom
migrate-to-pnpm

Conversation

@johnnyreilly

@johnnyreilly johnnyreilly commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Summary

Moves ts-loader's development tooling from yarn to pnpm. #1712 is the npm alternative, for comparison.

  • Lockfile: yarn.lock is replaced by pnpm-lock.yaml (converted with pnpm import; versions match yarn's), and pnpm is pinned through "packageManager": "pnpm@12.11.2".
  • Root layout: a new pnpm-workspace.yaml sets nodeLinker: hoisted. Karma only finds karma-* plugins installed next to it, and the test packs resolve shared deps (webpack, babel presets) from the root node_modules.
  • Execution-test packs: all pack lockfiles are converted.
    • pnpm import ignored the packs' yarn.lock files and resolved fresh, which gave the react packs a second @types/react and failed CI. The pack lockfiles are therefore imported from chore: migrate from yarn to npm #1712's package-lock.json files, which were checked to resolve exactly the versions in each yarn.lock. The same check passes here.
    • run-tests.js installs packs with pnpm install --ignore-workspace --frozen-lockfile, so any lockfile drift now fails loudly. Packs use the hoisted layout, because some git-track copies of their file: deps in node_modules.
    • Packs install with auto-install-peers=false: yarn never installed peers, and pnpm was pulling webpack@3 into the babel packs through babel-loader@7's peer range.
    • strict-dep-builds is off, because pnpm 12 otherwise fails on the skipped install scripts of fsevents@1/core-js@2.
    • The pnpm pack keeps pnpm's defaults, since that's what it tests.
  • testLib: npm link ./test/comparison-tests/testLib is replaced by test/comparison-tests/link-test-lib.js, which just creates the symlink. npm link would rewrite pnpm's node_modules.
  • CI:
    • Every workflow (including release.yml) runs pnpm/action-setup@v6 before setup-node with cache: pnpm, and yarn commands become pnpm commands.
    • Windows jobs pin pnpm_config_store_dir=C:\pnpm-store. Installs run under C:\source\ts-loader while the checkout is on D:, so setup-node's cache step was looking for the store on the wrong drive.
    • The benchmark job imports the base branch's yarn.lock when it has no pnpm-lock.yaml. Resolving fresh pulled newer typings that break main's build.
  • Other files: the Dockerfile, devcontainer, .vscode/settings.json, AGENTS.md, CONTRIBUTING.md and the test-pack READMEs are updated.

Not changed: the README's install instructions for ts-loader users (including Yarn PnP), REFERENCES.md, examples/, CHANGELOG.md, and the yarn hint in src/compilerSetup.ts.

Testing

Run locally on macOS with Node 24:

  • pnpm build and pnpm lint pass, and pnpm comparison-tests passes in full.
  • pnpm execution-tests: 28/29 suites pass. 3.6.0_projectReferencesToBeBuilt also fails locally on main with yarn (karma temp-path issue on macOS), and it passes in CI.
  • The benchmark job's base-branch steps were simulated against main, and the benchmark ran end to end.

🤖 Generated with Claude Code

- replace yarn.lock with pnpm-lock.yaml (via `pnpm import`) and pin
  pnpm through `packageManager`
- use the hoisted node linker at the root so karma can find its plugins
  and the test packs resolve shared deps as before
- convert execution-test pack lockfiles and install them with pnpm
  (hoisted, except the pnpm pack, which keeps the symlinked layout)
- replace `npm link` of testLib with a symlink script that leaves pnpm's
  node_modules alone
- CI: add pnpm/action-setup, cache pnpm, swap yarn commands
- update Dockerfile, devcontainer and docs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- regenerate execution-test pack lockfiles so they resolve exactly the
  versions in their old yarn.lock: `pnpm import` had ignored them and
  resolved fresh, giving the react packs a second @types/react; also
  restores basic-happypack's lockfile, lost to the harness's git clean
- install packs with auto-install-peers=false (yarn never installed
  peers; babel packs were pulling in webpack@3) and --frozen-lockfile
- Windows: pin the pnpm store so setup-node's cache step finds it, as
  installs run on C: while the checkout is on D:
- benchmark: import the base branch's yarn.lock when it has no
  pnpm-lock.yaml instead of resolving fresh, which pulled newer typings
  that break its build and tripped ERR_PNPM_IGNORED_BUILDS

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Benchmark (Ubuntu)

Scenario transpileOnly PR branch median (ms) base branch median (ms) Δ vs base branch
Cold build false 952.0 957.1 -0.5%
Incremental rebuild (leaf touch) false 62.4 63.0 -1.0%
Incremental rebuild (hub touch) false 376.7 376.6 +0.0%
Cold build true 568.2 567.5 +0.1%
Incremental rebuild (leaf touch) true 34.6 33.0 +4.8%
Incremental rebuild (hub touch) true 34.4 34.6 -0.5%

PR branch = /home/runner/work/ts-loader/ts-loader, base branch = /home/runner/work/ts-loader/ts-loader-main. 2 warmup + 10 measured iterations per scenario, median reported. Report-only - no threshold fails this check.

@github-actions

Copy link
Copy Markdown

Benchmark (Windows)

Scenario transpileOnly PR branch median (ms) base branch median (ms) Δ vs base branch
Cold build false 995.4 991.9 +0.4%
Incremental rebuild (leaf touch) false 62.8 61.5 +2.1%
Incremental rebuild (hub touch) false 403.9 409.2 -1.3%
Cold build true 579.0 577.8 +0.2%
Incremental rebuild (leaf touch) true 29.7 31.4 -5.4%
Incremental rebuild (hub touch) true 32.0 33.9 -5.7%

PR branch = C:\source\ts-loader, base branch = C:\source\ts-loader-main. 2 warmup + 10 measured iterations per scenario, median reported. Report-only - no threshold fails this check.

@github-actions

Copy link
Copy Markdown

Benchmark (macOS)

Scenario transpileOnly PR branch median (ms) base branch median (ms) Δ vs base branch
Cold build false 757.7 788.8 -3.9%
Incremental rebuild (leaf touch) false 58.7 58.7 -0.1%
Incremental rebuild (hub touch) false 387.4 408.2 -5.1%
Cold build true 682.7 656.3 +4.0%
Incremental rebuild (leaf touch) true 58.0 55.9 +3.6%
Incremental rebuild (hub touch) true 57.5 58.1 -1.0%

PR branch = /Users/runner/work/ts-loader/ts-loader, base branch = /Users/runner/work/ts-loader/ts-loader-main. 2 warmup + 10 measured iterations per scenario, median reported. Report-only - no threshold fails this check.

@johnnyreilly

Copy link
Copy Markdown
Member Author

Closed in favour of #1712

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant