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

[NEXT-1173] use node module inside instrumentation hook cause module not found error #49565

Closed
1 task done
galaxynova1999 opened this issue May 10, 2023 · 23 comments
Closed
1 task done
Labels
bug Issue was opened via the bug report template. Instrumentation Related to Next.js Instrumentation. linear: next Confirmed issue that is tracked by the Next.js team.

Comments

@galaxynova1999
Copy link

galaxynova1999 commented May 10, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: linux
      Arch: x64
      Version: #22 SMP Tue Jan 10 18:39:00 UTC 2023
    Binaries:
      Node: 16.17.0
      npm: 8.15.0
      Yarn: 1.22.19
      pnpm: 7.1.0
    Relevant packages:
      next: 13.4.2-canary.4
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 4.9.4

Which area(s) of Next.js are affected? (leave empty if unsure)

No response

Link to the code that reproduces this issue

https://codesandbox.io/p/sandbox/awesome-roman-jkuyps?file=%2Fpages%2Findex.tsx%3A3%2C10-3%2C14

To Reproduce

run yarn dev in codesandbox

Describe the Bug

use node module like path (except process, because it has been defined in webpack.resolve.fallback) inside instrumentation.ts file will cause module not found error

also, it can be temporarily solved by adding browser field in package.json

"browser": {
    "path": false
  }

image

Expected Behavior

no error since it's a server startup config, it's highly likely to use nodejs module(s)

Which browser are you using? (if relevant)

Chrome 100.0.4878.0

How are you deploying your application? (if relevant)

next start

NEXT-1173

@galaxynova1999 galaxynova1999 added the bug Issue was opened via the bug report template. label May 10, 2023
@mickeldebs
Copy link

Hi, was trying this feature out and faced the same problem at first. Then read again the documentation and realized that I needed to use import inside the function. The other issue is that you need to check that your are running your code in the correct runtime.
Seen your codesandbox and this should fix it:

instrumentation.ts:

export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    const { join } = await import("path");
    const { cwd, exit, platform } = await import("process");
    console.log(join("a", "b"));
    console.log(cwd());
  }
}

Hope this helps

@mickeldebs
Copy link

My problem with this feature is I wanted something to run on server start and not when the first browser window opens. It seems that its not the case even though they are marketing it as start with the server:
If you export a function named register from this file, we will call that function whenever a new Next.js server instance is bootstrapped.

@galaxynova1999
Copy link
Author

Hi, was trying this feature out and faced the same problem at first. Then read again the documentation and realized that I needed to use import inside the function. The other issue is that you need to check that your are running your code in the correct runtime. Seen your codesandbox and this should fix it:

instrumentation.ts:

export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    const { join } = await import("path");
    const { cwd, exit, platform } = await import("process");
    console.log(join("a", "b"));
    console.log(cwd());
  }
}

Hope this helps

it works,thanks!
maybe the document should describe it more clear

@timneutkens timneutkens added the linear: next Confirmed issue that is tracked by the Next.js team. label May 17, 2023
@timneutkens timneutkens changed the title use node module inside instrumentation hook cause module not found error [NEXT-1173] use node module inside instrumentation hook cause module not found error May 17, 2023
@pthieu
Copy link

pthieu commented Jun 8, 2023

I'm also hitting a similar issue:

Error: Module not found: Can't resolve 'net'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/.pnpm/[email protected]/node_modules/postgres/src/index.js
./src/app/api/db/index.ts
./src/instrumentation.ts

For my case, I'm running my DB migrations on server start, and I import the migration function from my DB lib. From the above solution, it looks like I may need to pull in my DB connection and migration logic directly into register, but this is not ideal.

@kemengwang
Copy link

My problem with this feature is I wanted something to run on server start and not when the first browser window opens. It seems that its not the case even though they are marketing it as start with the server: If you export a function named register from this file, we will call that function whenever a new Next.js server instance is bootstrapped.

I have the same problem, This looks like a bug.

@lmgeorge
Copy link

Also running into this issue when attempting to bootstrap the https://github.com/microsoft/ApplicationInsights-node.js package.

