Closed tembra closed 9 months ago
can you share the code? I had some issues at first with Next.js 14, but got it working. Ensure that you are explicitly using the "use client"; where appropriate.
@jpieters You can check the issue/example of the code in this repo: https://github.com/tembra/human-nextjs-14
There I tried many ways to load Human, each one in a specific intuitive named route, and they all fail.
http://localhost:3000/
default wayhttp://localhost:3000/no-ssr
http://localhost:3000/lazy-loaded
http://localhost:3000/load-on-button-click
Notice that even on /load-on-button-click
the error occurs during the build time. It seems that TypeScript/NextJS is executing the code inside the callback function that is assigned to a variable, but never called.
Even if NextJS is pre-rendering client components/pages on the server for the initial page load, it does not makes sense that this function is being executed.
Said that I think that import
keyword is the problem, with TypeScript/NextJS trying to immediately find/import the module during the build time. Thinking this way I also tried to use (and also change/adapt) the webpack configuration from next.config.js of the human-next demo.
If you can share how you got it working it will be awesome. I'm really out of ideas.
After digging deeper on webpack configuration I managed to get it working using this next.config.mjs
configuration:
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { webpack, isServer }) => {
if (isServer) {
config.plugins.push(
new webpack.IgnorePlugin({
checkResource(resource) {
if (resource === '@vladmandic/human') {
// ignore human package on server
return true
}
return false
},
})
// or a shorter (but not too explicit) version
// new webpack.IgnorePlugin({ resourceRegExp: /^@vladmandic\/human$/ })
)
}
return config
}
}
export default nextConfig
With this configuration all my examples of the shared code work.
However I obviously got the error below during page compiling. So this is not the correct approach.
$ npm run dev
> human-nextjs-14@0.1.0 dev
> next dev
▲ Next.js 14.1.0
- Local: http://localhost:3000
✓ Ready in 6s
○ Compiling / ...
✓ Compiled / in 8.4s (477 modules)
⨯ Error: Cannot find module '@vladmandic/human'
at webpackMissingModule (./app/page.tsx:7:50)
at eval (./app/page.tsx:7:142)
at (ssr)/./app/page.tsx (.../human-nextjs-14/.next/server/app/page.js:162:1)
at __webpack_require__ (.../human-nextjs-14/.next/server/webpack-runtime.js:33:42)
at JSON.parse (<anonymous>)
✓ Compiled in 243ms (230 modules)
I also still want to know WHY the module is being imported/resolved by webpack on server rendering if it is lazy loaded inside a callback.
Anyone has any thoughts/explanations or am I missing something in my code?
since this is not an issue with human
itself, this is better suited for discussions.
also, i'm not a next.js user, so really cannot help much. i've experimented with next long time ago and while i liked the concept, i really did not like how its build/packaging process and weird webpack worked.
Issue Description
When importing Human on a NextJS 14 project, the framework tries to import the node bundle instead of ESM for browsers, despite adding
'use client'
on top of the page file.Since node bundle requires a tfjs backend, the error below comes in:
I know that this is not an issue within the Human package at all and it's about NextJS SSR. However I guess you may help me to achieve the desired solution.
I already tried to load Human within a separated dynamic loaded component with
dynamic(() => import('@/components/Human'), { ssr: false })
, but it also did not work.I also tried to import it inside a
useEffect
of theHuman
component created as you did in your class constructor in NextJS demo, but it also did not work.I also tried to import Human explicitly from
@vladmandic/human/dist/human.esm
but it did not found the path.Everything works fine if I use Vite instead of NextJS to create my project.
Steps to Reproduce
npx create-next-app app-name
and choose all default configs.npm i
app/page.tsx
to add'use client'
on top the file and add import to Humanimport { Human } from '@vladmandic/human
.npm run dev
Expected Behavior
NextJS identify that I'm using a client component on that page and load ESM bundle of Human package instead of node bundle.
Environment
js
,esm
,esm-nobundle
)? esmDiagnostics
Additional
package.json