msw icon indicating copy to clipboard operation
msw copied to clipboard

Cannot find module msw/node after updating

Open joshbenhamou opened this issue 1 year ago • 25 comments

Prerequisites

Environment check

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

Node.js version

21.4.0

Reproduction repository

https://github.com/mswjs/examples/tree/main/examples/with-vitest

Reproduction steps

The issue is happening in the official MSW Vitest example. Check out the sandbox link and see the typescript error https://codesandbox.io/p/sandbox/github/mswjs/examples-new/tree/main/examples/with-vitest?file=%2Fmocks%2Fnode.ts%3A2%2C32-3%2C1

Current behavior

Import validation fails

Expected behavior

Import validation succeeds

joshbenhamou avatar Jan 10 '24 16:01 joshbenhamou

Hi, @joshbenhamou. I've just updated all the examples to the latest version of MSW and they all pass. Could you please confirm your issue is solved?

kettanaito avatar Jan 15 '24 09:01 kettanaito

Thanks @kettanaito . The sandbox link is no longer working for me in https://github.com/mswjs/examples/tree/main/examples/with-vitest. However, I saw that you updated the MSW package to 2.0.14 and tried that locally. Same problem with that version and also with 2.1.3

joshbenhamou avatar Jan 22 '24 20:01 joshbenhamou

Oh, thanks for pointing out the broken sandboxes! Caused by renaming the repo and deleting the old one. Will fix.

Edit: the sandbox is running properly now but it doesn't seem CodeSandbox allows us to use terminal anymore to run tests. You may want to check that example locally.

kettanaito avatar Jan 25 '24 12:01 kettanaito

Thanks. The sandbox is working for me now. It looks like the change you've made that is the module and moduleResolution in the tsconfig.json. Trying this locally, raises typescript errors across every import. I need to look into this further but happy for you to close the issue as it's working on the demo. If you could explain a little behind the rationale of the compiler option changes that'd be nice though

joshbenhamou avatar Jan 26 '24 15:01 joshbenhamou

I'm experiencing the same issue, but no changes to module/moduleResolution seem to resolve it in my project.

I do notice that the sandbox is a major version behind on both vitest and resolved vite version.. that being said, after bumping these, I still cannot reproduce the issue in the sandbox 🙃

iChip avatar Jan 26 '24 18:01 iChip

Same as @iChip , it's still not working for me but I haven't had the time to investigate yet unfortunately

joshbenhamou avatar Feb 02 '24 13:02 joshbenhamou

Same thing happens for me. My setup is Remix, Cloudflare Workers, Playwright with following configs:

    ...
    "moduleResolution": "Bundler",
    "module": "ES2022",
    "resolveJsonModule": true,
    "target": "ES2022",
    ...
/** @type {import('@remix-run/dev').AppConfig} */
export default {
  ignoredRouteFiles: [`**/.*`],
  server: `./app/server.ts`,
  serverConditions: ['workerd', 'worker', 'browser'],
  serverDependenciesToBundle: [
    // bundle everything except the virtual module for the static content manifest provided by wrangler
    /^(?!.*\b__STATIC_CONTENT_MANIFEST\b).*$/,
  ],
  serverMainFields: [`browser`, `module`, `main`],
  serverMinify: true,
  serverModuleFormat: `esm`,
  serverPlatform: `neutral`,
  browserNodeBuiltinsPolyfill: {
    modules: {
      buffer: true,
    },
  },
  serverNodeBuiltinsPolyfill: {
    modules: ['util', 'crypto'],
  },
}

Do we have any ideas what might be the cause?

I am willing to give a stab and fixing it if there is a person who could point me to a direction!

sampolahtinen avatar Apr 22 '24 08:04 sampolahtinen

Just want to chime and and mention I am upgrading MSW from 1.3.3 to 2.2.13 and receive the same error

Package path ./node is not exported from package /Users/damien/Documents/Git/Maia/monorepo/node_modules/msw (see exports field in /Users/damien/Documents/Git/Maia/monorepo/node_modules/msw/package.json)

My scripts is very basic

import { setupServer, type SetupServer } from 'msw/node';

import { handlers } from './handlers';

export const server: SetupServer = setupServer(...handlers);

DamienDeloubes avatar May 02 '24 19:05 DamienDeloubes

I'm also running into the same issue after upgrading. My use case is to mock out API responses for components using Storybook and the MSW addon. I tried upgrading everything together -- MSW to v2, msw-storybook-addon to v2, Storybook from v7 to v8 -- but no matter what I try I'm getting the same error as @DamienDeloubes.

I tried the hacky solution mentioned in another issue but that still caused errors with any component's Storybook file that was using the MSW addon. I've tried adjusting my tsconfig.json and tweaking my Storybook Webpack config to no avail. I'm also not using the app router so there's no conflict there. Does anyone have any other ideas?

erichartline avatar May 07 '24 13:05 erichartline

IDK if this will help you, but I had a similar issue and found that the hacky solution only worked if I removed the !isServer clause, i.e. not adding an alias for 'msw/node' for the client build. I posted my solution at https://github.com/mswjs/msw/issues/1877#issuecomment-2099139075

NateWilliams2 avatar May 07 '24 19:05 NateWilliams2

IDK if this will help you, but I had a similar issue and found that the hacky solution only worked if I removed the !isServer clause, i.e. not adding an alias for 'msw/node' for the client build. I posted my solution at #1877 (comment)

Thanks for the idea. Unfortunately, I'm still getting the Package path ./node is not exported from package node_modules/msw when trying to access any stories using MSW. I've tried every variation of the Webpack config I can think of to no avail. Glad you were able to find a solution though!

erichartline avatar May 07 '24 21:05 erichartline