Inlining the logic into the register function doesn't work as the Node runtime dependencies are only used by the applicationinsights package. Using the workaround with the browser config is a non-starter as that would require explicitly declaring [node package name]: false for over a dozen packages, when those packages should be resolvable in the nodejs runtime without issue.

@kubop
Copy link

kubop commented Sep 7, 2023

Also running into this issue when attempting to bootstrap the https://github.com/microsoft/ApplicationInsights-node.js package.

Inlining the logic into the register function doesn't work as the Node runtime dependencies are only used by the applicationinsights package. Using the workaround with the browser config is a non-starter as that would require explicitly declaring [node package name]: false for over a dozen packages, when those packages should be resolvable in the nodejs runtime without issue.

@lmgeorge Have you managed to fix or implement some workaround for this issue? I'm also trying to include the applicationinsights with instrumentation, but without any luck.

@lmgeorge
Copy link

lmgeorge commented Sep 9, 2023

@kubop I have not. I started to explore the workaround mentioned in the description of the bug, but after adding the tenth Node standard library package, I gave up due to time constraints.

@jjhuff
Copy link

jjhuff commented Sep 13, 2023

Hi, was trying this feature out and faced the same problem at first. Then read again the documentation and realized that I needed to use import inside the function. The other issue is that you need to check that your are running your code in the correct runtime. Seen your codesandbox and this should fix it:

instrumentation.ts:

export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    const { join } = await import("path");
    const { cwd, exit, platform } = await import("process");
    console.log(join("a", "b"));
    console.log(cwd());
  }
}

Hope this helps

FWIW, this doesn't seem to work in my 13.4.19, at least with webpack config:

./src/instrumentation.ts:16:16
Module not found: Can't resolve 'path'

@ItzDerock
Copy link

ItzDerock commented Oct 8, 2023

Ran into this issue with 13.5.4, originally, I had

if (process.env.NEXT_RUNTIME !== "nodejs") return;
// imports and do something

but apparently this does not work, instead it must be

if (process.env.NEXT_RUNTIME === "nodejs") {
  // imports and do something
}

@igabor94
Copy link

Ran into this issue with 13.5.4, originally, I had

if (process.env.NEXT_RUNTIME !== "nodejs") return;
// imports and do something

but apparently this does not work, instead it must be

if (process.env.NEXT_RUNTIME === "nodejs") {
  // imports and do something
}

It worked for me on 13.4.19. Thank you!

@justLuiz
Copy link

justLuiz commented Nov 1, 2023

Another usefull sample with this problem

nextjs instrumentation with prometheus sample

@landisdesign
Copy link

landisdesign commented Nov 11, 2023

I'm running into this in dependencies.

If I attempt to await import('winston'), it errors on os being required by the @colors/colors dependency in winston.

Forked from @justLuiz's example:

Just importing winston

@axpchina
Copy link

axpchina commented Dec 7, 2023

for some reason...found out that you must put those imports in:

export async function register() {
    if (process.env.NEXT_RUNTIME === "nodejs") {
        console.log("instrumentation register");
        //await import packages...
    }
}

not only using await, the trick seems to be "if (process.env.NEXT_RUNTIME === "nodejs") {...}", you have to do things inside this "IF", I don't know why, but it worked well, otherwise didn't.

@robsoncloud
Copy link

for some reason...found out that you must put those imports in:

export async function register() {
    if (process.env.NEXT_RUNTIME === "nodejs") {
        console.log("instrumentation register");
        //await import packages...
    }
}

not only using await, the trick seems to be "if (process.env.NEXT_RUNTIME === "nodejs") {...}", you have to do things inside this "IF", I don't know why, but it worked well, otherwise didn't.

I had the same issue and this tip did the trick to solve the issue. Thanks

@developerasun
Copy link

developerasun commented Jan 20, 2024

for some reason...found out that you must put those imports in:

export async function register() {
    if (process.env.NEXT_RUNTIME === "nodejs") {
        console.log("instrumentation register");
        //await import packages...
    }
}

not only using await, the trick seems to be "if (process.env.NEXT_RUNTIME === "nodejs") {...}", you have to do things inside this "IF", I don't know why, but it worked well, otherwise didn't.

