theme-ui icon indicating copy to clipboard operation
theme-ui copied to clipboard

Theme UI provider import causes an ESM error when mdx-js/react is subsequently required

Open johno opened this issue 2 years ago • 9 comments

Describe the bug

MDX v2 switches to ESM, but Theme UI's cjs file is imported during Next's SSR, which causes an error. I'm not entirely sure if this is a bug in Theme UI or Next, but a direct @mdx-js/react import doesn't cause an error. So, it seems like something to do with the preconstruct build during Next's SSR, maybe? Result of it being a second level dependency?

error - Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@mdx-js/react/index.js
require() of ES modules is not supported.
require() of /Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@mdx-js/react/index.js from /Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@theme-ui/mdx/dist/theme-ui-mdx.cjs.dev.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 index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@mdx-js/react/package.json.

To Reproduce

Steps to reproduce the behavior:

  1. Go to https://github.com/johno/repro-mdx-v2-theme-ui
  2. Follow steps in readme

Expected behavior

I'd expect Theme UI's ESM modules to be imported which will ensure no error is caused when the MDX import occurs. And it should be ESM files rather than cjs.

johno avatar Nov 24 '21 18:11 johno

I also tried experimental.esmExternals = true in next.config.js which resulted in a slightly different error.

error - Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@mdx-js/react/index.js from /Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@theme-ui/mdx/dist/theme-ui-mdx.cjs.dev.js not supported.
Instead change the require of index.js in /Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@theme-ui/mdx/dist/theme-ui-mdx.cjs.dev.js to a dynamic import() which is available in all CommonJS modules.
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@mdx-js/react/index.js from /Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@theme-ui/mdx/dist/theme-ui-mdx.cjs.dev.js not supported.
Instead change the require of index.js in /Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@theme-ui/mdx/dist/theme-ui-mdx.cjs.dev.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@theme-ui/mdx/dist/theme-ui-mdx.cjs.dev.js:9:15)
    at Object.<anonymous> (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/@theme-ui/mdx/dist/theme-ui-mdx.cjs.js:6:20)
    at Object.<anonymous> (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/theme-ui/dist/theme-ui.cjs.dev.js:7:11)
    at Object.<anonymous> (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/theme-ui/dist/theme-ui.cjs.js:6:20)
    at Object.theme-ui (/Users/johno-mini/c/repro-mdx-v2-theme-ui/.next/server/pages/_app.js:42:18)
    at __webpack_require__ (/Users/johno-mini/c/repro-mdx-v2-theme-ui/.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///./pages/_app.js:7:66)
    at Object../pages/_app.js (/Users/johno-mini/c/repro-mdx-v2-theme-ui/.next/server/pages/_app.js:22:1)
    at __webpack_require__ (/Users/johno-mini/c/repro-mdx-v2-theme-ui/.next/server/webpack-runtime.js:33:42)
    at __webpack_exec__ (/Users/johno-mini/c/repro-mdx-v2-theme-ui/.next/server/pages/_app.js:52:39)
    at /Users/johno-mini/c/repro-mdx-v2-theme-ui/.next/server/pages/_app.js:53:28
    at Object.<anonymous> (/Users/johno-mini/c/repro-mdx-v2-theme-ui/.next/server/pages/_app.js:56:3)
    at Object.requirePage (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/next/dist/server/require.js:48:12)
    at Object.loadComponents (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/next/dist/server/load-components.js:57:23)
    at DevServer.findPageComponents (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/next/dist/server/next-server.js:1233:63)
    at DevServer.findPageComponents (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/next/dist/server/dev/next-dev-server.js:660:26)
    at async DevServer.renderErrorToResponse (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/next/dist/server/next-server.js:1702:26)
    at async pipe.req.req (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/next/dist/server/next-server.js:1670:30)
    at async DevServer.pipe (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/next/dist/server/next-server.js:1148:25)
    at async DevServer.run (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/next/dist/server/dev/next-dev-server.js:446:24)
    at async DevServer.handleRequest (/Users/johno-mini/c/repro-mdx-v2-theme-ui/node_modules/next/dist/server/next-server.js:320:20) {
  code: 'ERR_REQUIRE_ESM'
}

johno avatar Nov 24 '21 18:11 johno

Is there a known workaround for this? I don't use MDX so I tried just not requiring @mdx-js/react in my package.json, but that didn't work, theme-ui complained about the missing module.

ckeeney avatar Jun 08 '22 05:06 ckeeney

Downgrading mdx-js to version 1.6 solved this issue for me.

ckeeney avatar Jun 14 '22 05:06 ckeeney

I'm inclined to think that Theme UI should go all in on ESM here and use something like tsup to build the packages rather than Preconstruct's faux-ESM.

Since Theme UI is an MDX user and MDX itself has gone all in on ESM - it's likely time to rip off the bandaid. Right now a fresh install of Theme UI, MDX, and Next.js effectively fails since it brings in MDX v2.

The other option is to rip out MDX and implement an API that folks can leverage to connect Theme UI and MDX. An API might look something like the following:

import { useMDXComponents } from 'theme-ui'

// ...

const components = useMDXComponents()

// ...

return <MDXProvider components={components} />

johno avatar Jul 18 '22 19:07 johno

@johno +1 to that proposed API approach, keeps the pattern consistent with @mdx-js/react usage

mryechkin avatar Jul 18 '22 19:07 mryechkin

Is there a fix for this? Using "@mdx-js/react": "^1.6.22", gives dependency error with react 18

npm install
npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! 
npm ERR! While resolving: @mdx-js/[email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"18.2.0" from the root project
npm ERR!   peer react@">=16.8.0" from @emotion/[email protected]
npm ERR!   node_modules/@emotion/react
npm ERR!     @emotion/react@"^11.10.0" from the root project
npm ERR!     peer @emotion/react@"^11" from @theme-ui/[email protected]
npm ERR!     node_modules/@theme-ui/color-modes
npm ERR!       @theme-ui/color-modes@"0.14.7" from @theme-ui/[email protected]
npm ERR!       node_modules/@theme-ui/theme-provider
npm ERR!         @theme-ui/theme-provider@"0.14.7" from [email protected]
npm ERR!         node_modules/theme-ui
npm ERR!       1 more (theme-ui)
npm ERR!     6 more (@theme-ui/components, @theme-ui/core, @theme-ui/css, ...)
npm ERR!   16 more (@theme-ui/color-modes, @theme-ui/components, ...)
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.13.1 || ^17.0.0" from @mdx-js/[email protected]
npm ERR! node_modules/@mdx-js/react
npm ERR!   @mdx-js/react@"^1.6.22" from the root project
npm ERR!   peer @mdx-js/react@"^1 || ^2" from @theme-ui/[email protected]
npm ERR!   node_modules/@theme-ui/mdx
npm ERR!     @theme-ui/mdx@"0.14.7" from @theme-ui/[email protected]
npm ERR!     node_modules/@theme-ui/theme-provider
npm ERR!       @theme-ui/theme-provider@"0.14.7" from [email protected]
npm ERR!       node_modules/theme-ui
npm ERR!     1 more (theme-ui)
npm ERR! 
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/react
npm ERR!   peer react@"^16.13.1 || ^17.0.0" from @mdx-js/[email protected]
npm ERR!   node_modules/@mdx-js/react
npm ERR!     @mdx-js/react@"^1.6.22" from the root project
npm ERR!     peer @mdx-js/react@"^1 || ^2" from @theme-ui/[email protected]
npm ERR!     node_modules/@theme-ui/mdx
npm ERR!       @theme-ui/mdx@"0.14.7" from @theme-ui/[email protected]
npm ERR!       node_modules/@theme-ui/theme-provider
npm ERR!         @theme-ui/theme-provider@"0.14.7" from [email protected]
npm ERR!         node_modules/theme-ui
npm ERR!       1 more (theme-ui)
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

web-programmer-here avatar Jul 31 '22 13:07 web-programmer-here

@web-programmer-here, use --legacy-peer-deps for now as a workaround until a new version of Theme UI is released.

hasparus avatar Aug 01 '22 11:08 hasparus

@hasparus thanks, that fixed my issue, is there an eta for theme ui update to fix this issue? thanks

web-programmer-here avatar Aug 02 '22 00:08 web-programmer-here

FYI, we'll be releasing a new major of gatsby-plugin-mdx on August 16 with support for MDX v2: https://github.com/gatsbyjs/gatsby/pull/35650

I haven't tried https://github.com/LekoArts/mdx-v2-example with Theme UI yet to see if there any compat issues, just wanted to put this on y'all radar.

LekoArts avatar Aug 05 '22 06:08 LekoArts

Great news @johno! Our latest develop release fixes this issue thanks to @hasparus. Just forked your test repo & updated deps, it's working: https://github.com/lachlanjc/repro-mdx-v2-theme-ui/commit/5990f8e1c093e27493777e66df9f080f6d2deb1e

lachlanjc avatar Sep 19 '22 04:09 lachlanjc

Awesome @lachlanjc and @hasparus, thanks! Y'all rock!

johno avatar Sep 19 '22 14:09 johno