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

Allow the SDK to use native fetch #1487

Closed
icyJoseph opened this issue May 9, 2023 · 10 comments · Fixed by #1488 or #1503
Closed

Allow the SDK to use native fetch #1487

icyJoseph opened this issue May 9, 2023 · 10 comments · Fixed by #1488 or #1503
Labels
enhancement New feature or request

Comments

@icyJoseph
Copy link
Contributor

icyJoseph commented May 9, 2023

Description

As of Node 18.x.x it is possible that fetch is available in the global object, making the cross-fetch polyfill unnecessary.

Basic example

On these lines: https://github.com/meilisearch/meilisearch-js/blob/795044940b1c3c0a11ee62da87de377668b5f5ed/src/http-requests.ts#L141C1-L148C9

      const fetchFn = this.httpClient ? this.httpClient : fetch
      const result = fetchFn(constructURL.toString(), {
        ...config,
        ...this.requestConfig,
        method,
        body,
        headers,
      })

Since the above happens within an async context, we could perhaps do something like this pseudocode:

      if (typeof fetch === 'undefined') {
            await import('cross-fetch/polyfill')
      }
      const fetchFn = this.httpClient ? this.httpClient : fetch
      const result = fetchFn(constructURL.toString(), {
        ...config,
        ...this.requestConfig,
        method,
        body,
        headers,
      })

I am not sure why, but this file src/errors/meilisearch-communication-error.ts also has that polyfill.

The main motivation for this, would be that in turn cross-fetch uses node-fetch, which in turn loads other modules and such, and not all of them are necessarily at their latest versions. For example node-fetch has a v3 version out there, and since Node 18, this chain of dependencies is avoidable, by the presence of a native fetch.

I guess this constitutes a breaking change though...

@icyJoseph
Copy link
Contributor Author

It looks like it works, running docker-compose run --rm package bash -c "yarn install && yarn test && yarn lint", with both node:16 and node:18 in the docker-compose.yml file.

Though the implementation looks like:

    if (typeof fetch === 'undefined') {
        // @ts-expect-error polyfill brings in no meaningful types
        await import('cross-fetch/polyfill')
      }

      const fetchFn = this.httpClient ? this.httpClient : fetch
     

@brunoocasali
Copy link
Member

Hello @icyJoseph just to mention the maintainer of this repo is on holiday! 🌴🌴

When they are back they will check your issue and your PR! ;)

@meili-bors meili-bors bot closed this as completed in b319cc6 May 22, 2023
@bidoubiwa
Copy link
Contributor

I'm re-opening this issue. The code has been rollbacked. It introduced a failing built in some environments. See here #1496.

I didn't have time to look into it more and considered a release without that critical bug should be done as fast as possible.

See release v0.32.5

@bidoubiwa bidoubiwa reopened this May 30, 2023
@bidoubiwa bidoubiwa added the enhancement New feature or request label May 30, 2023
@icyJoseph
Copy link
Contributor Author

icyJoseph commented May 30, 2023

I haven't really worked with unenv, but if I understand correctly, rather than installing cross-fetch, it looks it up inside its presets, and there it only has node_modules/unenv/runtime/npm/cross-fetch.cjs is that's what's going on with #1496?

I'll do a bit of local testing, even within a Nitro env, when I get some time, because I think require('cross-fetch/polyfill') would suffice - I'll review why I went with a different choice (cross-fetch/dist/node-polyfill), than what I had originally proposed (see my comments above).

Looking forward

For what is worth, this change did not work for my use case either 😅 - Using Next.js with Node 18 I keep getting warnings about encoding not being resolved:

./node_modules/meilisearch/node_modules/node-fetch/lib/index.js
Module not found: Can't resolve 'encoding' in '/path-to-my/user/project/node_modules/meilisearch/node_modules/node-fetch/lib'

Import trace for requested module:
./node_modules/meilisearch/node_modules/node-fetch/lib/index.js
./node_modules/meilisearch/node_modules/cross-fetch/dist/node-ponyfill.js
./node_modules/meilisearch/node_modules/cross-fetch/dist/node-polyfill.js
./node_modules/meilisearch/dist/bundles/meilisearch.cjs.js
./src/posts/lib.ts
./src/app/og-image/[slug]/route.tsx

It still compiles and works fine though, just like it did before.

What makes this a bit more annoying is that, supabase also has this issue. It is not surprising because, fetch polyfills have been widely used the past years, so migrating away from them won't be so trivial.

I wonder if, looking forward, dropping the fetch polyfill, ought to be part of 1.x.x kind of thing - Not really sure what the release plans, goals and milestones for this project are though.

@icyJoseph
Copy link
Contributor Author

Alright I can confirm that doing:

    if (typeof fetch === 'undefined') {
      require('cross-fetch/polyfill')
    }

Fixes the issue. Tested locally with a Nitro app, w/ Node 16 and 18.

Even made sure to run a health check on the Meilisearch instance, from the Nitro app.

It also passes all tests.

Should I open a PR?

@bidoubiwa
Copy link
Contributor

Hey @icyJoseph, definitely! Thanks a lot for the investigation

@meili-bors meili-bors bot closed this as completed in 2d2c7f2 May 31, 2023
@CapitaineToinon
Copy link

CapitaineToinon commented Jul 7, 2023

Commenting here because I think it's related but using Meilisearch in a Next 13 app gives me this warning, despite cross-fetch not being imported:

./node_modules/.pnpm/[email protected]/node_modules/node-fetch/lib/index.js
Module not found: Can't resolve 'encoding' in '/Users/antoine/Documents/www/speedsouls-bachelor/node_modules/.pnpm/[email protected]/node_modules/node-fetch/lib'

Import trace for requested module:
./node_modules/.pnpm/[email protected]/node_modules/node-fetch/lib/index.js
./node_modules/.pnpm/[email protected]/node_modules/cross-fetch/dist/node-ponyfill.js
./node_modules/.pnpm/[email protected]/node_modules/cross-fetch/dist/node-polyfill.js
./node_modules/.pnpm/[email protected]/node_modules/meilisearch/dist/bundles/meilisearch.cjs.js
./lib/meilisearch/search.ts
./components/search/command.tsx
./components/navbar.tsx

Apparently superbase has a similar problem. Just a warning so nothing that prevents me from deploying but maybe there is a way to fix this from the meilisearch side.

@icyJoseph
Copy link
Contributor Author

icyJoseph commented Jul 7, 2023

@CapitaineToinon this was what I set out to fix, but supporting all environments, while also conditionally importing was a bit more difficult than I initially thought.

See my comment above for more detail.

@CapitaineToinon
Copy link

Oh sorry I missed that message. Thank you for clearing that up! 👍

@icyJoseph
Copy link
Contributor Author

No worries. There are now tests for various environments, including nitro and I understand the codebase better, so I might try it once again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
4 participants