Skip to content

issue: misconfigured peerDependencies in internal packages #814

@ItamarGronich

Description

@ItamarGronich

Version Number

5.2.1

Steps to reproduce

  1. Clone the reproduction: repository https://github.com/ItamarGronich/repro-resolvers
  2. Follow the README.md in the repo root for reproduction steps.

Description

Currently the structure of this package and repo is that there's the main package at the root of the repo, and then a directory with a private package.json file for each resolver:

/
|_ package.json { /* all package publish configuration*/ }
  |_ zod
  |  |_ package.json { private: true, peerDependencies: { /* zod|etc... */} }
  |_ yup
  |  |_ package.json { private: true, peerDependencies: { /* ... */} }
  |_ etc...

So the entire thing is published as one package, while the internal packages are essentially ignored by package managers.

This means that their manifests and dependency requirements are essentially invisible to package managers. Because they aren't real packages.

This means that:

  1. package managers won't autoinstall peers because they don't know they exist
  2. no warning for missing or wrong peer dependencies
  3. package managers with have strict peer dependency resolution won't error out on wrong peers.
  4. in some package managers, even if the peer is not specifically declared in package.json, it still can be resolved from the root of the workspace because all packages are hoisted, but in pnpm for example you can set hoist: false to prevent this behavior. and if you combine that with pnpm workspaces, then zod would not be accessible to @hookform/resolvers. Thats because pnpm creates virutal sandboxes for all peer libraries, so even if zod IS installed in the workspace project, it still won't be found. You can reproduce that by checking out the pnpm-unhoisted branch on my reproductino repo.

Suggested solution

One possible solution to this issue is to restructure the package layout with workspaces.

Each resolver would be it's own package which is also published (not private).
That would also have benefits for your users because they can install a smaller more minial package with less dependencies.

How this would be structure is like this

  1. Every resolver has it's own package
  2. Code in the root src directory would be moved into a @hookforms/resolvers-core package
  3. For backwards compatibility, the old package would be kept as a wrapper around the new packages, re-exporting their functionality the same way it does today but instead of the code existing in the package, it would be imported and re-exported from the new packages.
  4. Modify the docs to reflect the new package structure and provide guidance on how to migrate to the new setup.

Expected behaviour

peerDependencies are resolved correctly for all package manager with every setting.

Relevant log output

./node_modules/@hookform/resolvers/zod/dist/zod.mjs:1:1
  × Package subpath './v4/core' is not defined by "exports" in ./node_modules/zod/package.json

 @ ./src/index.js

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions