I receive the error Invalid hook call. Hooks can only be called inside of the body of a function component when attempting to use my Microbundled module in Create-React-App. Essentially, there are two versions of React. See Dan's comment.
I ran into this issue previously but was able to solve it by adding --globals react=react1, which felt like a hacky solution. However, I just re-ran yarn install and the issue came back.
Is there a known solution here?
Here's my module's package.json file.
{
"dependencies": {
"nanoid": "^2.1.8",
"normalizr": "^3.4.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-redux": "^7.1.3",
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"styled": "^1.0.0"
},
"devDependencies": {
"babel-eslint": "^10.0.3",
"eslint": "^6.8.0",
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-react-hooks": "^1.7.0",
"prop-types": "^15.7.2"
},
"license": "UNLICENSED",
"main": "dist/index.js",
"module": "dist/index.es.js",
"name": "tk-ux",
"peerDependencies": {
"prop-types": "^15.7.2"
},
"repository": "github:pBread/tk-ux.git",
"scripts": {
"build": "microbundle build --alias API=src/Modules/API/index.js,Constants=src/Constants/index.js,Containers=src/Containers/index.js,Modules=src/Modules/index.js,Utilities=src/Utilities/index.js --globals react=React --jsx React.createElement",
"dev": "yarn link && cd example && yarn link 'tk-ux' && yarn start",
"serve": "microbundle watch --alias API=src/Modules/API/index.js,Constants=src/Constants/index.js,Containers=src/Containers/index.js,Modules=src/Modules/index.js,Utilities=src/Utilities/index.js --globals react=React --jsx React.createElement"
},
"source": "./src/index.js",
"umd:main": "dist/index.umd.js",
"version": "1.0.0"
}
This may be related to yarn link behavior. I was able to resolve the issue (at least temporarily) by unlinking the package in my local environment then re-linking them.
I think this is still an issue that needs some clarification and/or documentation. Can anyone elaborate on best-practices for avoiding conflicts like these? i.e. accidentally creating two versions of a dependency.
try having react as a peer dependency
I think it was a combination of --globals react=React,react-dom=ReactDOM and adding them as peer dependencies. Although, I'm not sure if that was the full fix.
Here's my working package.json...
{
"dependencies": {
"nanoid": "^2.1.8",
"normalizr": "^3.4.1",
"prop-types": "^15.7.2",
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0"
},
"devDependencies": {
"eslint": "^6.8.0",
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-react-hooks": "^2.3.0",
"microbundle": "^0.11.0",
"prop-types": "^15.7.2"
},
"files": ["dist"],
"license": "UNLICENSED",
"main": "dist/index.js",
"module": "dist/index.es.js",
"name": "tk-ux",
"peerDependencies": {
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-redux": "^7.1.3"
},
"repository": "github:pBread/tk-ux.git",
"scripts": {
"build": "microbundle build --globals react=React,react-dom=ReactDOM --jsx React.createElement",
"dev": "yarn dev:link && cd example && yarn start",
"dev:link": "yarn link && cd example && yarn link 'tk-ux'",
"dev:unlink": "yarn unlink",
"serve": "yarn build --w"
},
"source": "./src/index.js",
"unpkg": "dist/index.umd.js",
"version": "1.0.0"
}
can you try without the --globals ...?
It's a bit weird, anything in dependencies and peerDependencies should automatically be treated as external (and not be bundled)
Hmmm... maybe I was running into an issue with yarn link. I'll try removing the globals and let you know.
Seems like this is more of a yarn issue than a Microbundle issue. Can we close?
I'm also having this issue, tried to use microbundle and it's including react even though react is a peerDependency
Hi @nicholasio!
Sorry to hear you're running into an issue. To help us best begin debugging the underlying cause, it is incredibly helpful if you're able to create a minimal reproduction. This is a simplified example of the issue that makes it clear and obvious what the issue is and how we can begin to debug it.
If you're up for it, we'd very much appreciate if you could provide a minimal reproduction and we'll be able to take another look.
As @ForsakenHarmony said, peerDependencies and dependencies are not bundled, but if you have react as a dependency, yarn will create a node_modules folder inside your library, so you actually have 2 react instances, the solution is to set react as peerDependencies, because that way you are letting yarn(or npm for this matter) know that it should use the global react package installed on that project.
This is not a problem with microbundle, but how you setup your package.json. I hope you find this explanation useful.
For me, the solution was to get rid of the umd export. For some reason (webpack or babel or NextJS?) was selecting that version, even though my package.json had all of the options available... And that particular build had the problem. React was VERY DEFINITELY getting included, and it was listed as a peer. (That said, it was also listed in the devDeps鈥攊s that possibly the bug? Because peers in devDeps should still be excluded.)
Anyway, here's my failing package.json, and my winning package.json.
I was also seeing react being bundled even though it was listed in devDependencies and peerDependencies. The solution for me was to add the prop-types package to the peerDependencies
Hmm - so it seems like Microbundle might be bundling dependencies of dependencies that are peers somehow? Seems strange.
@mikestopcontinues just an update - Next.js prefers CJS/UMD over ESM when bundling for the server. This doesn't align with any other bundler, so it's not something that makes much sense to account for in Microbundle.
In your failing package.json, the UMD build was being passed with --external none. That will inline all dependencies regardless of their presence in "dependencies" fields, causing the hooks error.
@developit Thanks for the tips. I'm not even sure what path lead me to include --external none. I'll take another look!
Most helpful comment
I'm also having this issue, tried to use microbundle and it's including react even though react is a peerDependency