react-hook-form / resolvers

📋 Validation resolvers: Yup, Zod, Superstruct, Joi, Vest, Class Validator, io-ts, Nope, computed-types, typanion, Ajv, TypeBox, ArkType, Valibot, effect-ts and VineJS
https://react-hook-form.com/
MIT License
1.72k stars 157 forks source link

`@hookform/resolvers` is unable to find `superstruct` when it's hoisted to the root-level and `superstruct` remains in the workspace #711

Open casr opened 3 weeks ago

casr commented 3 weeks ago

Describe the bug

@hookform/resolvers is unable to find superstruct when it's hoisted to the root-level and superstruct remains in the workspace. This likely impacts other validation packages due to it being more of a Node-resolution problem but focussing on the Superstruct example for now.

To Reproduce

You can run the following commands in a fresh directory. I used Node v20.15.0, NPM v10.7.0 for these tests.

#!/bin/sh -ex

rm -f package.json
rm -f apps/resolver-test/package.json
rm -f apps/resolver-test/test.js

# setup workspace
npm init -y
npm -w apps/resolver-test init -y --scope @repo
npm -w apps/resolver-test pkg set type=module

# installs @hookform/resolvers, superstruct at within the workspace
npm -w apps/resolver-test install @hookform/resolvers superstruct@^2

# nests superstruct@^2 into apps/resolver-test/node_modules, installs superstruct@^1 at root
npm install superstruct@^1
npm uninstall superstruct
# re-run this script with the above lines commented to observe the import not failing in later steps

echo "import { superstructResolver } from '@hookform/resolvers/superstruct'" >>apps/resolver-test/test.js
npm -w @repo/resolver-test pkg set scripts.test="node test.js"
npm -w @repo/resolver-test test

Observe at the end you get:

node:internal/modules/esm/resolve:854
  throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base), null);
        ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'superstruct' imported from /tmp/hookform-workspace-resolution/node_modules/@hookform/resolvers/superstruct/dist/superstruct.mjs
    at packageResolve (node:internal/modules/esm/resolve:854:9)
    at moduleResolve (node:internal/modules/esm/resolve:927:18)
    at defaultResolve (node:internal/modules/esm/resolve:1157:11)
    at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:383:12)
    at ModuleLoader.resolve (node:internal/modules/esm/loader:352:25)
    at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:227:38)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:87:39)
    at link (node:internal/modules/esm/module_job:86:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Expected behavior @hookform/resolvers should be able to resolve the superstruct module. Re-run the above set of commands without installing superstruct@^1 at the root-level and the test script does not error.

Additional context Perhaps the API should be modified to accept the relevant validation package. For example, that might look like:

import { createResolver } from "@hookform/resolvers/superstruct";
import * as sus from "superstruct";

const superstructResolver = createResolver(sus);