next.js: ERR_ESM_REQUIRE - Webpack 5 config should support ESM packages

What version of Next.js are you using?

10.1.3

What version of Node.js are you using?

14.x

What browser are you using?

Chrome

What operating system are you using?

macOS

How are you deploying your application?

Vercel

Describe the Bug

p-queue recently updated to using ESM modules, and it looks like some webpack configuration is required to support it. I doubt this is the last time this particular issue will come up.

Expected Behavior

Users should be able to require ESM modules without getting an error.

To Reproduce

Install p-queue@7.0.0, import it, and try to start next.

Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 34
  • Comments: 44 (15 by maintainers)

Most upvoted comments

Some background: @sindresorhus is in the process of moving most of his packages to ESM only in 2021. This error will likely become more common as more packages move to ESM only.

I ran into the same issue with https://github.com/sindresorhus/slugify. Workaround: don’t upgrade to latest major.

This is being worked on by @sokra currently, you can check out the initial PR here: https://github.com/vercel/next.js/pull/27069. Do keep in mind this is still work in progress.

not the op, but reproducible with this. both import and import() fail with:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /data/Development/playground/issue-next-esm/node_modules/p-queue/dist/index.js
require() of ES modules is not supported.
require() of /data/Development/playground/issue-next-esm/node_modules/p-queue/dist/index.js from /data/Development/playground/issue-next-esm/.next/server/pages/index.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename /data/Development/playground/issue-next-esm/node_modules/p-queue/dist/index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /data/Development/playground/issue-next-esm/node_modules/p-queue/package.json.

esmExternals: true is now the default on next@canary meaning it is going to be the default in the upcoming stable release. I’m going to close this issue as this particular case has been fixed. For loading ESModules in next.config.js please subscribe to https://github.com/vercel/next.js/issues/9607.

If anyone gets here because of the new unified stack, maybe this will save you some time:

const withTM = require("next-transpile-modules")([
  "bail",
  "comma-separated-tokens",
  "hast-to-hyperscript",
  "hast-util-from-parse5",
  "hast-util-has-property",
  "hast-util-heading-rank",
  "hast-util-parse-selector",
  "hast-util-raw",
  "hast-util-sanitize",
  "hast-util-to-parse5",
  "hast-util-to-string",
  "hastscript",
  "html-void-elements",
  "is-plain-obj",
  "mdast-util-from-markdown",
  "micromark-core-commonmark",
  "micromark-factory-destination",
  "micromark-factory-label",
  "micromark-factory-space",
  "micromark-factory-title",
  "micromark-factory-whitespace",
  "micromark-util-combine-extensions",
  "micromark-util-character",
  "micromark-util-chunked",
  "micromark-util-classify-character",
  "micromark-util-decode-numeric-character-reference",
  "micromark-util-html-tag-name",
  "micromark-util-normalize-identifier",
  "micromark-util-resolve-all",
  "micromark-util-subtokenize",
  "micromark-util-symbol",
  "property-information",
  "rehype-autolink-headings",
  "rehype-raw",
  "rehype-react",
  "rehype-sanitize",
  "rehype-slug",
  "remark-parse",
  "space-separated-tokens",
  "trough",
  "unified",
  "unist-util-stringify-position",
  "vfile",
  "web-namespaces"
]);

You can try the latest canary version and verify if it does work in your cases.

For anyone running into similar problems ( @mario-jerkovic ?) that aren’t immediately fixed with next-transpile-modules, you may need to include sub-dependencies in your next.config.js as well. I just ran into this problem with d3-delaunay but it might be present in other d3 modules as well.

Keep an eye on the error messages to see which modules you need to add.

My config looks like:

// next.config.js
const withTM = require("next-transpile-modules")([
  "d3-delaunay", // The package I'm trying to import
  "delaunator", // A dependency of d3-delaunay
  "robust-predicates", // A dependency of delaunator
]);

module.exports = withTM({
  reactStrictMode: true,
});

workaround: use next-transpile-modules

const withTM = require('next-transpile-modules')([
 // ...
  'p-debounce', // ESM module
])

@deadcoder0904 looks like you didn’t actually enable the esmExternals config?

@deadcoder0904 can you provide a reproduction repository so that we can have a look?

@deadcoder0904 maybe setup issue? I’m using next compose plugins to wrap the transpile,

This config, for latest rehype-raw, rehype-slug and remark-gfm v1.0.0

const withPlugins = require("next-compose-plugins");
const withTM = require("next-transpile-modules")([
  "escape-string-regexp",
  "comma-separated-tokens",
  "hast-to-hyperscript",
  "hast-util-from-parse5",
  "hast-util-has-property",
  "hast-util-heading-rank",
  "hast-util-parse-selector",
  "hast-util-raw",
  "hast-util-to-parse5",
  "hast-util-to-string",
  "hastscript",
  "html-void-elements",
  "property-information",
  "rehype-raw",
  "rehype-slug",
  "space-separated-tokens",
  "vfile-location",
  "web-namespaces",
]);

const nextConfig = {
  eslint: {
    ignoreDuringBuilds: true,
  },
};

module.exports = withPlugins([withTM], nextConfig);

or maybe you can try NextJS 11.1.0 , and try

// next.config.js
module.exports = {
  // Prefer loading of ES Modules over CommonJS
  experimental: { esmExternals: true }
}

no need to use transpile anymore, finally NextJS support it, and it become default in NextJS 12

Can you provide a reproduction? Then we can have a look into it 👍

Same issue with new version of d3 modules like d3-scale