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

Expo / React Native not having support for 'events' #1847

Closed
4 tasks done
thomasgrivet opened this issue Nov 8, 2023 · 17 comments · Fixed by #1858
Closed
4 tasks done

Expo / React Native not having support for 'events' #1847

thomasgrivet opened this issue Nov 8, 2023 · 17 comments · Fixed by #1858
Assignees
Labels
bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node

Comments

@thomasgrivet
Copy link

thomasgrivet commented Nov 8, 2023

Prerequisites

Environment check

  • I'm using the latest msw version
  • I'm using Node.js version 18 or higher

Node.js version

21.1.0

Reproduction repository

https://github.com/Cocolis-1/blank-expo/tree/feat/msw

Reproduction steps

Try to start the bundler using yarn start and start your dev client.

Current behavior

You should see the following error:

iOS Bundling failed
The package at "node_modules/msw/lib/native/index.js" attempted to import the Node standard library module "events".
It failed because the native React runtime does not include the Node standard library.
Learn more: https://docs.expo.dev/workflow/using-libraries/#using-third-party-libraries

Expected behavior

MSW should not depend on node:events (if possible) so that React Native users can use it.
I think the commit introducing node:events is this one.
Let me know if I can help in any way!

Thanks!

@thomasgrivet thomasgrivet added bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node labels Nov 8, 2023
@mattcosta7
Copy link
Contributor

hmmm

I wonder if here:

