Repository: next.js
Issue: `instrumentation.ts` cannot be used for instrumenting native modules with OpenTelemetry when native modules are imported from `instrumentation.ts`
Labels: bug,SWC,Instrumentation

### Link to the code that reproduces this issue

https://github.com/lforst/nextjs-instrumentation-behaviour-repro

### To Reproduce

```sh
npm i
npm run build
npm run start
curl http://localhost:3000/make-req
```

Afterward, take a look at the server logs.

Inside `make-req/route.ts`, we are making an `http.get()` call to `check/route.ts`.
This `http.get()` call should be instrumented, meaning tracing headers should be attached.
The `check/route.ts` endpoint simply returns the headers it receives, but no tracing headers are attached, meaning the instrumentation didn't work.

You might be inclined to say "yo the Sentry SDK is probably broken", but I don't think this is the case.
For the sake of simplicity, I used the Sentry SDK which uses the OpenTelemetry instrumentation under the hood.
You could probably also reproduce this by using the OpenTelemetry HTTP instrumentation + any OTEL HTTP propagator, and the propagation would also fail.

### Current vs. Expected behavior

The expected behaviour is for the OpenTelemetry instrumentation to be able to patch the `http` module so that the `http` call will have tracing headers attached.

I suspect that other native modules like `fs` are also affected by this.

### Provide environment information

```bash
Operating System:
  Platform: linux
  Arch: arm64
  Version: #15-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan  9 22:39:36 UTC 2024
  Available memory (MB): 15962
  Available CPU cores: 6
Binaries:
  Node: 18.18.2
  npm: 9.8.1
  Yarn: 1.22.22
  pnpm: 8.15.5
Relevant Packages:
  next: 14.2.2 // Latest available version is detected (14.2.2).
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.1.3
Next.js Config:
  output: N/A
```


### Which area(s) are affected? (Select all that apply)

Instrumentation, SWC

### Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), next start (local), Vercel (Deployed)

### Additional context

We noticed this from version `14.2.0` onwards which included a change to not externalize `@sentry/nextjs` anymore: https://github.com/vercel/next.js/pull/61194

However, we don't think this is the problem. In it's root I believe this is caused by the following, only surfaced by that change:
- Next.js bundling produces code that "caches" `require` calls to native modules like `http`.
- This usually looks like the following:
  ```
  13685: (e) => {
    "use strict";
    e.exports = require("http");
  },
  ```
- When any code inside `instrumentation.ts` or any dependencies of `instrumentation.ts` depends on native modules like `http`, the require call to this module is cached before the `register()` hook is ran.
- This means, when OpenTelemetry tries to patch `require` with [`require-in-the-middle`](https://www.npmjs.com/package/require-in-the-middle), it is pointless because any usages of the native module will use the "cached" version.
- When `@sentry/nextjs` wasn't externalized, we didn't notice this problem, because the dependency on `http` by `@sentry/nextjs` wasn't bundled into the output of `instrumentation.ts`, meaning `http` wasn't cached too early.

I think this is fixable by either not "caching" native modules inside `instrumentation.ts`, or simply externalizing _everything_ imported inside `instrumentation.ts`. The latter would probably have a lot of bad consequences.

Let me know if this needs clarification.