Skip to content

Migrate package manager from npm to pnpm#320104

Draft
ulugbekna wants to merge 5 commits into
mainfrom
ulugbekna/npm-to-pnpm-migration
Draft

Migrate package manager from npm to pnpm#320104
ulugbekna wants to merge 5 commits into
mainfrom
ulugbekna/npm-to-pnpm-migration

Conversation

@ulugbekna
Copy link
Copy Markdown
Contributor

Summary

Migrates the VS Code monorepo from npm to pnpm (pnpm@10.32.1 via corepack).

re-verify.

What changed

Workspace & manifests

  • Add pnpm-workspace.yaml with explicit members (mirroring build/npm/dirs.ts, not broad globs so manifest-only theme extensions and sim fixtures stay out) + an onlyBuiltDependencies allowlist for native/binary packages.
    pnpm.
  • build/, remote/, remote/web stay standalone (their own .npmrc with Node-runtime headers + own lockfile) outside the Electron-runtime workspace, so native modules build against the correct headers. Each gets its own pnpm.overrides + pnpm.onlyBuiltDependencies so lifecycle scripts still run under --ignore-workspace.

.npmrc files

  • node-linker=hoisted (packaging assumes a flat node_modules), pnpm peer settings; drop legacy-peer-deps.

Install orchestration & build scripts

  • Rewrite build/npm/preinstall.ts (pnpm guard), postinstall.ts (installs only the standalone dirs; root install is driven by pnpm install, no recursion), dirs.ts (standaloneDirs).
  • Update installStateHash.ts + build/azure-pipelines/common/computeNodeModulesCacheKey.ts to hash pnpm lockfiles/workspace.
    Azure callers unaffected).

CI

  • GitHub Actions: corepack enable + pnpm install --frozen-lockfile (standalone build/ installs use --ignore-workspace).

Lockfiles

  • Remove the obsolete package-lock.json files; ignore pnpm-debug.log*. The pnpm-lock.yaml files must be generated and committed by CI.

Verification done locally

  • build type-check clean on all changed files.
  • pnpm-workspace.yaml parses; all 51 members resolve to real dirs.
  • All root scripts are npm-free.
  • Pre-commit hygiene hook passed.

Follow-ups (need CI / too heavy to verify in-session)

  • Generate & commit pnpm-lock.yaml (root) + standalone locks via pnpm install in CI.
    corepack/pnpm + rework node_modules tarball caching toward the pnpm store / pnpm fetch.
  • Distro repo (.build/distro) coordination for the standalone installs.
  • Full native build-from-source + packaging E2E (ASAR, copy-from-node_modules).

This is an AI-assisted migration intended as a starting point; the lockfile generation and Azure pipeline sweep are required before it can go green.>

Migrate the VS Code monorepo from npm to pnpm.

- Add pnpm-workspace.yaml with explicit members (mirroring build/npm/dirs.ts)
  plus an onlyBuiltDependencies allowlist for native/binary packages.
- Root package.json: set packageManager=pnpm@10.32.1, convert overrides to
  pnpm.overrides (pnpm selector syntax), and convert all scripts npm->pnpm.
- Keep build/, remote/, remote/web as standalone installs (own .npmrc +
  lockfile, node runtime headers) outside the Electron-runtime workspace; give
  them their own pnpm.overrides + pnpm.onlyBuiltDependencies so native modules
  still build under --ignore-workspace.
- .npmrc files: node-linker=hoisted (packaging assumes a flat node_modules),
  pnpm peer settings, drop legacy-peer-deps.
- Rewrite install orchestration (preinstall.ts pnpm guard, postinstall.ts
  standalone-only sub-installs, dirs.ts standaloneDirs).
- Update hashing (installStateHash.ts, computeNodeModulesCacheKey.ts) and
  production-dependency listing (dependencies.ts) for pnpm; setup-npm-registry.ts
  now writes registry= into .npmrc instead of rewriting lockfiles.
- Update GitHub Actions to corepack enable + pnpm install --frozen-lockfile
  (standalone build/ installs use --ignore-workspace).
- Remove obsolete package-lock.json files (pnpm-lock.yaml to be generated and
  committed by CI); ignore pnpm-debug.log*.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 5, 2026 13:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

ulugbekna and others added 4 commits June 5, 2026 15:37
Generated with `pnpm install --lockfile-only` (root) and
`--lockfile-only --ignore-workspace` for the standalone trees so CI's
`pnpm install --frozen-lockfile` can resolve. All four satisfy a frozen install
locally.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove `cache: npm` (keyed on the deleted package-lock.json) from setup-node
  in chat-lib-package.yml and chat-perf.yml; it errored with "Some specified
  paths were not resolved, unable to cache dependencies."
- The isolated copilot/chat-lib CI jobs install with `pnpm install
  --frozen-lockfile --ignore-workspace`, so give extensions/copilot and
  extensions/copilot/chat-lib their own committed pnpm-lock.yaml. Move copilot's
  top-level `overrides` to `pnpm.overrides` and add `pnpm.onlyBuiltDependencies`
  so the standalone install resolves consistently (these member-level fields are
  inert in the root workspace and only apply under --ignore-workspace).
- Add the missing `--ignore-workspace` to the chat-lib-package.yml installs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The isolated copilot/chat-lib CI jobs install standalone with
`--ignore-workspace`, so they no longer share the root workspace lockfile.
Regenerating those standalone lockfiles from scratch floated transitive
dependencies to newer versions than main's committed package-lock pinned,
which broke the chat-lib extraction compile:

- vscode-languageserver-protocol floated 3.17.5 -> 3.18.0 (pulling
  vscode-jsonrpc 9.0.0), causing "Cannot find module
  'vscode-languageserver-protocol'" and IDisposable/Emitter type errors.

Pin the drifted packages to main's exact versions via member-level
`pnpm.overrides` (honored under --ignore-workspace): typescript@5.8.3,
@types/node@22.16.3, vscode-languageserver-protocol@3.17.5, openai@6.7.0,
ws@8.20.1 for copilot; the protocol/typescript/node cluster for chat-lib.

Also:
- Expand copilot `pnpm.onlyBuiltDependencies` to the full set of native
  packages (sqlite3, keytar, electron, etc.) so the standalone install builds
  them like npm did; previously only esbuild was allowlisted, so sqlite3
  bindings were missing and "Copilot - Check Test Cache" failed.
- Add `node-linker=hoisted` to the copilot and chat-lib .npmrc so the
  standalone trees match npm's flat layout.
- The extract step rewrites chat-lib/package.json dependency versions, so
  switch "Install chat-lib dependencies" to a mutable `pnpm install`
  (mirroring main's `npm install`) instead of `--frozen-lockfile`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two more standalone/native issues surfaced once the earlier failures cleared:

- Root native module builds (native-keymap, @vscode/spdlog, node-pty,
  @vscode/policy-watcher) failed against the Electron 42 headers with
  "building this native module without using the right config.gypi ... update
  node-gyp (>=9.0.0)". npm used its bundled modern node-gyp, but pnpm picked up
  a transitive node-gyp@8.4.1 which is too old for Electron 42. Pin node-gyp to
  10.3.1 via root pnpm.overrides (build/ and copilot already do the same).
  Verified locally that all four modules now compile.

- The chat-lib extract step rewrites chat-lib/package.json dependency versions,
  so the committed lockfile no longer matches and CI (frozen by default)
  errored with ERR_PNPM_OUTDATED_LOCKFILE. Use `pnpm install
  --no-frozen-lockfile --ignore-workspace` to mirror main's mutable
  `npm install`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

2 participants