With the help from @phryneas, we've done some improvements in the export conditions in MSW. Please upgrade to [email protected] and let me know if you still experience the Package path ./node is not exported from package node_modules/msw error. Thanks!

kettanaito avatar May 08 '24 18:05 kettanaito

With the help from @phryneas, we've done some improvements in the export conditions in MSW. Please upgrade to [email protected] and let me know if you still experience the Package path ./node is not exported from package node_modules/msw error. Thanks!

Hmm, I still seem to encounter the same error when pinning the msw package to 2.3.0.

Module not found: Package path ./node is not exported from package /Users/damien/Documents/Git/Maia/monorepo/node_modules/msw (see exports field in /Users/damien/Documents/Git/Maia/monorepo/node_modules/msw/package.json)

DamienDeloubes avatar May 13 '24 07:05 DamienDeloubes

I am also still receiving the same error when trying to run/build Storybook (which uses MSW pretty heavily).

erichartline avatar May 13 '24 14:05 erichartline

You will still need to ensure that you have a node import condition specified in your bundler setup - but now, it will work with both node and browser specified, where before it only worked if you had only node (without bundler) specified.

phryneas avatar May 13 '24 18:05 phryneas

import { setupServer, type SetupServer } from 'msw/node';

import { handlers } from './handlers';

export const server: SetupServer = setupServer(...handlers);

Thanks for your input! What do you mean exactly? For example, I am working in a NextJS repository with MSW used for mocking endpoints. The setup looks fairly straightforward, this has always worked for us:

import { setupServer, type SetupServer } from 'msw/node';

import { handlers } from './handlers';

export const server: SetupServer = setupServer(...handlers);

However, I am still encountering the build issue as described above. How would I go about resolving that issue?

DamienDeloubes avatar May 14 '24 12:05 DamienDeloubes

Are you using vitest? Here's an example vite.config.js:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  resolve: {
    // this line is important so the "browser build" of dependencies is used
    // and not the "SSR build", which would contain "streaming-to-the-browser"
    // specific code
   // "node" is important so it picks up the right msw import.
    conditions: ["browser", "node"],
  },
  test: {
    globals: true,
    environment: "jsdom",
  },
});

phryneas avatar May 14 '24 17:05 phryneas

Unfortunately not vite, just a plain NextJS project

DamienDeloubes avatar May 14 '24 17:05 DamienDeloubes

So you are trying to mock the network access inside of React Server Components? I'm not sure if that's supported. Also, afaik Next.js simulates their edge runtime in some cases - not sure if you can mock anything in that environment.

phryneas avatar May 14 '24 18:05 phryneas

Sorry, I see I was a bit unclear. I have a NextJS project where I use Redux Toolkit Query. For the past year, I have used MSW to make the requests made by RTQ. Unfortunately when I upgraded the MSW package I got the error described in this thread, moving back to an older version fixes everything. So I don't want to mock server components, just the rtq apis.

DamienDeloubes avatar May 14 '24 18:05 DamienDeloubes

So, still pages router. Maybe @kettanaito knows something on how to set that up - you'll need some additional bundler config.

phryneas avatar May 14 '24 18:05 phryneas

Next.js uses webpack, so you have to add a webpack property in next.config.js and add the node condition to webpack's module resolution logic:

// next.config.js
module.exports = {
  webpack(config) {
    config.resolve.conditionNames = ['node', ...webpackDefaultConditions]
  }
}

resolve.conditionNames

The above is made-up, you have to read Next.js docs if that's the right way to extend webpack.

kettanaito avatar May 15 '24 14:05 kettanaito

Having the same issue in a React, Vite, Jest project. Although the setup works for our React Native app (RN/Metro/Jest) 🤔

hnipps avatar Aug 09 '24 19:08 hnipps

Setting customExportConditions to 'node' seems to have fixed the issue for me.

testEnvironment: 'jest-environment-jsdom',
testEnvironmentOptions: {
  customExportConditions: ['node'],
},

Full Jest config:

import type { Config } from 'jest';

const config: Config = {
  cacheDirectory: '.jest/cache',
  collectCoverage: true,
  collectCoverageFrom: ['<rootDir>/src/**/*.{js,jsx,ts,tsx}', '!<rootDir>/src/**/env-variables.ts'],
  coverageReporters: ['lcov'],
  moduleDirectories: ['node_modules', 'src', 'test'],
  testMatch: ['<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}', '<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}'],
  moduleNameMapper: {
    '\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/__mocks__/filemock.ts',
    '\\.(css|less)$': '<rootDir>/__mocks__/filemock.ts',
  },
  setupFiles: ['<rootDir>/jest.polyfills.js'],
  setupFilesAfterEnv: ['<rootDir>/mock-api/setup.js'], // MSW setup file
  testEnvironment: 'jest-environment-jsdom',
  testEnvironmentOptions: {
    customExportConditions: ['node'],
  },
};

export default config;

The default customExportCondition is 'browser' and I believe this caused Jest module resolver to look at the browser key in the ./node block of MSW package.json exports, which is set to null. Hence the "Cannot find module" error.

By setting customExportConditions to 'node' we tell the module resolver to look at the node key of the ./node block in package.json exports, which leads us to the correct module 🎉

hnipps avatar Aug 09 '24 19:08 hnipps

I am also still receiving the same error when trying to run/build Storybook (which uses MSW pretty heavily).

An update from my end - I was able to bypass this issue by avoiding importing any mock handler functions from files that were also importing from msw/node. Even though I wasn't using anything from msw/node directly, my Storybook builds would still break. By separating the functions from any references to the node version of the mock server, I was able to get past the issue.

erichartline avatar Aug 13 '24 02:08 erichartline