this is true, I tried both with/without full env path like below (using next 14.1)

// does not work
const runtime = process.env.NEXT_RUNTIME

if (runtime === "nodejs") {
  const { myModule} = await import("some-module")
}

and only below works

// works
if (process.env.NEXT_RUNTIME=== "nodejs") {
  const { myModule } = await import("some-module")
}

seems like nextjs under the hook make a detection pattern only working with fully annotated process.env.

felt like kind of unneeded complicates tho

@Andrii-Antoniuk
Copy link

Can also confirm that an early return won't work

if (process.env.NEXT_RUNTIME !== "nodejs") {
  return;
  }

@ZeeshanAhmadKhalil
Copy link

ZeeshanAhmadKhalil commented Feb 21, 2024

for me register() inside instrumentation.ts is not working at all. I am using it like this:


//! not working
export async function register() {
    console.log("register===>")
}

But I am unable to see any consoles. Do consoles don't work here? Or should i do some extra steps to make register() working?

@balazsorban44 balazsorban44 added the Instrumentation Related to Next.js Instrumentation. label Apr 19, 2024
@mxvsh
Copy link

mxvsh commented May 9, 2024

here is what i did -

i wanted to execute functions in my next.js application on every startup - i tried using instrumentation.ts but it was always throwing error about fs and other node modules, so what i did is make a GET api route (Next 14) and use fetch from instrumentation.ts. It worked like charm 🎉

export function register() {
  fetch('http://localhost:3000/api/init')
}

i have hard coded the URL, but you can use process.env.VERCEL_URL

@talonx
Copy link

talonx commented May 9, 2024

This is too cumbersome to use for initialization. I ended up moving all the init code into another node service altogether, based on Express, where it's much easier.

@Arctomachine
Copy link

I encountered this error with several libraries.
Contrary to #49565 (comment) everything worked normally in dev mode, but builds failed.
So I tried several variations of what is described in #49565 (comment) and the best workflow in this file is like this:

  1. Avoid writing any logic in instrumentation file
  2. Write function with all logic in separate file and export it
  3. In register function use (if process.env.NEXT_RUNTIME === 'nodejs') { }
  4. Inside this condition use const { someFunction } = await import('fileWithFunction')
  5. And call someFunction()

Any other workflow will potentially give error, so avoid writing literally anything else in instrumentation file.

@CyberT33N
Copy link

CyberT33N commented Jul 26, 2024

I ended up using magic comments to disable webpack for my import:

My problem was, that my imported path was always a dynamic variable and did not find a valid solution to import it. However, I guess there isa way but I did not spend much more time with it and just added webpackIgnore comment. I do not think that there will be crazy negative aspects when you use it for dynamic imports. But of course it is not the cleanest solution. Maybe somebody with more webpack expierence has a more clean solution.

instrumentation.ts

export async function register() {
    console.log('[INSTRUMENATION] - process.env.NEXT_RUNTIME: ', process.env.NEXT_RUNTIME)

    if (process.env.NEXT_RUNTIME === 'nodejs') {
        const { bootstrap } = await import('@/src/bootstrap')
        await bootstrap()
    }
}

bootstrap.ts

async function bootstrap () {
    const modelDetails = await import(/* webpackIgnore: true */ path)
    return modelDetails
}
  • Also another workaround in other cases is to make this:
      await import(`${path}`)

@huozhi
Copy link
Member

huozhi commented Aug 20, 2024

This is caused by the runtime since when the instrumentation.js will be the entry for both Node.js and Edge runtime. Separate the entry based on the runtime would be the proper solution for now. In the future we might introduce the different entry file convention of instrumentation.js for different runtime.

One small improvement we patched on latest canary release is that we won't generate the edge runtime entry of instrumentation.js when you only have Node.js routes, so you can safely write Node.js code inside of the instrumentation.js file there.

@huozhi huozhi closed this as completed Aug 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. Instrumentation Related to Next.js Instrumentation. linear: next Confirmed issue that is tracked by the Next.js team.
Projects
None yet
Development

No branches or pull requests