next.js: Error: Must use import to load ES Module

What version of Next.js are you using?

10.2.2

What version of Node.js are you using?

14.16.1

What browser are you using?

Edge

What operating system are you using?

Windows

How are you deploying your application?

local development

Describe the Bug

When importing the react-konva package I get this error

Server Error
Error: Must use import to load ES Module: C:\Users\bucsa\dev\atomic\node_modules\konva\lib\Core.js
require() of ES modules is not supported.
require() of C:\Users\bucsa\dev\atomic\node_modules\konva\lib\Core.js from C:\Users\bucsa\dev\atomic\node_modules\react-konva\lib\ReactKonvaCore.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 Core.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from C:\Users\bucsa\dev\atomic\node_modules\konva\package.json.

The same error was thrown when I tried to import the chessops library but managed to work around that by dynamically importing it when the component loads. Neither that nor importing with next/dynamic could solve the issue with this package though.

Expected Behavior

I expected the components to be imported and not throw an error.

To Reproduce

Install react-konva and konva

import { Stage } from 'react-konva'

const Example = () => {
  return <Stage></Stage>
}

About this issue

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

Commits related to this issue

Most upvoted comments

This actually happens intermittently with ReactMarkdown.

Same issue, any updates?

FWIW, the latest NextJS@11 produces a similar webpack error when importing of an ESM-only npm package.

@steven-tey I did not try to use the components with refs so I haven’t faced this issue but after a bit of testing I found the solution. Instead of importing these components in the page, create a component that handles all the canvas logic and import that dynamically without SSR. Inside that component, you can use the react-konva components normally.

Before:

// pages/some-page.js
import React, { useRef } from 'react';
import dynamic from 'next/dynamic';
const Stage = dynamic(() => import('react-konva').then((module) => module.Stage), { ssr: false });

export default function Home() {
  const stageRef = useRef();

  return (
    <div>
      <Stage ref={stageRef} width={500} height={500}></Stage>
    </div>
  );
}

After:

// pages/some-page.js
import React from 'react';
import dynamic from 'next/dynamic';
const MyComponent = dynamic(() => import('../components/MyComponent'), { ssr: false });

export default function Home() {
  return (
    <div>
      <MyComponent></MyComponent>
    </div>
  );
}
// components/MyComponent.js
import React, { useRef } from 'react';
import { Stage, Layer } from 'react-konva'; // notice you can import from react-konva normally

export default function Home() {
  const stageRef = useRef();

  return (
    <div>
      <Stage width={500} height={500} ref={stageRef}>
        <Layer></Layer>
      </Stage>
    </div>
  );
}

It should be as easy as copying and pasting everything from the page and maybe passing the url params to your component as props if you don’t have any content that must be rendered server side.

For my project I realized SSR is unnecessary for 99% of the pages especially with all this headache from fighting with next dynamic imports so I just switched to bare react.

Anything for remark-gfm @Firanolfind

Thanks @Firanolfind! That fixed the following error:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /vercel/path0/node_modules/react-markdown/index.js
-
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /vercel/path0/node_modules/react-markdown/index.js
--

Note that I had to add webpack5: false like so:


const withTM = require("next-transpile-modules")(["react-markdown"]);
module.exports = withTM({ webpack5: false });

import dynamic from 'next/dynamic';
const MyComponent = dynamic(() => import('../components/MyComponent'), { ssr: false });

fixed my issue with React-konva

If you need to include a lot of packages in the transpiler list you can generate the list like this:

cd node_modules
for d in $(ls); do grep '"type": "module"' "$d"/package.json >/dev/null 2>&1 && echo \"$d\", ; done

Couldn’t get remark-gfm to work. Tried some solution here. Ended up ‘solving’ it by just downgrading remark-gfm to 1.0.0, away from esm.

Same issue here with Next.JS 10.2.3 with Sindre Sohrus’s p-limit which effectively uses the "type": "module" in its package.json. I haven’t been able to make the next-transpile-modules workaround work…

Module parse failed: Unexpected token (7:6)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| 
| class Node {
>       value;
|       next;
|
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /.../node_modules/p-limit/index.js
require() of ES modules is not supported.
require() of /.../node_modules/p-limit/index.js from /.../.next/server/pages/_admin/upload.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.

Has this fix been pushed to the 10.x.x branch ? Best Regards,

The issue was solved by importing dynamically and with ssr: false. It’s still weird though, I didn’t use "type": "module" in my package.json and the error came up in a fresh nextjs installation too. Even without using the components, just importing them. Only typescript complains about the components because they are not the default export from the package but that was solved by wrapping my component’s import with dynamic. Haven’t looked at the chessops library yet but I guess that should also work inside my dynamically imported component.

This actually happens intermittently with ReactMarkdown.

Found solution for ReactMarkdown

next.config.js

const withTM = require('next-transpile-modules')(['react-markdown']);

module.exports = withTM({
...
})

and import it like that import ReactMarkdown from 'react-markdown/react-markdown.min';

You almost saved me 2 days 😄 I was struggling to find a solution and tried a lot of things.

Now I get this warning in the terminal. any suggestion?

markdown-warning

actually fixed by adding order prop to the li element

   <ReactMarkdown
              children={page.content}
              components={{
                li: ({ node, ...props }: any) => (
                  <li className="list-disc" ordered="false" {...props} />
                ),
              }}
          />

@curiousercreative What do you suggest to fix that kind of issue? (typescript with a library that uses type: module in package.json)