Hey, I’ve been looking a bit at how we could provide support for running unmock also in browser and other JS environments. Making
unmock an isomorphic package that runs anywhere sounds great, but after some research it looks to me that it could be quite hard to maintain and the codebase could become too messy. Therefore, I think we should maybe consider going back to unmock-0.0.x -style: having separate packages for browser and other JS environments, leaving “unmock” to be the Node package and, for example, “unmock-browser” to be the browser package. Then it might also be simpler to create a standalone bundle of browser package if that's needed. And separate packages would also add more decoupling to the codebase, which is always nice.
Providing different packages for different environments also has some disadvantages, the two I can see being (1) need to write some environment-specific documentation, (2) possible confusion in server-side rendering frameworks like in Next.js, where one then needs to add a package both for the server and browser instead of just one.
What do you think?
Continuing on the topic of isomorphic packages, one possibility might be to create multiple builds from "unmock" and then use package.json's
react-native to point to different entry points like this unmock/unmock-js#310
The drawback is that every implementation's every dependency is then a dependency of
unmock, but only those required by the current environment are actually used. But I guess that's a problem with any isomorphic package.
Made a sketch for
unmock-fetch, a package that would define a fetch interceptor by overriding
window.fetch and, for Unmock's use, would also export
fetch that would work like
fetch but use Unmock behind the scenes. unmock/unmock-js#312
I think the package could be generally useful in the same way as
node-mitm, so probably the "unmock algorithm" should not be part of the package.
If we go with a package structure like this, I would see additional packages like
unmock-react-native that implements "Backend" with
unmock-fetch as interceptor and
unmock-node doing the same thing with
node-mitm. Also possibly
unmock-types would be needed if
unmock-fetch did not depend on the "core".
I did not yet think about monkey patching XMLHttpRequest, is someone still using that? I also understood that
fetch API is independent of
XMLHttpRequest in modern environments so that
fetch cannot be patched by patching
fetchso one would also need to patch
XMLHttpRequest. But isomorphic fetch packages like "cross-fetch" and "isomorphic-fetch" are very popular as well so we'd cover a lot of ground already by patching
fetch. But yep, I can see us then also releasing
unmock-xml-http-requestthat provides a simple API to intercept and mock XMLHttpRequest. And for example
unmock-browserwould then wrap both
XMLHttpRequestinterceptors as one interceptor.
node-fetchfrom a dependency in
unmock-core(https://github.com/unmock/unmock-js/blob/dev/packages/unmock-core/src/index.ts). I had originally created
unmock-fetchin case we eventually wanted to link testing to production traffic, but no one seems to dig the idea, so it's probably best to just get rid of it. That means that we'll have to update our examples to use
unmock.fetch, but the API is the same.
Added all of your notes about telemetry to the initial doc, thanks!
Also @ksaaskil question for you re: some of our tests. I'm running with this idea of adding more meaningful placeholders and stumbled across this test in the unmock-node package: https://github.com/unmock/unmock-js/blob/dev/packages/unmock-node/src/__tests__/index.test.ts#L38-L44
What is this testing for exactly? I'm trying to think of a better replacement for "foo" (maybe var, data, whatever) but also curious about whether or not we actually need this test.
unmock-serverbranch - it is pretty cool stuff! If the project develops further, I wonder if/when a
libunmockwill be in order? It makes sense to start with NodeJS as that is our most developed library, but at a certain point, having the whole stack in TypeScript seems like a disadvantage if the goal is to deploy it as a stand-alone or embedded entity. I'm wondering how we could test that out 🤔