mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
15.97k stars 519 forks source link

Property 'TransformStream' doesn't exist on React Native #2344

Closed vonkanehoffen closed 6 days ago

vonkanehoffen commented 3 weeks ago

So when I add msw-storybook-addon to Chromatic's Storybook (v8) React Native template here (or any other React Native SB project I try for that matter) I get the following error when I run with yarn storybook:ios (same on Android too I think):

 ERROR  ReferenceError: Property 'TransformStream' doesn't exist, js engine: hermes

This is with only initialize(); and loaders: [mswLoader], before I even get to the mocking 😭

See minimal reproduction here: https://github.com/vonkanehoffen/sb-rn-msw-problem

Any ideas anyone?

I tried this suggestion: https://github.com/mswjs/msw-storybook-addon/issues/149#issuecomment-2084397975 but no luck...

edit:

Also tried adding:

  "resolutions": {
    "@mswjs/interceptors": "0.36.5"
  },

following https://github.com/mswjs/interceptors/issues/663#issuecomment-2438696632

but this just changed the error to:

ReferenceError: Property 'MessageEvent' doesn't exist, js engine: hermes
vonkanehoffen commented 3 weeks ago

Also wondering if this: https://github.com/mswjs/data/issues/306#issuecomment-2446904312 or this: https://github.com/mswjs/msw/issues/156#issuecomment-2446412743 has something to do with it....although reverting msw to 2.5.2 didn't help either.

yannbf commented 3 weeks ago

Hey @vonkanehoffen thanks for reporting this issue, and especially for providing a reproduction. I don't think this is related to the MSW addon, but rather to MSW itself. If I add this to App.jsx in your repro and run yarn ios, I get the same error:

import { setupServer } from 'msw/native'

setupServer([])

The stack trace points to this line of code in the MSW interceptors library: https://github.com/mswjs/interceptors/blob/main/src/interceptors/fetch/utils/brotli-decompress.browser.ts

@kettanaito could you take a look? Perhaps it's one of those situations where the exports map is not respecting react native and therefore it's importing a browser package that needs things that are not available.

kettanaito commented 2 weeks ago

Hi, @vonkanehoffen. Thanks for reporting this.

@yannbf, that doesn't look like an export condition issue. We rely on TransformStream because it's a globally available API everywhere. Apparently, not in React Native. That would be nice to confirm.

If that's the case, I'd address this by adding brotli-decompress.react-native.ts that exports an empty class without even extending TransformStream to skip React Native altogether. I hope there's a reliable export condition for that. One issue with this approach is that this check is currently build-time, so we'd have to add a React Native build target, which I'd rather avoid.

LuisRodriguezLD commented 2 weeks ago

I'm having the same issue If it helps, version 2.4.11 works fine but 2.4.12 onwards starts throwing the error

 ERROR  ReferenceError: Property 'TransformStream' doesn't exist, js engine: hermes
kettanaito commented 2 weeks ago

I could really use some help with this. Out-of-the-box Expo app in a pnpm monorepeo doesn't even run for me. There's clearly things that MSW needs that React Native doesn't have. The approach is either:

If someone has the time to look into this, I'd be grateful. Otherwise, I will likely close this soon because I don't have a day to tweak the React Native project to even run.

vonkanehoffen commented 2 weeks ago

Thanks so much for the replies u guys! @LuisRodriguezLD reverting to 2.4.11 works for me too, both applied directly in App.jsx and via storybook. Thanks. That's helped me loads 😁 See https://github.com/vonkanehoffen/sb-rn-msw-problem/commit/990ca35613c80cc38cd1e9763e933ae1af0541ab in case it helps anyone else.

@kettanaito I've never got Expo to run with pnpm in a monorepo either sorry. My example's just yarn in a standard repo, and that should work anywhere - yarn && yarn ios when you have Expo & Xcode setup in your dev env.

I'll take a look and see if I can figure out how to do one of the above for the latests msw version, and see how far I get (probably not very 😂 )

g-farrow commented 1 week ago

I've also hit this problem, I am not using React Native, just normal react. It seems to be introduced in 2.5.0. I have reverted to 2.4.11 and the error goes away. But any version >= 2.5.0 gives me an error:

