Skip to content

Conversation

agrasth
Copy link
Collaborator

@agrasth agrasth commented May 20, 2025

  • All tests passed. If this feature is not already covered by the tests, I added new tests.
  • All static analysis checks passed.
  • This pull request is on the dev branch.
  • I used gofmt for formatting the code before submitting the pull request.

NPM Publish: Improve package.json Location Handling

Description

This PR improves how the npm publish command handles finding and reading package.json files in npm packages. Instead of using a complex priority-based approach, it implements a simpler and more predictable strategy that maintains compatibility with both standard and non-standard npm package structures.

Package.json Search Strategy

The command now uses a three-step strategy to locate package.json:

  1. First checks standard locations in this order:

    • package/package.json (standard npm package location)
    • Any package.json in a root-level directory (e.g., node-pkg/package.json)
  2. If not found in standard locations, performs a second pass to scan the entire package for any package.json file, using the first one found.

  3. Only throws an error if no package.json is found anywhere in the package.

Changes

  • Implemented a simpler, more predictable package.json lookup strategy
  • Added support for non-standard package structures (e.g., packages with root-level directories)
  • Added detailed debug logging to show where package.json was found
  • Improved error messages and handling
  • Removed complex priority-based package.json selection logic

Testing Done

  • Verified with standard npm packages (package/package.json)
  • Verified with non-standard package structures (root-level directory package.json)
  • Verified error handling when no package.json is found
  • Added test cases covering various package structures
  • All existing tests pass

Impact

This change simplifies the code and makes the behavior more predictable while maintaining compatibility with different package structures. It should not break any existing functionality but makes the package.json selection process more transparent and easier to understand.

@agrasth agrasth added the safe to test Approve running integration tests on a pull request label May 20, 2025
return err
}

// findBestPackageJson scans the tarball and returns the best package.json file based on priority
Copy link
Collaborator

Choose a reason for hiding this comment

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

a little more description on what exactly is best package and how it is finding will help readers later

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

Comment on lines 395 to 400
priority := calculatePackageJsonPriority(hdr.Name)
candidate := &packageJsonCandidate{
path: hdr.Name,
priority: priority,
content: content,
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

why do we need to have priority and search for? is it because of consideration that there can be multiple package.json ?

  • Can we pack a npm package with multiple package.json? if so then npm should get confused with what package.json to use.
  • Cant we limit the solution finding first package.json and returning it without adding any priority? Asking this since to pack you have to be in root folder of package and run npm pack this will have package.json as package/package.json but packing can also be done using other tools which might be reason for having something like node/package.json even in this scenario search in root folder for package.json should be good right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, npm packages can absolutely contain multiple package.json files for several legitimate reasons.
One of the example can be a

  • Monorepo structures where Packages with nested components each having their own package.json.
  • Some packages include vendored dependencies with their own package.json

The key issue is that the order of files in a tar archive is not guaranteed to be consistent. Simply taking the first package.json we find would be problematic some build tools might place package.json in different locations than the npm standard

How npm handles this situation
It has expectations about where package.json should be located but can handle non-standard structures. When publishing, npm normalizes the package structure, but when consuming packages, it needs to be flexible.

Can't we just use the first package.json we find?
What I felt was simply using the first package.json found would be problematic for several reasons:

  • The order of files in a tarball is not guaranteed or standardized - it depends on how the archive was created
  • A less relevant package.json (like from an example directory) might appear first in the tarball
  • This would make our behavior inconsistent and potentially different from npm's own behavior

The current approach with package/package.json as highest priority matches npm's conventions, while providing fallbacks for non-standard packages. Using just "the first one found" would be unpredictable across different package structures.

We can discuss this tomorrow. If we want, we can go ahead with that approach. The implementation is what I had initially thought.

@bhanurp bhanurp removed the safe to test Approve running integration tests on a pull request label May 22, 2025
@agrasth agrasth added the safe to test Approve running integration tests on a pull request label May 26, 2025
@agrasth agrasth force-pushed the fix/npm-publish-package-json-location-new branch from d866afd to ff8275b Compare May 26, 2025 09:26
@bhanurp bhanurp self-requested a review May 26, 2025 11:17
@agrasth agrasth merged commit 37dadd7 into jfrog:main May 26, 2025
@agrasth agrasth deleted the fix/npm-publish-package-json-location-new branch May 26, 2025 11:18
@bhanurp bhanurp added improvement Automatically generated release notes and removed safe to test Approve running integration tests on a pull request labels May 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement Automatically generated release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants