"Error: Cannot find module 'react/jsx-runtime'" when consuming Parcel's multi-module React component library in Next.js project created by "yarn create next-app" command
See original GitHub issue🐛 bug report
Error “Cannot find module ‘react/jsx-runtime’” happens when consuming Parcel’s multi-module React component library in a Next.js project. I already spent a week just to fix this build, I really like developing Parcel API, so I really appreciate any help/suggestion to make this work 😢 . I tried to adjust engines in the parcel config, context field, add/remove targets, but it doesn’t seem to work (it can build but Next.js couldn’t consume it - alway get an error like “Can’t find module ‘…’”), also when I include “react” in includeModules field or set includeModules to true, it produced the error “Can’t have more than 1 copy of React…”.
🎛 Configuration (.babelrc, package.json, cli command)
.babelrc:
- I don’t have
.babelrcin my project, I just use default babel configuration in@parcel/config-default.
package.json:
{
"name": "reproduce-parcel-issue",
"version": "1.0.0",
"description": "Code configuration to reproduce parcel issue",
"engines": {
"node": ">= 12"
},
"browserslist": "> 0.5%, last 2 versions, not dead",
"author": "Thien Huynh",
"license": "MIT",
"private": false,
"devDependencies": {
"@parcel/core": "^2.5.0",
"@parcel/packager-ts": "2.5.0",
"@parcel/transformer-typescript-tsc": "^2.5.0",
"@parcel/transformer-typescript-types": "2.5.0",
"@parcel/types": "^2.5.0",
"@types/node": "^17.0.31",
"@types/react": "17.0.41",
"@types/react-dom": "17.0.13",
"@types/styled-components": "5.1.24",
"eslint": "7.32.0",
"eslint-config-airbnb": "18.2.0",
"eslint-config-airbnb-typescript": "^12.3.1",
"eslint-config-prettier": "^6.11.0",
"eslint-import-resolver-parcel2": "^1.0.1",
"eslint-plugin-import": "2.25.4",
"eslint-plugin-jest": "24.7.0",
"eslint-plugin-jsx-a11y": "6.5.1",
"eslint-plugin-prettier": "3.4.1",
"eslint-plugin-react": "7.29.4",
"eslint-plugin-react-hooks": "4.3.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"@typescript-eslint/eslint-plugin": "4.33.0",
"@typescript-eslint/parser": "4.33.0",
"dotenv": "^16.0.0",
"postcss": "8.4.12",
"postcss-preset-env": "6.7.1",
"parcel": "^2.5.0",
"prettier": "2.6.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-hotkeys-hook": "3.4.4",
"react-is": "17.0.2",
"react-tooltip": "4.2.21",
"styled-components": "5.3.3",
"ttypescript": "^1.5.13",
"typescript": "4.6.2"
},
"resolutions": {
"@types/react": "17.0.41",
"@types/react-dom": "17.0.13"
},
"peerDependencies": {
"framer-motion": "^4.x",
"react": "^17.x",
"react-dom": "^17.x",
"react-hotkeys-hook": "^3.x",
"react-is": "^17.x",
"react-tooltip": "^4.x",
"styled-components": "^5.x"
},
"eslintConfig": {
"extends": "react-app"
},
"scripts": {
"prebuild": "rm -rf ./dist .parcel-cache && ttsc build.ts --outDir . --module es2022 --sourceMap true && mv build.js build.mjs",
"build": "node build.mjs && yarn build:dts",
"postbuild": "yarn build:prep:publish",
"prebuild:dts": "echo 'building dts'",
"build:dts": "ttsc --emitDeclarationOnly",
"posbuild:dts": "echo 'done build dts'",
"prebuild:prep:publish": "echo 'building for publishing'",
"build:prep:publish": "ttsc src/setupPackage.ts --sourceMap false && mv dist/setupPackage.js ./dist/setupPackage.mjs && node dist/setupPackage.mjs",
"postbuild:prep:publish": "echo 'done building for publishing'"
},
"exports": {
".": {
"import": "./module/index.js",
"node": "./module/index.js",
"module": "./module/index.js",
"default": "./index.js"
},
"./components/*": {
"import": "./module/components/**/*.js",
"node": "./module/components/**/*.js",
"module": "./module/components/**/*.js",
"default": "./components/**/*.js"
},
"./icons/*": {
"import": "./module/icons/*.js",
"node": "./module/icons/*.js",
"module": "./module/icons/*.js",
"default": "./icons/*.js"
}
}
}
build.ts: (parcel config)
{
detailedReport: { assetsPerBundle: 20 },
entries: 'src/index.ts' // or 'src/icons/*.tsx',
targets: {
main: {
distDir: 'dist',
context: 'browser',
engines: {
browsers: ['> 0.5%', 'last 2 versions', 'not dead'],
parcel: '>2.5',
},
},
module: {
distDir: 'dist/module',
context: 'node',
engines: {
node: '>= 12',
parcel: '>2.5',
},
},
},
defaultTargetOptions: {
isLibrary: true,
sourceMaps: false,
shouldOptimize: false,
outputFormat: 'esmodule',
engines: {
parcel: '>2.5',
},
},
shouldPatchConsole: true,
shouldAutoInstall: true,
shouldContentHash: false,
additionalReporters: [
{
packageName: '@parcel/reporter-cli',
resolveFrom: fileURLToPath(import.meta.url),
},
],
defaultConfig: '@parcel/config-default',
mode: 'production',
}
🤔 Expected Behavior
No runtime exception. The library should be able to be consumed in the Next.js project.
Be able to import components from the reproduce-parcel-issue library in the Next.js project:
import { Button } from "reproduce-parcel-issue";
// or
import { Button } from "reproduce-parcel-issue/components/Button/Button"
// or
import { Anchor } from "reproduce-parcel-issue/components/Button/Anchor"
😯 Current Behavior
Produced error “Cannot find module ‘react/jsx-runtime’” when access to dev url localhost:3000 after ran yarn dev in Next.js project.
Stack traces:
Unhandled Runtime Error
Error: Cannot find module 'react/jsx-runtime'
Call Stack
newRequire
node_modules/reproduce-parcel-issue/module/index.js (61:0)
newRequire
node_modules/reproduce-parcel-issue/module/index.js (45:0)
localRequire
node_modules/reproduce-parcel-issue/module/index.js (84:32)
Object.2G6Uk.@parcel/transformer-js/src/esmodule-helpers.js
node_modules/reproduce-parcel-issue/module/index.js (169:0)
newRequire
node_modules/reproduce-parcel-issue/module/index.js (71:0)
localRequire
node_modules/reproduce-parcel-issue/module/index.js (84:32)
Object.gGjxz../Anchor
node_modules/reproduce-parcel-issue/module/index.js (161:0)
newRequire
node_modules/reproduce-parcel-issue/module/index.js (71:0)
localRequire
node_modules/reproduce-parcel-issue/module/index.js (84:32)
Object.XliwM../components/Button
node_modules/reproduce-parcel-issue/module/index.js (152:0)
newRequire
node_modules/reproduce-parcel-issue/module/index.js (71:0)
eval
node_modules/reproduce-parcel-issue/module/index.js (122:0)
eval
node_modules/reproduce-parcel-issue/module/index.js (145:1)
Object../node_modules/reproduce-parcel-issue/module/index.js
file:///Users/thienhuynh/test-next/.next/static/chunks/pages/index.js (454:1)
Object.options.factory
/_next/static/chunks/webpack.js (685:31)
__webpack_require__
file:///Users/thienhuynh/test-next/.next/static/chunks/webpack.js (37:33)
fn
/_next/static/chunks/webpack.js (354:21)
eval
webpack-internal:///./pages/index.js (11:80)
Module../pages/index.js
file:///Users/thienhuynh/test-next/.next/static/chunks/pages/index.js (117:1)
Module.options.factory
/_next/static/chunks/webpack.js (685:31)
__webpack_require__
file:///Users/thienhuynh/test-next/.next/static/chunks/webpack.js (37:33)
fn
/_next/static/chunks/webpack.js (354:21)
eval
node_modules/next/dist/build/webpack/loaders/next-client-pages-loader.js?page=%2F&absolutePagePath=%2FUsers%2Fthienhuynh%2Ftest-next%2Fpages%2Findex.js! (5:15)
eval
node_modules/next/dist/client/route-loader.js (207:48)
💁 Possible Solution
I don’t know if this is the issue with Parcel or Next.js configuration. Maybe making the right configuration options in the Parcel API to either generate the bundled script can be used on the client side (be able to use shared modules (react, react-dom, styled-components, …) on the browser) or make Next.js to be able to consume the library directly (like importing it as if it’s an internal code in Next.js project when the library’s not bundled and minified) before building pages 💁
🔦 Context
I’m trying to create a public multi-module React component library that would be consumed by the Next.js project. I want to separate the modules, so the consumers don’t need to import everything when they just want to consume just one component in the big module. And the way I use Parcel to bundle in my mini project is by writing a script build.ts that use Parcel API.
The script build.ts will just loop through the module configs list and call Parcel API to bundle it.
💻 Code Sample
Repositories:
Step to reproduce:
- Clone this React project “Parcel bundling sample script” and run the command below to generate bundled modules in
distfolder
yarn && yarn build
- Clone this project “Next.js project consume bundled Parcel library” (created with the
create-next-app). - Copy generated
distfolder from “Parcel bundling sample script” project over the Next.js project, run command below in Next.js project’s terminal to install local module in project’s dependenciesnode_modulesand build dev server:
yarn && yarn dev
🌍 Your Environment
| Software | Version(s) |
|---|---|
| Parcel | 2.5.0 |
| Node | 14.19.0 |
| npm/Yarn | Yarn (1.22.17) |
| Operating System | MacOS |
Update
With same configuration, I tried to bundle project with Rollup and it works perfectly when I use the library in the next project. I added building process for using Rollup.js to bundle in this repository Parcel bundling sample script on branch feat/rollup-test.
Step to reproduce:
- Clone this repository Parcel bundling sample script and switch branch to
feat/rollup-test - Run command below to install dependencies and build the library with rollup
yarn && yarn build:rollup
- Copy generated
distfolder from “Parcel bundling sample script” project over the Next.js project, run command below in Next.js project’s terminal to install local module in project’s dependenciesnode_modulesand build dev server:
yarn && yarn dev
Issue Analytics
- State:
- Created a year ago
- Comments:9
Top Related StackOverflow Question
@djuretic I think
reactshould not be independenciesand the library built by Parcel should use whichever thereactversion on the consumer project, because I use Parcel in order to build the library, and ifreactis thedependency, it may cause an error since it initiates more than 2reactinstances in the same app.Even though this issue is closed, I want to comment about what worked for me.
I was having both
Failed to resolve 'react/jsx-runtime'andExternal dependency "react" is not declared in package.jsonerrors, movingreactand some other packages fromdevDependenciestodependenciesinpackage.jsonsolved the errors.