ReferenceError: TransformStream is not defined

My node version is 20.14.0

I am using vitest with the following setup:

import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";
import { defineConfig } from "vitest/config";

const debug: boolean = false;

export default defineConfig({
  test: {
    environment: "jsdom",
    globals: true,
    unstubEnvs: true,
    coverage: {
      include: ["src/**/*.tsx", "src/**/*.ts"],
      exclude: ["src/**/*.stories.tsx", "src/components/Atoms/Icons/**", "src/**/*.test.tsx"],
      provider: "istanbul",
    },
    setupFiles: ["./vitest.setup.ts"],
    pool: "vmThreads",
  },
  plugins: [
    react(),
    tsconfigPaths({
      root: process.cwd(),
    }),
  ],
});

I have the following setup file:

import "@testing-library/jest-dom";

import * as matchers from "@testing-library/jest-dom/matchers";
import { cleanup } from "@testing-library/react";
// import "jest-canvas-mock";
import ResizeObserver from "resize-observer-polyfill";
import { afterEach, expect } from "vitest";

import { server } from "./mocks/server";

// Mock the ResizeObserver used by the HeadlessUI library
global.ResizeObserver = ResizeObserver;

// Establish API mocking before all tests.
beforeAll(() => server.listen());

// Reset any request handlers that we may add during the tests,
// so they don't affect other tests.
afterEach(() => server.resetHandlers());

// Clean up after the tests are finished.
afterAll(() => server.close());

expect.extend(matchers);

afterEach(() => {
  cleanup();
});

and this server setup file:

import { setupServer } from "msw/node";

import { handlers } from "./handlers";

// This configures a request mocking server with the given request handlers.
export const server = setupServer(...handlers);

Maybe I have done something silly with my configuration? Any help or advice would be greatly appreciated!

bennybennett commented 1 week ago

We have an almost identical setup as @g-farrow (though using jest instead of vitest), and are encountering the same issue >= 2.5.0.

PascalZajac commented 1 week ago

+1 what @bennybennett shared.

kettanaito commented 1 week ago

If you are using Jest

Please use https://github.com/mswjs/jest-fixed-jsdom. It includes TransformStream, I believe.

bennybennett commented 1 week ago

Thank you @kettanaito !! (You finally made us ask the question "Should we be using Jest?" Kudos! 🍾 )

mikelax commented 1 week ago

Thanks @kettanaito , for posterity here, I believe this became an issue due to this change in the interceptors sub-project. This looks to be where TransformStream started to be used.

kettanaito commented 6 days ago

@mikelax, yeah, you're right. We are relying on TransformStream to support proper response body decoding in Node.js (gzip, deflate, brotli). That is a standard API everywhere, has been for years.

I believe this issue is solely related to Jest, for which I've already posted a solution. I'm going to close this one.

g-farrow commented 3 days ago

hi @kettanaito I am using vitest already and the issue occurs. The browser mode in vitest is still experimental and I cannot switch to using it at this stage (it is a fairly significant migration).

I tried to use the jest-fixed-jsdom custom environment you suggested but I couldn't work out the correct configuration as vitest automatically prefixes the environment name so ends up looking for "vitest-environment-jest-fixed-jsdom".

Do you have any suggestions for Vitest specifically, please?

vonkanehoffen commented 1 day ago

@kettanaito its not solely related to Jest I don't think? My original reproduction of the problem doesn't use jest at all - I was just trying to use MSW in Storybook.

ahammer-sc commented 1 day ago

I am also having this error with vitest running in node mode with jsdom. I cannot switch to browser mode, as this is experimental and requires significant work. Also, it doesn't work with my CI flow easily. I also cannot use jest-fixed-jsdom as vitest doesnt know how to load this?

Instead, we should be able to run msw vitest with jsdom. Can you please release a vitest-environment-fixed-jsom?

lgibso34 commented 1 day ago

I'm seeing this after following the MSWJS RN setup documentation and just running my RN (non-expo) app. I am importing setupServer from msw/native.

Not jest related at all.

george-g-y-b commented 11 hours ago

@lgibso34 I faced the same issue as yourself. I resorted to using version 2.4.11 for now. Thanks @LuisRodriguezLD