Open eco-front-end-team opened 1 year ago
<Button>
is not a class component in Blueprint v5.x.
Can you help me debug this? Is there a way you can repro this error with a code sandbox or stackblitz environment?
<Button>
is not a class component in Blueprint v5.x.Can you help me debug this? Is there a way you can repro this error with a code sandbox or stackblitz environment?
https://stackblitz.com/edit/next-typescript-c1wmce?file=package.json
Same problem
This is my package.json
I'm using node v16.20.1
"dependencies": {
"@blueprintjs/core": "^5.0.1",
"autoprefixer": "10.4.14",
"eslint": "8.44.0",
"eslint-config-next": "13.4.9",
"next": "13.4.9",
"postcss": "8.4.25",
"react": "18.2.0",
"react-dom": "18.2.0",
"tailwindcss": "3.3.2",
"typescript": "5.1.6"
},
Also seeing this on the Icon component, I think it's due to file barrelling and not actually a component that's being rendered, but could be wrong.
edit: for some reason my blueprint is importing the cjs bundle, when it should be esm
if I do:
import { Icon } from '@blueprintjs/core/lib/esnext/index';
now the page renders, but getting errors from other components that are being imported:
- warn ../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/common/abstractComponent.js
Attempted import error: 'Component' is not exported from 'react' (imported as 'React').
Import trace for requested module:
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/common/abstractComponent.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/deprecatedTypeAliases.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/index.js
./src/components/ui/button.tsx
./src/app/(extra)/(bare)/components/button/page.tsx
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/common/abstractPureComponent.js
Attempted import error: 'PureComponent' is not exported from 'react' (imported as 'React').
Import trace for requested module:
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/common/abstractPureComponent.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/deprecatedTypeAliases.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/index.js
./src/components/ui/button.tsx
./src/app/(extra)/(bare)/components/button/page.tsx
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/button/buttons.js
Attempted import error: 'useState' is not exported from 'react' (imported as 'React').
Import trace for requested module:
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/button/buttons.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/index.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/index.js
./src/components/ui/button.tsx
./src/app/(extra)/(bare)/components/button/page.tsx
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/button/buttons.js
Attempted import error: 'useState' is not exported from 'react' (imported as 'React').
Import trace for requested module:
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/button/buttons.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/index.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/index.js
./src/components/ui/button.tsx
./src/app/(extra)/(bare)/components/button/page.tsx
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/button/buttons.js
Attempted import error: 'useRef' is not exported from 'react' (imported as 'React').
Import trace for requested module:
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/button/buttons.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/index.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/index.js
./src/components/ui/button.tsx
./src/app/(extra)/(bare)/components/button/page.tsx
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/context-menu/contextMenu.js
Attempted import error: 'useState' is not exported from 'react' (imported as 'React').
Import trace for requested module:
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/context-menu/contextMenu.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/index.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/index.js
./src/components/ui/button.tsx
./src/app/(extra)/(bare)/components/button/page.tsx
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/context-menu/contextMenu.js
Attempted import error: 'useState' is not exported from 'react' (imported as 'React').
Import trace for requested module:
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/context-menu/contextMenu.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/index.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/index.js
./src/components/ui/button.tsx
./src/app/(extra)/(bare)/components/button/page.tsx
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/context-menu/contextMenu.js
Attempted import error: 'useState' is not exported from 'react' (imported as 'React').
Import trace for requested module:
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/context-menu/contextMenu.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/index.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/index.js
./src/components/ui/button.tsx
./src/app/(extra)/(bare)/components/button/page.tsx
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/context-menu/contextMenu.js
Attempted import error: 'useRef' is not exported from 'react' (imported as 'React').
Import trace for requested module:
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/context-menu/contextMenu.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/index.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/index.js
./src/components/ui/button.tsx
./src/app/(extra)/(bare)/components/button/page.tsx
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/context-menu/contextMenu.js
Attempted import error: 'useEffect' is not exported from 'react' (imported as 'React').
Import trace for requested module:
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/context-menu/contextMenu.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/components/index.js
../../node_modules/.pnpm/@blueprintjs+core@5.0.1_@types+react@18.2.14_react-dom@18.2.0_react@18.2.0/node_modules/@blueprintjs/core/lib/esnext/index.js
./src/components/ui/button.tsx
./src/app/(extra)/(bare)/components/button/page.tsx
This issue sounds a bit like https://github.com/vercel/next.js/issues/39375 (although Blueprint is not specifying an "exports"
field in package.json).
I tried changing to "moduleResolution": "nodenext"
in tsconfig.json
in your stackblitz but the same issue still shows up: https://stackblitz.com/edit/next-typescript-mvuuvj?file=tsconfig.json. This might be a bug in Next.js?
According to NextJS doc https://nextjs.org/docs/messages/class-component-in-server-component We need to render blueprintjs component only in client component I modified the stackblitz to client component It seems work, but I'm not sure if it is proper or not. https://stackblitz.com/edit/next-typescript-fxxvuk?file=src%2Fapp%2Fpage.tsx
We're using Blueprintjs extensively with in a nextjs project.
The key is the use client
directive on top. I think the primary issue under this is that many bp components are class components, these don't work in SSR with nextjs.
@adidahiya any thinking about a refactor to function components? I saw that some of the bp components already are, are there any specific features of class components needed for the other ones? If not we'd be happy to help update them to react.FC, and maybe in meantime I'm happy to put something in the docs or as a discussion to label which components are classes and which are FC (and test that those work for SSR).
I haven't tested SSR with the FC components (like button), I'll give that a try tomorrow.
After looking through the code a bit, it looks like newer components are all FCs, and that the things being used on class components are:
Default props would be easy to transition over, while I'm not sure how prop validation or animation would work (but can't yet find a component using the animation methods).
There are definitely some easy candidates for moving over to FCs (like slider), I'm happy to work on converting some of the low-hanging fruit if thats useful.
@adidahiya any thinking about a refactor to function components?
Hey @tevonsb, I wanted to give a heads up that Adi is taking a well-deserved rest and will be back in September. I appreciate your offer to help. I suspect he'll have better informed thoughts than I will when he's back.
@gluxon great! No rush from our end, thanks for the heads up :)
@tevonsb what are the drawbacks from a UX perspective of using class components in Next.js applications? How does migrating every component to be an FC concretely help end-users? I'm willing to be convinced, but I would like to really understand the motivation here.
As you mentioned, newer Blueprint components are FCs. I also managed to migrate many simple components from classes to FCs in the latest major version, v5.0. I have an issue tracking the migration of other simple components for v6.0: https://github.com/palantir/blueprint/issues/6289. I'd be open to PRs for contributions there (not yet though; a few months from now when I create a next
branch for v6.0 work with breaking changes).
Finally, the remaining class components are fairly complex, so migrating them accurately would require a decent amount of work. For example, DateRangeInput is 1000+ lines and has a lot of complex state management. Taking on this migration would need some compelling justification.
Hey @adidahiya Sorry for the delay on my end!
This issue is really helpful, having these simple components as function components I think is half the battle at least.
The compelling piece from a DX perspective is allowing for SSR. class components currently can only render on client, not using SSR (at least in nextjs world), according to this link, it seems that react server components require function components (given their dependence on async/await, correct me if I'm wrong on this!
So refactoring to function components would unlock the value of server components as well as the various improvements that react is introducing around them.
Given that nextjs and SSR are really taking off it seems quite beneficial for devs to be able to use them.
Like I mentioned we'd be happy to submit PRs helping convert the simple components! As well as digging into the more complex ones as well.
One thought could be to break the complex components out of core (like table etc already is), so that core is "complete" and devs could install additional components themselves and use the "use client" directive.
We're planning to do something like this already, pushing these complex components down to the leaves so that the majority of our app can render on server, then add client components at the end.
Environment
Code Sandbox
Steps to reproduce
Just run the NextJS app. It will throw following errors. I've tried different components still getting the same error.
Actual behavior