Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getSearchParams is not parsing correctly when using Vite #39

Closed
DavoCg opened this issue Nov 2, 2023 · 11 comments
Closed

getSearchParams is not parsing correctly when using Vite #39

DavoCg opened this issue Nov 2, 2023 · 11 comments

Comments

@DavoCg
Copy link

DavoCg commented Nov 2, 2023

Hi,

When using Remix 2.2.0 using Vite, it seems that getSearchParams stopped parsing correctly the query params without throwing any errors.

It could be related to Request polyfill in vite adapater as mentionned here : remix-run/remix#7819

@kiliman
Copy link
Owner

kiliman commented Nov 2, 2023

Thanks for the report. I'll take a look.

@kiliman
Copy link
Owner

kiliman commented Nov 2, 2023

This is weird. When I used the following code with the remix-params-helper, it returned an error. But when I copied the helper code directly into my project, it worked correctly.

// routes/test.$id.tsx
export async function loader({ request, params }: DataFunctionArgs) {
  const resultParams = getParams(params, z.object({ id: z.string() }))
  const resultSearchParams = getSearchParams(
    request,
    z.object({ q: z.string(), page: z.number().default(1) }),
  )
  return json({ resultParams, resultSearchParams })
}

export default function Component() {
  const loaderData = useLoaderData<typeof loader>()

  return (
    <div>
      <Form>
        <input name="q" className="border" />
      </Form>
      <pre>{JSON.stringify(loaderData, null, 2)}</pre>
    </div>
  )
}

remix-params-helper package

image

inline

image

@DavoCg
Copy link
Author

DavoCg commented Nov 2, 2023

Thanks @kiliman for your quick answer. As you mentioned, I tried copying the helper directly in my codebase and everything work as expected. This is indeed pretty weird, I'll continue investigating and update here if I find something

@kiliman
Copy link
Owner

kiliman commented Nov 2, 2023

I did some more investigation. It looks like I need to make a pure ESM package. By default it was loading the CJS version, and for some reason, this code was always returning false, so it wasn't parsing properly and always failing.

function parseParams(o, schema, key, value) {
    var _a;
    // find actual shape definition for this key
    let shape = schema;
    console.log('parseParams', shape instanceof zod_1.ZodObject)
    while (shape instanceof zod_1.ZodObject || shape instanceof zod_1.ZodEffects) {
        shape =
            shape instanceof zod_1.ZodObject
                ? shape.shape
                : shape instanceof zod_1.ZodEffects
                    ? shape._def.schema
                    : null;
        if (shape === null) {
            throw new Error(`Could not find shape for key ${key}`);
        }
    }
    // ...
}

@DavoCg
Copy link
Author

DavoCg commented Nov 2, 2023

I was about to send the same finding after debugging in node_modules, const def = shape[key]; is undefined and not processed. I'll use a local version in the meantime, thanks for taking the time @kiliman !

@mauscoelho
Copy link

Sorry for recommending something different here. I needed a quick fix and started using Zodix.
The API is the same so it was an easy migration.

@kiliman
Copy link
Owner

kiliman commented Nov 6, 2023

@mauscoelho I'm glad you found something that works for you.

@hi-ogawa
Copy link

It looks like I need to make a pure ESM package. By default it was loading the CJS version, and for some reason, this code was always returning false, so it wasn't parsing properly and always failing.

I think the issue is a dual package hazard (see https://nodejs.org/api/packages.html#dual-package-hazard) of zod dependency where user code loads esm version of zod (via import) but remix-params-helper loads cjs version (via require).

I was interested in this issue since this might be a general problem which others libraries might face.
For the specific case of remix-params-helper, it already includes esm version in the package, so enforcing vite to resolve esm version can be a quick workaround available on user side.
This can be achieved by the combination of ssr.noExternal and resolve.alias like this:
https://stackblitz.com/edit/remix-run-remix-cktyfl?file=vite.config.ts

export default defineConfig({
  plugins: [remix(), tsconfigPaths()],
  ssr: {
    noExternal: ['remix-params-helper'],
  },
  resolve: {
    alias: {
      'remix-params-helper': 'node_modules/remix-params-helper/dist/helper.js',
    },
  },
});
reveal screenshot

image

I'm not familiar with remix-params-helper myself so I might missing some scenarios not covered by this workaround, but I hope this still gives some ideas of the underlying issue!

@Skoob1905
Copy link

+1 to this. an error is always returned. I'm trying to use this in my loader to parse queryParams for my API but just throws an error everytime.

@kiliman
Copy link
Owner

kiliman commented Nov 22, 2023

I'll be publishing an updated package that works properly for both CJS and ESM imports.

@kiliman
Copy link
Owner

kiliman commented Nov 22, 2023

Fixed in v0.5.0

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

No branches or pull requests

5 participants