private init(): void {
this.interceptor.on('request', async ({ request, requestId }) => {
/**
* @note React Native doesn't have "node:events".
*/
if (typeof setMaxListeners === 'function') {
// Bump the maximum number of event listeners on the
// request's "AbortSignal". This prepares the request
// for each request handler cloning it at least once.
// Note that cloning a request automatically appends a
// new "abort" event listener to the parent request's
// "AbortController" so if the parent aborts, all the
// clones are automatically aborted.
try {
setMaxListeners(
Math.max(defaultMaxListeners, this.currentHandlers.length),
request.signal,
)
} catch (error: unknown) {
/**
* @note Mock environments (JSDOM, ...) are not able to implement an internal
* "kIsNodeEventTarget" Symbol that Node.js uses to identify Node.js `EventTarget`s.
* `setMaxListeners` throws an error for non-Node.js `EventTarget`s.
* At the same time, mock environments are also not able to implement the
* internal "events.maxEventTargetListenersWarned" Symbol, which results in
* "MaxListenersExceededWarning" not being printed by Node.js for those anyway.
* The main reason for using `setMaxListeners` is to suppress these warnings in Node.js,
* which won't be printed anyway if `setMaxListeners` fails.
*/
if (
!(
isNodeExceptionLike(error) &&
error.code === 'ERR_INVALID_ARG_TYPE'
)
) {
throw error
}
}
}

maybe we can move to a dynamic import?

...

try {
   const events = await import("node:events")
   const {setMaxListeners, defaultMaxListeners} = events
....

or something along those lines to avoid a static build failure? and fix support?

@DogukanTansuk
Copy link

DogukanTansuk commented Nov 10, 2023

Is there any update? And how can I help?

@mattcosta7
Copy link
Contributor

Is there any update? And how can I help?

I haven't ever run anything with react-native or expo, and haven't had a chance to get everything setup

If you install patch-package and modfiy the built code of the file I showed above, to require lazily? Although that might be good enough in this case

Another option could be - if you yarn add events does that polyfill apply well enough?
EAS seems to build with node 16, but 18 is the minimum for msw. Is it possible to update to use node 18+?
(I only had a few minutes to try to get it setup this morning, and failed to do so)

@mattcosta7
Copy link
Contributor

https://github.com/browserify/events

this is the events polyfill that I believe should work across js engines and maybe good enough to replace the issue in your environment?

@mattcosta7
Copy link
Contributor

One other option might be something like - https://github.com/parshap/node-libs-react-native which uses that events module under the hood it seems (to this was a very cursory look)

@kettanaito
Copy link
Member

I wonder, do React Native bundlers support some export conditions, like react-native? We could do a placeholder module for node:events that would still be a root-level import that resolves to different things based on the environment.

// src/utils/nodeEvents.ts
export * from 'node:events'
// src/utils/nodeEvents.react-native.ts
export {}
// package.json
{
  "exports": {
    "./src/utils/nodeEvents.ts": {
      "react-native": "./src/utils/nodeEvents.react-native.ts",
      "default": "./src/utils/nodeEvents.ts"
    }
  }
}

This is a very loose example of what I mean.

@kettanaito
Copy link
Member

I went with @mattcosta7's suggestion with the lazy import of node:events in #1858. @mattcosta7, could you please give that PR a look? Does it look right to you?

@kettanaito kettanaito self-assigned this Nov 15, 2023
@DogukanTansuk
Copy link

I went with @mattcosta7's suggestion with the lazy import of node:events in #1858. @mattcosta7, could you please give that PR a look? Does it look right to you?

Did you try those changes with the bare React-Native project? Or just make the changes and build it?

@kettanaito
Copy link
Member

kettanaito commented Nov 15, 2023

@DogukanTansuk, no, I haven't. I'm not a React Native developer and I don't even have enough space on my machine to install XCode to run React Native (but I heard you don't need it?). You are free to give those changes a try by installing MSW from a particular branch/commit, which is supported by all package managers 🙌

By the way, if you work with React Native, you can help us a lot by testing this, and other things out in regards to MSW integration. We are looking for someone to pave the way for MSW integration in React Native: report issues, try releases, submit a usage example, and validate our Integration docs. If that sounds interesting to you, let me know.

@DogukanTansuk
Copy link

@kettanaito I would love to help you with that one. Me and my team currently renewing a bank application with React Native CLI. We are using MSW for mocking endpoint results on test cases. It perfectly works fine with yarn test but when we run the application it gives the error shown below in the image.

Screenshot 2023-11-16 at 9 57 22 AM

@kettanaito
Copy link
Member

@DogukanTansuk, that looks like a compiler error telling you that the file you are requiring (./mocks/native) doesn't exist. Double-check that on your side.

@kettanaito
Copy link
Member

Released: v2.0.7 🎉

This has been released in v2.0.7!

Make sure to always update to the latest version (npm i msw@latest) to get the newest features and bug fixes.


Predictable release automation by @ossjs/release.

@DogukanTansuk
Copy link

@DogukanTansuk, that looks like a compiler error telling you that the file you are requiring (./mocks/native) doesn't exist. Double-check that on your side.

In my index.js file everything looks good, there's no configuration problem. The issue was fixed with the new patch that you released.

Released: v2.0.7 🎉

This has been released in v2.0.7!

Make sure to always update to the latest version (npm i msw@latest) to get the newest features and bug fixes.

Predictable release automation by @ossjs/release.

Whoever has the same problem as mine this update will fix your issue by updating your current version of msw.

@kettanaito
Copy link
Member

@DogukanTansuk, over the moon to hear that! Thanks!

@DogukanTansuk
Copy link

@DogukanTansuk, over the moon to hear that! Thanks!

Do you want me to prepare the example with Bare React-Native CLI?

@kettanaito
Copy link
Member

kettanaito commented Nov 17, 2023

@DogukanTansuk, it's an important choice to decide what kind of example to feature. I think it's a good practice to find something in-between of real-world usage and barebone-ness, if I may say so. While we cannot feature an example of each and every possible tech the developers may be using, something like a common ground example to let them branch from would be nice.

For example, is React Native CLI commonly used? I hear a lot about projects like Metro. I think there's nothing wrong with featuring a minimal example using the stack most folks employ to build React Native apps. There's always been previous attempts to add a React Native example, which were sadly ignored by me due to the lack of time. I have a bit more resources available right now, so lets make the official React Native example happen!

I also highly recommend checking out the existing examples in terms of what and how they feature. The goal here is to be simple and general. In the context of React Native, I think the right course of action is to feature MSW for local development and for integration testing (I recommend Vitest).

@DogukanTansuk
Copy link

DogukanTansuk commented Nov 17, 2023

@DogukanTansuk, it's an important choice to decide what kind of example to feature. I think it's a good practice to find something in-between of real-world usage and barebone-ness, if I may say so. While we cannot feature an example of each and every possible tech the developers may be using, something like a common ground example to let them branch from would be nice.

For example, is React Native CLI commonly used? I hear a lot about projects like Metro. I think there's nothing wrong with featuring a minimal example using the stack most folks employ to build React Native apps. There's always been previous attempts to add a React Native example, which were sadly ignored by me due to the lack of time. I have a bit more resources available right now, so lets make the official React Native example happen!

I also highly recommend checking out the existing examples in terms of what and how they feature. The goal here is to be simple and general. In the context of React Native, I think the right course of action is to feature MSW for local development and for integration testing (I recommend Vitest).

You have two options to go with in React Native, either you choose React Native CLI or Expo CLI. Most people use Redux/Redux-Toolkit with Saga or Thunk. I can prepare a couple of project examples including Redux/Redux-Toolkit. Also, we can provide some jest test examples. Our banking project includes most of the tech stack that I mentioned. Also, we have a SaaS project which has a mobile application written with Expo CLI.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants