profile
viewpoint

Ask questionsBug: Cannot import 'react/jsx-runtime' from esm node/webpack 5

<!-- Please provide a clear and concise description of what the bug is. Include screenshots if needed. Please test using the latest version of the relevant React packages to make sure your issue has not already been fixed. -->

React version: 17.0.1

Steps To Reproduce

  1. Create a new directory, cd to it.
  2. Run npm i react@17 webpack@5 webpack-cli@4
  3. Create index.mjs with the following content:
    import * as jsx from 'react/jsx-runtime';
    console.log(jsx);
    
  4. Run node index.mjs
  5. Run npx webpack-cli path/to/index.mjs
    • I had to use an absolute path on my machine or webpack-cli wouldn't find index.mjs, don't know why.

<!-- Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Issues without reproduction steps or code examples may be immediately closed as not actionable. -->

Link to code example: --

<!-- Please provide a CodeSandbox (https://codesandbox.io/s/new), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem. You may provide a screenshot of the application if you think it is relevant to your bug report. Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve. -->

The current behavior

> node index.mjs
node:internal/process/esm_loader:74
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'D:\repos\jsx\node_modules\react\jsx-runtime' imported from D:\repos\jsx\index.mjs
Did you mean to import react/jsx-runtime.js?
    at new NodeError (node:internal/errors:277:15)
    at finalizeResolution (node:internal/modules/esm/resolve:307:11)
    at moduleResolve (node:internal/modules/esm/resolve:742:10)
    at Loader.defaultResolve [as _resolve] (node:internal/modules/esm/resolve:853:11)
    at Loader.resolve (node:internal/modules/esm/loader:85:40)
    at Loader.getModuleJob (node:internal/modules/esm/loader:229:28)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:51:40)
    at link (node:internal/modules/esm/module_job:50:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}
> npx webpack-cli D:\repos\jsx\index.mjs
[webpack-cli] Compilation finished
assets by status 264 bytes [cached] 1 asset
./index.mjs 64 bytes [built] [code generated]

ERROR in ./index.mjs 1:0-41
Module not found: Error: Can't resolve 'react/jsx-runtime' in 'D:\repos\jsx'
Did you mean 'jsx-runtime.js'?
BREAKING CHANGE: The request 'react/jsx-runtime' failed to resolve only because it was resolved as fully specified
(probably because the origin is a '*.mjs' file or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.

webpack 5.4.0 compiled with 1 error in 150 ms
npm ERR! code 1

The expected behavior

No issues importing react/jsx-runtime with no file extensions.

I can think of two solutions:

  • Fix babel, typescript, and all the other tools that automatically add the import to add the file extension.
    • That ship has sailed though, I don't think this is right thing to do.
  • Add the exports field in react's package.json.
    • This could also open the door to supporting prod/dev builds without depending on process.env.NODE_ENV for bundlers.
    • More discussion here: https://github.com/facebook/react/issues/11503#issuecomment-717589904
    • https://nodejs.org/dist/latest/docs/api/packages.html
    • https://webpack.js.org/guides/package-exports/
facebook/react

Answer questions nstepien

In the repo I work on, we've started publishing the library using the new runtime, using rollup+babel. If you install it (npm install react-data-grid), and check node_modules/react-data-grid/lib/bundle.js, you'll see the import:

import { jsxs, jsx, Fragment } from 'react/jsx-runtime';

Some bundlers like webpack 4 or rollup are fine with it, but webpack 5 adopted the newer Node semantics regarding esm, so it expects either a full path with file extension, or react/jsx-runtime to be matched in an exports map. It's also an issue in Node if you try to do server-side rendering from an esm file.

IMO adding an exports map should be a quick and safe enough fix. There are multiple transformers that would need fixing otherwise: Babel, TypeScript 4.1, more? I can go back to the classic runtime so it's not a major issue, but it needs to be fixed upstream one way or the other eventually.

useful!
source:https://uonfu.com/
Github User Rank List