Skip to content

pnpm deploy command removes keys from package.json #9215

@yuvalkarmi

Description

@yuvalkarmi

Verify latest release

  • I verified that the issue exists in the latest pnpm release

pnpm version

No response

Which area(s) of pnpm are affected? (leave empty if unsure)

No response

Link to the code that reproduces this issue or a replay of the bug

No response

Reproduction steps

  1. Create a project with pnpm init
  2. Add any key that pnpm does not explicitly recognize to package.json. For example main (e.g. "main": "path/to/main/file.js") and save
  3. Run pnpm deploy --filter your-package-name your-package-temp-dist-folder
  4. Open the package.json created in your-package-temp-dist-folder
  5. Note that the main key is missing

Describe the Bug

This is true for any keys not explicitly supported by pnpm, but that are often required by build tools (e.g. electron-builder). This is especially annoying since it will fail said build process, and you'll be left banging your head against the wall for 2 hours not understanding what you're doing wrong (oops, a random key in package.json that your build process expects is missing).

Expected Behavior

Original package.json keys should be preserved except for necessary modifications by pnpm (e.g. package versions / paths / whatnot).


Temporary fix

I've created this script which copies over missing keys from one package.json file to another. You can run it after your pnpm deploy command.

Usage:

node path/to/patch-deploy-package-json.js "path/to/original/package.json" "path/to/pnpm-created/package.json"

patch-deploy-package-json.js

import path from 'path';
import fs from 'fs/promises';

async function copyMissingKeys(sourceFilePath, targetFilePath) {
  try {
    // Read the files
    const sourceContent = await fs.readFile(sourceFilePath, 'utf8');
    const targetContent = await fs.readFile(targetFilePath, 'utf8');

    // Parse JSON
    const sourcePackage = JSON.parse(sourceContent);
    const targetPackage = JSON.parse(targetContent);

    // Count missing keys before update
    const missingKeysBefore = Object.keys(sourcePackage).filter(key => !(key in targetPackage));
    console.log(`Found ${missingKeysBefore.length} missing keys: ${missingKeysBefore.join(', ')}`);

    // Copy over missing keys
    let modifiedCount = 0;
    for (const key of Object.keys(sourcePackage)) {
      if (!(key in targetPackage)) {
        targetPackage[key] = sourcePackage[key];
        modifiedCount++;
      }
    }

    if (modifiedCount === 0) {
      console.log('No missing keys to copy. Target file remains unchanged.');
      return;
    }

    // Write the updated target file
    const updatedContent = JSON.stringify(targetPackage, null, 2);
    await fs.writeFile(targetFilePath, updatedContent);
    
    console.log(`Successfully copied ${modifiedCount} missing keys from ${path.basename(sourceFilePath)} to ${path.basename(targetFilePath)}`);
  } catch (error) {
    console.error('Error:', error.message);
    process.exit(1);
  }
}

// Check if file paths are provided as arguments
const args = process.argv.slice(2);
if (args.length !== 2) {
  console.error('Usage: node copy-missing-keys.js <source-package.json> <target-package.json>');
  process.exit(1);
}

const [sourceFilePath, targetFilePath] = args;

// Execute the function
copyMissingKeys(sourceFilePath, targetFilePath);

Which Node.js version are you using?

20.17.0

Which operating systems have you used?

  • macOS
  • Windows
  • Linux

If your OS is a Linux based, which one it is? (Include the version if relevant)

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions