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

Can't resolve '@mswjs/interceptors/lib/interceptors/ClientRequest' #1267

Closed
4 tasks done
ntucker opened this issue Jun 1, 2022 · 29 comments · Fixed by #1399
Closed
4 tasks done

Can't resolve '@mswjs/interceptors/lib/interceptors/ClientRequest' #1267

ntucker opened this issue Jun 1, 2022 · 29 comments · Fixed by #1399
Labels
bug Something isn't working needs:triage Issues that have not been investigated yet. scope:browser Related to MSW running in a browser

Comments

@ntucker
Copy link

ntucker commented Jun 1, 2022

Prerequisites

Environment check

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

Browsers

NODE 16/18

Reproduction repository

https://github.com/coinbase/rest-hooks/tree/a3963b2618981992bab115a8e8543abdb9cdc655/website

Gonna revert MSW upgrade to make this work so master will no longer have this problem.

Reproduction steps

  1. clone repo above
  2. git checkout a3963b2618981992bab115a8e8543abdb9cdc655
  3. navigate to website folder
  4. yarn install
  5. yarn start
  6. observe error in cli as well as opened browser tab

Current behavior

ERROR in ./node_modules/msw/lib/node/index.mjs 45:0-94

Module not found: Error: Can't resolve '@mswjs/interceptors/lib/interceptors/ClientRequest' in '/home/ntucker/src/rest-hooks/website/node_modules/msw/lib/node'
Did you mean 'index.js'?
BREAKING CHANGE: The request '@mswjs/interceptors/lib/interceptors/ClientRequest' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.

#1247 breaks in node versions that support ESM

Expected behavior

To fix this - the ESM version of MSW must be explicit about file extensions. Otherwise it is by definition incorrectly built. If this cannot be done you should not ship a custom ESM version as this is incorrect. The only reason it would work is if it is used by a system that doesn't enforce fully (webpack). However this will break in fully-spec compliant things like node.

More simply:

import '@mswjs/interceptors/lib/interceptors/ClientRequest' => import '@mswjs/interceptors/lib/interceptors/ClientRequest.mjs'

@ntucker ntucker added bug Something isn't working needs:triage Issues that have not been investigated yet. scope:browser Related to MSW running in a browser labels Jun 1, 2022
@kettanaito
Copy link
Member

Hey, @ntucker. Thanks for reporting this.

To fix this - the ESM version of MSW must be explicit about file extensions.

That's an interesting part: MSW doesn't publish an ESM version as of now. The /lib/ import you see is CommonJS. We don't have official support for ESM, I need to look into proper ESM bundling with tsup because the factory esm build target produced a module that breaks for consumers (see #1252).

Can you try this on 0.41.0 and 0.40.x? Does it work on the latter version?

@ntucker
Copy link
Author

ntucker commented Jun 2, 2022

node_modules/msw/lib/node/index.mjs is commonjs? Mjs extensions should only be used for esm

@ntucker
Copy link
Author

ntucker commented Jun 2, 2022

node_modules/msw/lib/node/index.mjs is commonest? Mjs extensions should only be used for esmwhat is #1247 about then? It adds mjs extensions

@kettanaito
Copy link
Member

Oh, you're right, we do publish ESM but only for msw/node:

format: ['esm', 'cjs'],

🤦 I'm tried of dancing around with builds. We should remove all ESM build targets. The Interceptors library is (always was) CommonJS. So if the parent module (msw/node) is ESM it won't be able to use it.

I have a suspicion that ESM mean different things in different bundles. We used to have ESM build with Rollup for years but that shouldn't have worked (I've described why above). So confused.

@ntucker
Copy link
Author

ntucker commented Jun 3, 2022

I believe importing is fine... you just have to specify the file extension anytime you're in an esm.

@kettanaito
Copy link
Member

@ntucker, yeah, that's the problem: how to do that in an ambiguous context?

The source code compiles to multiple targets, so I don't see specifying file extensions all the time as a sensible strategy. Moreover, it raises a compilation error in TS, which forces you not to include extensions. It seems like this should be done by the bundler automatically since it's the bundle that's aware of the build target (ESM) and should provide all the necessary transformations for the source code to produce a valid target code.

I'm looking for help with the proper library bundling, so anybody experienced with this is welcome to join the discussion or open a pull request. Thanks.

@ntucker
Copy link
Author

ntucker commented Jun 9, 2022

Ts doesn't force you to not use extensions. If you add .js it will still look for .d.ts etc. See my project for example bundling: https://github.com/coinbase/rest-hooks

