Skip to content

refactor: migrate from yarn to pnpm - #7

Open
ukeSJTU wants to merge 4 commits into
code-philia:mainfrom
ukeSJTU:refactor/migrate-yarn-to-pnpm
Open

refactor: migrate from yarn to pnpm#7
ukeSJTU wants to merge 4 commits into
code-philia:mainfrom
ukeSJTU:refactor/migrate-yarn-to-pnpm

Conversation

@ukeSJTU

@ukeSJTU ukeSJTU commented Dec 8, 2025

Copy link
Copy Markdown

Migration of package manager: yarn to pnpm

This PR migrates the project from yarn to pnpm as the package manager. pnpm provides faster installation speed, better workspace management, and simplified setup. Developers only need to run pnpm install once at the project root instead of installing dependencies in two separate folders as yarn required.

This PR should resolve #6

Changes

  • Migrated from yarn to pnpm workspaces
  • Replaced dual yarn.lock files (3,865 total lines) with single pnpm-lock.yaml at project root
  • Updated all scripts in package.json to use pnpm
  • Updated setup scripts (setup.sh, setup.ps1)
  • Updated documentation (README.md)
  • Added workspace configuration (pnpm-workspace.yaml)
  • Added pnpm configuration (.npmrc)

Configuration (.npmrc)

Key settings for VS Code extension compatibility:

  • hoist=true + node-linker=hoisted: Ensures esbuild externals (playwright-core, vscode) are accessible at the expected locations
  • strict-peer-dependencies=false: Allows React 19 peer dependency warnings (these are informational; React 19 is compatible with the packages we use)
  • auto-install-peers=true: Automatically installs peer dependencies for convenience

These settings are necessary for the VS Code extension to build and run correctly with esbuild's external dependencies.

Performance Improvements

The benchmarks were obtained by running benchmark-migration.sh on a MacBook Air with M2 chip. Install times are measured with warm cache to simulate typical developer workflow and eliminate network speed variance.

Benchmark Results:

Metric Yarn pnpm Improvement
Install time (avg) 7.36s 4.93s 33% faster
Disk space 358M 384M +7% (+26M)
Lock file 3,865 lines (2 files) 3,974 lines (1 file) Single source of truth

Install Speed Breakdown:

  • Yarn: 8.05s / 6.62s / 7.42s (avg: 7.36s)
  • pnpm: 6.82s / 4.62s / 3.37s (avg: 4.93s)

Disk Space Distribution:

  • Yarn: 93M (root) + 264M (webview-ui) = 358M
  • pnpm: 320M (root) + 64M (webview-ui) = 384M

Note on disk space: The slight increase (+7%) is expected when using node-linker=hoisted mode, which is required for VS Code extension compatibility. pnpm workspace consolidates shared dependencies at the root level instead of duplicating them across packages. The 33% speed improvement and simplified workflow far outweigh this minimal disk space cost.

Additional Benefits

Beyond the performance improvements, pnpm provides:

  1. Simplified Installation

    • Single pnpm install command at root (no need for cd webview-ui && yarn)
    • Workspace dependencies managed automatically
  2. Better Dependency Management

    • Single unified lock file ensures consistent versions across all packages
    • Stricter dependency resolution prevents phantom dependencies
    • Better security by default
  3. Modern Tooling

    • Active ecosystem and development
    • Adopted by major projects (Vue 3, Nuxt, Turborepo, etc.)
    • Better workspace support for monorepo patterns
  4. Improved Maintenance

    • Easier to resolve merge conflicts (single lock file)
    • Clearer dependency relationships
    • Workspace filtering with pnpm --filter for targeted operations

Migration Guide for Developers

BREAKING CHANGE: This PR fully removes yarn and migrates to pnpm.

Setup Steps:

  1. Install pnpm globally:

    npm install -g pnpm
  2. Clean up old artifacts (if upgrading from yarn):

    rm -rf node_modules webview-ui/node_modules
  3. Install dependencies:

    pnpm install
  4. Verify installation:

    pnpm package

Common Commands:

Task Old (yarn) New (pnpm)
Install all deps yarn install:all pnpm install
Build webview cd webview-ui && yarn build pnpm build:webview
Start webview dev cd webview-ui && yarn start pnpm start:webview
Package extension yarn package pnpm package
Run type check yarn check-types pnpm check-types
Run linter yarn lint pnpm lint

Testing Checklist

  • pnpm install completes without errors
  • pnpm package builds extension successfully
  • pnpm start:webview runs development server
  • pnpm check-types passes
  • pnpm lint passes
  • Extension loads in VS Code Extension Development Host
  • Benchmark comparison completed (yarn vs pnpm)
  • Playwright automation works (requires testing after merge)
  • Tested on multiple platforms (macOS completed, Windows/Linux pending)

