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

MSW does not intercept requests when the node http(s) library is imported using * as #2049

Closed
4 tasks done
mickdekkers opened this issue Feb 21, 2024 · 4 comments
Closed
4 tasks done
Labels
bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node

Comments

@mickdekkers
Copy link

mickdekkers commented Feb 21, 2024

Prerequisites

Environment check

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

Node.js version

v20.10.0

Reproduction repository

https://github.com/mickdekkers/issue-repro-msw-request-interception-https-import

Reproduction steps

  1. Clone the repo
  2. Run npm i
  3. Run node index.mjs

Current behavior

MSW does not intercept the request to https://example.org with the code in the repro.

However, if you comment out the following line in index.mjs:

import * as https from "node:https";

And uncomment the following line:

// import https from "node:https";

Then run node index.mjs again, you'll see that MSW now intercepts the request as expected.

Expected behavior

MSW should intercept requests regardless of how the node http(s) library is imported.

Additional info

  • The same issue exists when importing the node:http library and sending a request to http://example.org
  • I hit this issue while attempting to write tests for an application that uses the jose library. The network request that jose sends to fetch a JWKS was not being intercepted. After exhausting all the likely causes, I eventually narrowed it down to the way it imports the node:https library. Relevant code: https://github.com/panva/jose/blob/v5.2.1/src/runtime/node/fetch_jwks.ts#L2
@mickdekkers mickdekkers added bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node labels Feb 21, 2024
@aduth
Copy link

aduth commented Feb 23, 2024

Another related effect of this is that MSW doesn't intercept correctly when using named ES module exports from the relevant default Node modules.

Example:

// Not intercepted:
import { get } from 'node:https';

get('https://example.com', (response) => { /* ... */ });
// Intercepted as expected:
import https from 'node:https';

https.get('https://example.com', (response) => { /* ... */ });

@kettanaito
Copy link
Member

Hi, @mickdekkers. Thanks for reporting this!

Alas, this is a technical limitation, and to my best knowledge we cannot solve it. When you import something as a wildcard import * as X from Y, JavaScript creates a special object called Y in that module's scope. The properties of that object are readonly and their reassignment seems to be protected even on runtime.

This code throws:

import * as http from 'http'

http.get = () => {}

This code doesn't:

import http from 'http'

http.get = () => {}

The same goes for named exports mentioned by @aduth. Reassigning the named export is not possible because it's a local variable created in that module's scope upon importing. You cannot reassign those:

import { get } from 'http'

get = () => {} // Error

I don't think it's possible to support these two use cases. If it's the code you control, I recommend importing the native Node.js modules using the default export. If it's the code you don't own, neither of us can do much about it.

@kettanaito
Copy link
Member

For the third-party code, I believe import * as http from 'http' is an incorrect way to import built-in Node.js modules. You can consider raising a pull request to that library's repo and see if they would agree on that.

@aduth
Copy link

aduth commented Mar 19, 2024

I wonder if the new Node module loader hooks could be an option here to override how the HTTP modules are resolved?

https://nodejs.org/api/module.html#hooks

Granted:

  • It may add some complexity for how hooks are registered
  • May be additional overhead to manage both ESM and CommonJS
  • Hooks are “release candidate” but still not fully stable

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:node Related to MSW running in Node
Projects
None yet
Development

No branches or pull requests

3 participants