@ntucker
Copy link
Author

ntucker commented Jun 9, 2022

@ntucker
Copy link
Author

ntucker commented Aug 1, 2022

Again, this implementation is against spec so it will break in all environments that implement spec correctly: https://nodejs.org/api/esm.html#mandatory-file-extensions

@daKmoR
Copy link

daKmoR commented Aug 28, 2022

simplest way to reproduce it is

👉 test.mjs

import { setupServer } from 'msw/node';

execute in the console

node test.mjs

will result in

$ node test.mjs
node:internal/process/esm_loader:97
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/html/rocket/node_modules/msw/node' is not supported resolving ES modules imported from /html/rocket/test.mjs
Did you mean to import msw/lib/node/index.js?
    at new NodeError (node:internal/errors:387:5)
    at finalizeResolution (node:internal/modules/esm/resolve:400:17)
    at moduleResolve (node:internal/modules/esm/resolve:965:10)
    at defaultResolve (node:internal/modules/esm/resolve:1173:11)
    at nextResolve (node:internal/modules/esm/loader:173:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:852:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:439:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
    at link (node:internal/modules/esm/module_job:75:36) {
  code: 'ERR_UNSUPPORTED_DIR_IMPORT',
  url: 'file:///html/rocket/node_modules/msw/node'
}

Node.js v18.7.0

Is there a plan to go to esm? or to support esm entrypoints?

See node docs for conditional entry points for esm & cjs

https://nodejs.org/api/packages.html#packages_conditional_exports

@kettanaito
Copy link
Member

Is there a plan to go to esm? or to support esm entrypoints?

Yes, there is a plan. Contributions are extremely welcome to make this plan a reality. This particular support doesn't interest me at the moment so I'm unlikely to spend time on it. But I'm always open to providing code reviews and making this support happen.

@ntucker
Copy link
Author

ntucker commented Aug 30, 2022

I would personally be happy with ESM targets being removed until properly impelemented

@raulfdm
Copy link

raulfdm commented Sep 7, 2022

just started having this issue using msw@0.47.0 + ts@4.8.2 + next@12.2.5.

Is there a workaround til this is fixed but scripting the node_modules?

@raulfdm
Copy link

raulfdm commented Sep 7, 2022

Workaround: downgrade to 0.46.1

@mattcosta7
Copy link
Contributor

mattcosta7 commented Sep 7, 2022

just started having this issue using msw@0.47.0 + ts@4.8.2 + next@12.2.5.

Is there a workaround til this is fixed but scripting the node_modules?

where did you start noticing the issue on the msw/node side? curious if you would mind trying some steps to triage

in node_modules/msw/node/package.json remove the module entry - and in node_modules/msw/package.json

 "./node": {
      "require": "./lib/node/index.js",
      "default": "./lib/node/index.mjs"
    }

make the default the index.js build - removing the require option

then restart and see if that allows a build to succeed. if so, we might consider dropping the esm node build for now, until we can handle that directly

@raulfdm
Copy link

raulfdm commented Sep 7, 2022

just started having this issue using msw@0.47.0 + ts@4.8.2 + next@12.2.5.
Is there a workaround til this is fixed but scripting the node_modules?

where did you start noticing the issue on the msw/node side or the msw direct side?

msw/node. In the client it was working fine but the server part was broken

@mattcosta7
Copy link
Contributor

mattcosta7 commented Sep 7, 2022

just started having this issue using msw@0.47.0 + ts@4.8.2 + next@12.2.5.
Is there a workaround til this is fixed but scripting the node_modules?

where did you start noticing the issue on the msw/node side or the msw direct side?

msw/node. In the client it was working fine but the server part was broken

I added a few triage steps to my last message, if you wouldn't mind giving them a shot, and describing output. it might help with getting that fixed a bit

I think we probably never used the module import from msw/node directly, since the package.json wasn't type: module there, and in https://github.com/mswjs/msw/pull/1383/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519R15-R16 that might not be compat.

@ivanhofer curious if you've seen that working on your end properly

@ivanhofer
Copy link
Contributor

just started having this issue using msw@0.47.0 + ts@4.8.2 + next@12.2.5.
Is there a workaround til this is fixed but scripting the node_modules?

where did you start noticing the issue on the msw/node side or the msw direct side?

msw/node. In the client it was working fine but the server part was broken

I added a few triage steps to my last message, if you wouldn't mind giving them a shot, and describing output. it might help with getting that fixed a bit

I think we probably never used the module import from msw/node directly, since the package.json wasn't type: module there, and in #1383 (files) that might not be compat.

@ivanhofer curious if you've seen that working on your end properly

It is working for me, because I'm using it in a cjs context. I would assume this fixes it for esm: #1395
I didn't spot that the esm file didn't have a d.ts file in the last PR.

Belco90 added a commit to octochangelog/octochangelog-webapp that referenced this issue Sep 7, 2022
@Vinnl
Copy link

Vinnl commented Sep 8, 2022

@mattcosta7 I'm also only experiencing this problem since that upgrade (see the build error) and just tried your triage steps in my project. I can confirm that after those steps, the build completed successfully, so it might indeed be worth dropping esm from the Node build for now.

(Alternatively, only using default exports when importing from CJS modules in an ES module might also fix actual ES module support.)

@ivanhofer
Copy link
Contributor

ivanhofer commented Sep 10, 2022

I have investigated this issue a bit. There are a few road blocks to make msw/node work in a .mjs file:

  1. reference lib/index.js instead of 'lib' in a few files (easy to achive)
  2. tsup does not support import assertions (needed here https://github.com/mswjs/msw/blob/main/src/context/status.ts#L1) import assertion get removed from output egoist/tsup#714
  3. dynamic import of node-fetch (https://github.com/mswjs/msw/blob/main/src/context/fetch.ts#L6) is not supported in esm context. How to fix "Dynamic require of "os" is not supported" evanw/esbuild#1921

@ivanhofer
Copy link
Contributor

ivanhofer commented Sep 11, 2022

I have created a draft PR that fixes point nr. 1. If anyone knows a solution to the other points. Feel free to contribute.

Belco90 added a commit to octochangelog/octochangelog-webapp that referenced this issue Sep 11, 2022
Belco90 added a commit to octochangelog/octochangelog-webapp that referenced this issue Sep 11, 2022
Belco90 added a commit to octochangelog/octochangelog-webapp that referenced this issue Sep 11, 2022
Belco90 added a commit to octochangelog/octochangelog-webapp that referenced this issue Sep 14, 2022
Belco90 added a commit to octochangelog/octochangelog-webapp that referenced this issue Sep 14, 2022
Belco90 added a commit to octochangelog/octochangelog-webapp that referenced this issue Sep 15, 2022
* introduce ConditionallyRender component

* install msw

* add env vars for api mocking

* init mock service worker

* remove unused stuff

* remove unnecessary cookie option

* add a handler for testing library repo search

* add a renovate results for repo search handler

* improve chained repos search results

* throw error on unhandled requests to github api

* simplify fixtures search import

* basic repo releases mocking for dom-testing-library

* update msw to latest

* disable next lint during building

* add tests for paginateList util

* downgrade eslint to prevent issue in WebStorm

ESLint 8.23.0 causes an issue in WebStorm https://youtrack.jetbrains.com/issue/WEB-57089/ESLint823-TypeError-thislibOptionsparse-is-not-a-function

Should be solved in WebStorm 2022.2.2

* improve paginateList tests

* paginate github repo releases

* add extra test for paginateList

* update msw to latest

* mock repos details request with MSW

* add renovate fixtures to msw handlers

* enable api mocking by default

* adapt Cypress tests to MSW mocks

* improve GitHub API host comparison in MSW

* Docs improvements from PR suggestions

Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>

* msw setup refactor

* downgrade msw to avoid ESM bug

More details here: mswjs/msw#1267

* update cypress to v10.7.0

* update msw to latest

* downgrade msw to avoid ESM bug

More details here: mswjs/msw#1267

* remove unnecessary cookie mock for cypress e2e

* remove unnecessary local env var for e2e in CI

* refactor ignored hosts

* refactor githubReposDetailsHandlers

* mock network error on Cypress e2e properly

* extract msw hook

* extract waitForApiMocking Cypress command

* supress happotask type errors

* more CONTRIBUTING suggestions

Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>

* Update CONTRIBUTING.md

Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>

* more text nitpicks

Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>

* update cypress to v10.8.0

* pass e2e flag to e2e commands

* increase timeout for test case when loading more than 10 pages

* regenerate lock

Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
ivanhofer added a commit to ivanhofer/msw that referenced this issue Sep 15, 2022
knokmki612 added a commit to npocccties/chiloportal that referenced this issue Oct 3, 2022
CJSとして読み込み実行することで対処

ref mswjs/msw#1267 (comment)

```
error - unhandledRejection: Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/var/home/kimiaki/Workspace/github.com/npocccties/chiloportal/frontend/node_modules/@mswjs/interceptors/lib/interceptors/ClientRequest' is not supported resolving ES modules imported from /var/home/kimiaki/Workspace/github.com/npocccties/chiloportal/frontend/node_modules/msw/lib/node/index.mjs
Did you mean to import @mswjs/interceptors/lib/interceptors/ClientRequest/index.js?
    at new NodeError (node:internal/errors:387:5)
    at finalizeResolution (node:internal/modules/esm/resolve:425:17)
    at moduleResolve (node:internal/modules/esm/resolve:1006:10)
    at defaultResolve (node:internal/modules/esm/resolve:1214:11)
    at nextResolve (node:internal/modules/esm/loader:165:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:844:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:431:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
    at link (node:internal/modules/esm/module_job:75:36) {
  code: 'ERR_UNSUPPORTED_DIR_IMPORT',
  url: 'file:///var/home/kimiaki/Workspace/github.com/npocccties/chiloportal/frontend/node_modules/@mswjs/interceptors/lib/interceptors/ClientRequest'
}
```
knokmki612 added a commit to npocccties/chiloportal that referenced this issue Oct 3, 2022
CJSとして読み込み実行することで対処

ref mswjs/msw#1267 (comment)

```
error - unhandledRejection: Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/var/home/kimiaki/Workspace/github.com/npocccties/chiloportal/frontend/node_modules/@mswjs/interceptors/lib/interceptors/ClientRequest' is not supported resolving ES modules imported from /var/home/kimiaki/Workspace/github.com/npocccties/chiloportal/frontend/node_modules/msw/lib/node/index.mjs
Did you mean to import @mswjs/interceptors/lib/interceptors/ClientRequest/index.js?
    at new NodeError (node:internal/errors:387:5)
    at finalizeResolution (node:internal/modules/esm/resolve:425:17)
    at moduleResolve (node:internal/modules/esm/resolve:1006:10)
    at defaultResolve (node:internal/modules/esm/resolve:1214:11)
    at nextResolve (node:internal/modules/esm/loader:165:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:844:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:431:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
    at link (node:internal/modules/esm/module_job:75:36) {
  code: 'ERR_UNSUPPORTED_DIR_IMPORT',
  url: 'file:///var/home/kimiaki/Workspace/github.com/npocccties/chiloportal/frontend/node_modules/@mswjs/interceptors/lib/interceptors/ClientRequest'
}
```
knokmki612 added a commit to npocccties/chiloportal that referenced this issue Oct 3, 2022
CJSとして読み込み実行することで対処

ref mswjs/msw#1267 (comment)

```
error - unhandledRejection: Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/var/home/kimiaki/Workspace/github.com/npocccties/chiloportal/frontend/node_modules/@mswjs/interceptors/lib/interceptors/ClientRequest' is not supported resolving ES modules imported from /var/home/kimiaki/Workspace/github.com/npocccties/chiloportal/frontend/node_modules/msw/lib/node/index.mjs
Did you mean to import @mswjs/interceptors/lib/interceptors/ClientRequest/index.js?
    at new NodeError (node:internal/errors:387:5)
    at finalizeResolution (node:internal/modules/esm/resolve:425:17)
    at moduleResolve (node:internal/modules/esm/resolve:1006:10)
    at defaultResolve (node:internal/modules/esm/resolve:1214:11)
    at nextResolve (node:internal/modules/esm/loader:165:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:844:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:431:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
    at link (node:internal/modules/esm/module_job:75:36) {
  code: 'ERR_UNSUPPORTED_DIR_IMPORT',
  url: 'file:///var/home/kimiaki/Workspace/github.com/npocccties/chiloportal/frontend/node_modules/@mswjs/interceptors/lib/interceptors/ClientRequest'
}
```
@t18n
Copy link

t18n commented Oct 31, 2022

White we are waiting for the PR to be merged, here is my temporary fix with yarn patch (available only with Yarn 2, if you don't use yarn 2, try patch-package).

Export of the msw-npm-0.47.4-c11a8d2944.patch file

diff --git a/lib/node/index.mjs b/lib/node/index.mjs
index 2cce41056acf9178a73d624db6319e8b7c2f1536..bbe0f4c42cd6cd3cec114c0ac76c5eec2b00ad22 100644
--- a/lib/node/index.mjs
+++ b/lib/node/index.mjs
@@ -42,11 +42,13 @@ import { setTimeout as nodeSetTimeout } from "timers";
 var setTimeout = nodeSetTimeout;
 
 // src/node/setupServer.ts
-import { ClientRequestInterceptor } from "@mswjs/interceptors/lib/interceptors/ClientRequest";
-import { XMLHttpRequestInterceptor } from "@mswjs/interceptors/lib/interceptors/XMLHttpRequest";
+import { ClientRequestInterceptor } from "@mswjs/interceptors/lib/interceptors/ClientRequest/index.js";
+import { XMLHttpRequestInterceptor } from "@mswjs/interceptors/lib/interceptors/XMLHttpRequest/index.js";
 
 // src/node/createSetupServer.ts
-import { bold } from "chalk";
+import chalk from 'chalk';
+const { bold } = chalk;
+
 import { isNodeProcess as isNodeProcess3 } from "is-node-process";
 import { StrictEventEmitter } from "strict-event-emitter";
 import {
@@ -256,7 +258,7 @@ function isStringEqual(actual, expected) {
 }
 
 // src/context/status.ts
-import statuses from "statuses/codes.json";
+import statuses from "statuses/codes.json" assert {type: "json"};;
 var status = (statusCode, statusText) => {
   return (res) => {
     res.status = statusCode;
@@ -409,7 +411,9 @@ var errors = (errorsList) => {
 // src/context/fetch.ts
 import { isNodeProcess as isNodeProcess2 } from "is-node-process";
 import { Headers } from "headers-polyfill";
-var useFetch = isNodeProcess2() ? __require("node-fetch") : window.fetch;
+import nodeFetch from 'node-fetch';
+
+var useFetch = isNodeProcess2() ? nodeFetch : window.fetch;
 var augmentRequestInit = (requestInit) => {
   const headers = new Headers(requestInit.headers);
   headers.set("x-msw-bypass", "true");
@@ -575,7 +579,7 @@ function prepareResponse(res) {
 
 // src/utils/matching/matchRequestUrl.ts
 import { match } from "path-to-regexp";
-import { getCleanUrl } from "@mswjs/interceptors/lib/utils/getCleanUrl";
+import { getCleanUrl } from "@mswjs/interceptors/lib/utils/getCleanUrl.js";
 
 // src/utils/url/cleanUrl.ts
 var REDUNDANT_CHARACTERS_EXP = /[\?|#].*$/g;
@@ -638,7 +642,7 @@ function matchRequestUrl(url, path, baseUrl) {
 import * as cookieUtils3 from "cookie";
 import { store } from "@mswjs/cookies";
 import { IsomorphicRequest } from "@mswjs/interceptors";
-import { decodeBuffer } from "@mswjs/interceptors/lib/utils/bufferUtils";
+import { decodeBuffer } from "@mswjs/interceptors/lib/utils/bufferUtils.js";
 import { Headers as Headers2 } from "headers-polyfill";
 
 // src/utils/request/getRequestCookies.ts

@morrisonbrett
Copy link

@turboninh Can you please export the commit you patched and post it here?

@t18n
Copy link

t18n commented Nov 1, 2022

@morrisonbrett Updated my comment :)

kettanaito added a commit that referenced this issue Nov 7, 2022
* feat: better esm support

fixes #1267

* refactor: add workaround for `useFetch`

* refactor: move `statuses` to `devDependencies`

* fix: remove unneeded type assertion again

Co-authored-by: Artem Zakharchenko <kettanaito@gmail.com>
@kettanaito
Copy link
Member

Released: v0.48.0 🎉

This has been released in v0.48.0!

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.

@grzegorz-zadora
Copy link

#1267 (comment)

FYI the issue with bufferUtils still occurs in 0.48.0

Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'node_modules/@mswjs/interceptors/lib/utils/bufferUtils' imported from node_modules/msw/lib/node/index.mjs
Did you mean to import @mswjs/interceptors/lib/utils/bufferUtils.js

@cksal0805
Copy link
Contributor

Me too.. FYI the issue with bufferUtils still occurs in ^0.48.0

Did you mean to import @mswjs/interceptors/lib/utils/bufferUtils.js?
    at new NodeError (internal/errors.js:322:7)

@jorgepvenegas
Copy link

I wonder if the error on 0.48.0 is still there because of the interceptors? Looking at this comment #1399 (review)

@brleinad
Copy link

brleinad commented Jun 7, 2023

I was getting the same bufferUtils error after upgrading to 0.48.0 but it's now working for me after upgrading to 1.2.1

knokmki612 added a commit to npocccties/chiloportal that referenced this issue Nov 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs:triage Issues that have not been investigated yet. scope:browser Related to MSW running in a browser
Projects
None yet
Development

Successfully merging a pull request may close this issue.