Files Modified

Configuration Files (new):

  • pnpm-workspace.yaml - Workspace configuration
  • .npmrc - pnpm settings for VS Code extension compatibility

Configuration Files (updated):

  • package.json - All scripts updated to use pnpm
  • setup.sh - Updated to use pnpm commands
  • setup.ps1 - Updated to use pnpm commands
  • README.md - Updated installation instructions

Lock Files:

  • Removed: yarn.lock, webview-ui/yarn.lock
  • Added: pnpm-lock.yaml (single unified lock file)

Rollback Plan

If critical issues are discovered, rollback is possible by:

git revert <this-commit-hash>
npm install -g yarn
yarn install:all

However, we recommend moving forward with pnpm as the benefits significantly outweigh the minimal migration cost.

Attachments

To avoid polluting the codebase, I'll attach the benchmark script as below:

#!/bin/bash
set -e

echo "===== YARN TO PNPM MIGRATION BENCHMARK ====="
echo ""
echo "This benchmark measures:"
echo "  1. Install time (with warm cache - typical developer experience)"
echo "  2. Disk space usage"
echo "  3. Lock file size"
echo ""
echo "Note: Install times are measured with WARM cache to simulate"
echo "      typical developer workflow (not first-time setup)."
echo "      This provides fair comparison independent of network speed."
echo ""

# Function to clean node_modules only (keep cache)
clean_deps() {
    echo "Cleaning node_modules..."
    rm -rf node_modules webview-ui/node_modules
}

# Function to measure disk space
measure_disk() {
    local label=$1
    echo "[$label] Disk usage:"
    if [ -d "node_modules" ] && [ -d "webview-ui/node_modules" ]; then
        root_size=$(du -sh node_modules 2>/dev/null | awk '{print $1}')
        webview_size=$(du -sh webview-ui/node_modules 2>/dev/null | awk '{print $1}')
        total_size=$(du -shc node_modules webview-ui/node_modules 2>/dev/null | tail -1 | awk '{print $1}')
        echo "  Root:       $root_size"
        echo "  Webview-UI: $webview_size"
        echo "  Total:      $total_size"
    else
        echo "  No node_modules found"
    fi
    echo ""
}

# Function to measure install time with warm cache
measure_install_warm() {
    local manager=$1
    local command=$2
    echo "[$manager] Install time (warm cache, 3 runs):"

    total_time=0
    for i in 1 2 3; do
        clean_deps
        echo -n "  Run $i: "

        # Measure time
        start=$(date +%s.%N)
        eval "$command" > /dev/null 2>&1
        end=$(date +%s.%N)

        runtime=$(echo "$end - $start" | bc)
        printf "%.2fs\n" $runtime
        total_time=$(echo "$total_time + $runtime" | bc)
    done

    avg_time=$(echo "scale=2; $total_time / 3" | bc)
    echo "  Average: ${avg_time}s"
    echo ""
}

# Check if we're on yarn or pnpm branch
if [ -f "yarn.lock" ]; then
    echo "===== YARN BASELINE ====="
    echo ""

    # Warm up cache
    echo "Warming up yarn cache..."
    yarn install:all > /dev/null 2>&1

    # Measure
    measure_install_warm "yarn" "yarn install:all"
    measure_disk "yarn"

    echo "Lock files:"
    root_lines=$(wc -l < yarn.lock 2>/dev/null || echo "0")
    webview_lines=$(wc -l < webview-ui/yarn.lock 2>/dev/null || echo "0")
    total_lines=$((root_lines + webview_lines))
    echo "  Root:       $root_lines lines"
    echo "  Webview-UI: $webview_lines lines"
    echo "  Total:      $total_lines lines"
    echo ""

elif [ -f "pnpm-lock.yaml" ]; then
    echo "===== PNPM MIGRATION RESULTS ====="
    echo ""

    # Warm up cache
    echo "Warming up pnpm cache..."
    pnpm install > /dev/null 2>&1

    # Measure
    measure_install_warm "pnpm" "pnpm install"
    measure_disk "pnpm"

    echo "Lock file:"
    pnpm_lines=$(wc -l < pnpm-lock.yaml 2>/dev/null || echo "0")
    echo "  Single pnpm-lock.yaml: $pnpm_lines lines"
    echo ""

else
    echo "ERROR: Neither yarn.lock nor pnpm-lock.yaml found!"
    exit 1
fi

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.

Suggestion: Migrate from Yarn to pnpm for better monorepo management

1 participant