Skip to content

Proposal: Vendor whatwg-fetch #293

@samselikoff

Description

@samselikoff

Pretender uses the whatwg-fetch package in order to intercept fetch calls.

Even though whatwg-fetch is explicitly imported here (and used here), Pretender is actually relying implicitly on whatwg-fetch's internals to get the fetch intercepting behavior working correctly.

The reason is because the fetch implementation that whatwg-fetch provides actually delegates to window.XMLHTTPRequest under the hood. Since Pretender also monkey patches window.XMLHTTPRequest, it is able to intercept fetch calls equally as well. But it's only due to those internals – due to the fact that the whatwg-fetch polyfill happens to use XMLHTTPRequest under the hood. This is not part of whatwg-fetch's public API, even though it is unlikely the change.

The reason this bit us recently is because some folks are trying to use Mirage with Next.js. Next performs some build-time optimizations to ensure apps don't include multiple or heavy versions of popular polyfills, whatwg-fetch being one of them. So, they actually swap out the package that whatwg-fetch resolves to, meaning when Pretender tries to import * from 'whatwg-fetch', it ends up with a different polyfill entirely, and one that does not happen to use XMLHTTPRequest under the hood. Therefore, Pretender (and thus Mirage) don't work.

We asked about how to opt-out of this optimizing behavior here, but as of right now the Zeit team doesn't have any plans to make the behavior configurable.

In any case, regardless of whether Next.js chooses to expose such an option, it is still true that today, Pretender is relying on internals of whatwg-fetch, and that poses a risk to Pretender in the event those internals ever change.

I'm proposing that we vendor the latest version of whatwg-fetch into Pretender directly, since we are relying on observable but undocumented behavior of its current implementation. This would give us total control over the code, and would also address the Next.js issue since whatwg-fetch would no longer be an external dependency that could be hoisted or replaced.

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