next.js: `UnhandledSchemeError` when dependency uses `node:assert` imports

What version of Next.js are you using?

11.1.2

What version of Node.js are you using?

14.17.6

What browser are you using?

ff

What operating system are you using?

linux

How are you deploying your application?

vercel

Describe the Bug

In a project which has micromark-util-events-to-acorn@1.0.1 as a dependency, i get the following error when running yarn dev:

Module build failed: UnhandledSchemeError: Reading from "node:assert" is not handled by plugins (Unhandled scheme).

Screenshot_20210903_204738

Things to note about this package: it uses an export map with a “development” user condition, and node:assert is only used there, not in the exported production build.

Expected Behavior

No error.

To Reproduce

  1. git clone https://github.com/stefanprobst/issue-next-webpack-node-imports.git
  2. cd issue-next-webpack-node-imports
  3. yarn && yarn add next@latest && yarn dev
  4. open http://localhost:3000/
  5. See error message

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 23
  • Comments: 36 (19 by maintainers)

Commits related to this issue

Most upvoted comments

Oh, interesting. The reproduction uses 11.1.2, but upgrading to latest does throw the error after all. 👀

It might be because the client-side code elimination tool isn’t able to recognize the module you are using is for server-only.

import fs from "node:fs"

export default function Home() {
  return null
}

export async function getStaticProps() {
  console.log(fs)
  return { props: {} }
}

This works as the code can be analyzed and Next.js will know where the node: import is being used.

Let’s reopen and investigate further.

I’m still getting this error with next.js 12

Any updates on this issue? Facing the same problem but for xdm.

Slight modification I made so I could use the new format using next@12.3.0 and webpack@5.74.0, if this is helpful:

const webpack = require("webpack");

module.exports = {
  webpack: (config, options) => {
    config.plugins.push(
      new webpack.NormalModuleReplacementPlugin(/^node:/, (resource) => {
        resource.request = resource.request.replace(/^node:/, "");
      })
    );
    return config;
  },
};

Sill seeing this in next@13.3.1

@sebald I recall briefly seeing this error and I think I fixed it by deleting the .next directory. If this doesn’t work, you can check my full implementation here and maybe spot something I am missing. I don’t have this error on my end with this implementation.

i am still seeing the exact same error message with next@12.1.6 and node@16.14.2:

  1. git clone https://github.com/stefanprobst/issue-next-webpack-node-imports.git
  2. cd issue-next-webpack-node-imports
  3. yarn && yarn add next@latest && yarn dev
  4. open http://localhost:3000/
  5. See error message

Not sure if this fix for a similar bug is helpful: https://github.com/webpack/webpack/pull/15577 Can NextJS make sure to update their Webpack module to this version and see if it resolves this?

Next.js adds fallbacks for node built-in modules by using resolve.fallback:

https://github.com/vercel/next.js/blob/384953b35c5e9935bb4a2fcdfe5056efb73cd740/packages/next/build/webpack-config.ts#L628-L659

And this feature now doesn’t support node protocol: https://github.com/webpack/webpack/issues/14166

⚠️ This does not apply to middleware ⚠️

If you see compile errors related to node modules or node: prefix, that is because in Next 13 middleware ALWAYS runs in Edge runtime without a way to opt-out.

This means that whatever you import in middleware.ts, and their dependencies, must not import node packages or use edge-incompatible APIs

  1. It is currently impossible to change runtime for middleware with config.experimental.runtime or export const runtime = "nodejs" and they will be ignored.
  2. The above webpack workaround will not fix the underlying issue and runtime will still fail with missing packages (such as stream or crypto)
  3. Tested on next@13.3.1

Example failures

Even after closing https://github.com/webpack/webpack/issues/13290 and supposed fix in https://github.com/vercel/next.js/pull/45149 merged in Jan, it’s still failing for code in my middleware.ts that imports a 3rd party module, which seems to have @aws-sdk transient dependency, which dynamically imports node:file

dev:next: wait  - compiling /src/middleware (client and server)...
dev:next: error - node:fs
dev:next: Module build failed: UnhandledSchemeError: Reading from "node:fs" is not handled by plugins (Unhandled scheme).
dev:next: Webpack supports "data:" and "file:" URIs by default.
dev:next: You may need an additional plugin to handle "node:" URIs.
dev:next: Import trace for requested module:
dev:next: node:fs
dev:next: ./node_modules/.pnpm/strtok3@7.0.0/node_modules/strtok3/lib/FsPromise.js
dev:next: ./node_modules/.pnpm/strtok3@7.0.0/node_modules/strtok3/lib/index.js
dev:next: ./node_modules/.pnpm/file-type@18.3.0/node_modules/file-type/index.js
dev:next: ./node_modules/.pnpm/@keystone-6+core@5.2.0_@aws-sdk+abort-controller@3.310.0_@babel+core@7.21.4_@opentelemetry+ap_eexecvfunafgo67t2ljvtiogxm/node_modules/@keystone-6/core/dist/createSystem-a93ebf95.esm.js
dev:next: ./node_modules/.pnpm/@keystone-6+core@5.2.0_@aws-sdk+abort-controller@3.310.0_@babel+core@7.21.4_@opentelemetry+ap_eexecvfunafgo67t2ljvtiogxm/node_modules/@keystone-6/core/context/dist/keystone-6-core-context.esm.js
dev:next: ./src/keystone/context.ts
dev:next: ./src/server/auth.ts

Webpack has shims for some Node.js core modules that provide equivalent functionality in the browser, and path is one of them. The path shim provides the sep property, so my code works as expected.

We eventually want to remove these default shims because they increase bundle size massively in most cases. node: is meant to signal “In the Node.js environment” so hence why we intentionally do not add shims for those.

Hi everyone, this should be fixed in newer versions of Next.js, make sure you upgrade (npm i next@latest)! I tested the reproduction on top of this issue and it worked.

If you still see an issue and you think it’s related, please open a new one with an attached reproduction, thanks! 💚

wow thanks a lot for clarifying this @Thinkscape always felt there’s something off with middleware as I couldn’t get mysql2 working which I use in dev locally and was always confused but now that not even cuid2 works got me finally investigating.

This is actually reeaally annoying as so far, I think, middleware is the only place to set cookies on a request without user interaction or calling an api, which is already pretty annoying but have this middleware limited like this 🥲

Also I’d really like to be able to pass data from middleware to server components/actions and routes (https://github.com/vercel/next.js/discussions/34263#discussioncomment-5821645) which is pretty limiting not being able to do this 😬

Slight modification I made so I could use the new format using next@12.3.0 and webpack@5.74.0, if this is helpful:

const webpack = require("webpack");

module.exports = {
  webpack: (config, options) => {
    config.plugins.push(
      new webpack.NormalModuleReplacementPlugin(/^node:/, (resource) => {
        resource.request = resource.request.replace(/^node:/, "");
      })
    );
    return config;
  },
};

This is a great workaround!

Is the node: protocol supported in the current Next.js webpack configuration?

Things to note about this package: it uses an export map with a “development” user condition, and node:assert is only used there, not in the exported production build.

This is true throughout the micromark ecosystem as far as I know, so support for this would be great!

Edit: mentioned in https://github.com/remarkjs/react-markdown/issues/641, https://github.com/micromark/micromark/issues/87, and https://github.com/remarkjs/react-markdown/issues/632