next-plugin-preact icon indicating copy to clipboard operation
next-plugin-preact copied to clipboard

Nextjs v10 h.render is not a function

Open prisis opened this issue 3 years ago • 24 comments

Hey :),

im testing next.js v10 with preact and geting this error TypeError: h.render is not a function  with fast refresh.

If you need a repository to check the steup, i can provide you one

prisis avatar Oct 29 '20 16:10 prisis

Hey @JoviDeCroock maybe you have a idea?

prisis avatar Oct 30 '20 14:10 prisis

Mind trying with something else than pnpm? 😅 sorry not familiar with strict package managers and want to exclude that that is the issue. I can go on codesandbox later and try to see if I can reproduce the issue

JoviDeCroock avatar Oct 30 '20 14:10 JoviDeCroock

Yeah will try it :)

prisis avatar Oct 30 '20 15:10 prisis

So getting the same error, but webpack did show a bit more now

<w> [webpack.cache.PackFileCacheStrategy] Skipped not serializable cache item 'Compilation/modules|/home/Dokumente/a/node_modules/next/node_modules/@next/react-refresh-utils/loader.js!/home/Dokumente/a/node_modules/next/dist/build/webpack/loaders/next-babel-loader.js??ruleSet[1].rules[1].use[1]!/home/Dokumente/a/pages/_app.tsx': No serializer registered for ProvidedDependency
<w> while serializing webpack/lib/cache/PackFileCacheStrategy.PackContentItems -> webpack/lib/NormalModule -> Array { 37 items } -> ProvidedDependency
<w> [webpack.cache.PackFileCacheStrategy] Skipped not serializable cache item 'Compilation/modules|/home/Dokumente/a/node_modules/next/node_modules/@next/react-refresh-utils/loader.js!/home/Dokumente/a/node_modules/next/dist/build/webpack/loaders/next-babel-loader.js??ruleSet[1].rules[1].use[1]!/home/Dokumente/a/components/i18n/index.tsx': No serializer registered for ProvidedDependency
<w> while serializing webpack/lib/cache/PackFileCacheStrategy.PackContentItems -> webpack/lib/NormalModule -> Array { 22 items } -> ProvidedDependency
<w> [webpack.cache.PackFileCacheStrategy] Skipped not serializable cache item 'Compilation/modules|/home/Dokumente/a/node_modules/next/node_modules/@next/react-refresh-utils/loader.js!/home/Dokumente/a/node_modules/next/dist/build/webpack/loaders/next-babel-loader.js??ruleSet[1].rules[1].use[1]!/home/Dokumente/a/locales/de/index.ts': No serializer registered for ProvidedDependency
<w> while serializing webpack/lib/cache/PackFileCacheStrategy.PackContentItems -> webpack/lib/NormalModule -> Array { 7 items } -> ProvidedDependency
<w> [webpack.cache.PackFileCacheStrategy] Skipped not serializable cache item 'Compilation/modules|/home/Dokumente/a/node_modules/next/node_modules/@next/react-refresh-utils/loader.js!/home/Dokumente/a/node_modules/next/dist/build/webpack/loaders/next-babel-loader.js??ruleSet[1].rules[1].use[1]!/home/Dokumente/a/locales/en/index.ts': No serializer registered for ProvidedDependency
<w> while serializing webpack/lib/cache/PackFileCacheStrategy.PackContentItems -> webpack/lib/NormalModule -> Array { 7 items } -> ProvidedDependency
<w> [webpack.cache.PackFileCacheStrategy] Caching failed for pack: Error: No serializer registered for OriginalSource
<w> while serializing webpack/lib/util/registerExternalSerializer.webpack-sources/ConcatSource -> Array { 8 items } -> webpack/lib/util/registerExternalSerializer.webpack-sources/PrefixSource -> webpack/lib/util/registerExternalSerializer.webpack-sources/ConcatSource -> Array { 37 items } -> webpack/lib/util/registerExternalSerializer.webpack-sources/PrefixSource -> OriginalSource

prisis avatar Oct 30 '20 15:10 prisis

You can check this repo https://github.com/anolilab/next.js-template for the error

prisis avatar Oct 30 '20 15:10 prisis

Could this be something related to the new JSX transform?

martpie avatar Oct 30 '20 15:10 martpie

So from what I can see from debugging this, h is supposed to refer to a component instance where our diff invokes the render function but in this case refers to a vnode instead.

Btw. trying this within the demo of this repo upgraded to next 10 HMR works fine.

@JoviDeCroock any clue why that could happen?

sventschui avatar Oct 30 '20 20:10 sventschui

Does anyone know if nextjs uses webpack 5 by default or do we have opt-in manually?

  "resolutions": {
    "webpack": "^5.3.2"
  },

I had no such issues

wiesson avatar Oct 31 '20 08:10 wiesson

You need to opt in https://nextjs.org/blog/next-9-5#webpack-5-support-beta

prisis avatar Oct 31 '20 08:10 prisis

@wiesson thx, webpack 5 is doing something different in the resolution then webpack 4, if i switch to webpack 4 it works

prisis avatar Oct 31 '20 08:10 prisis

Odd, it seems like with webpack 5 the module resolution and loaders start goofing up. I've had no issues during the beta. This issue could be located in two placed afaik:

  • Preact and the used export maps
  • Prefresh and the loader manipulation

JoviDeCroock avatar Oct 31 '20 09:10 JoviDeCroock

I'm using webpack 5.3.2 (at least I think that 😅) with usePreact at this site and I had no issues.

  "dependencies": {
    "@google/markerclustererplus": "^5.1.3",
    "bootstrap": "^5.0.0-alpha2",
    "date-fns": "^2.16.1",
    "framer-motion": "^2.9.4",
    "next": "^10.0.0",
    "node-sass": "^4.14.1",
    "next-plugin-preact": "^3.0.3",
    "preact": "^10.5.5",
    "preact-render-to-string": "^5.1.11",
    "react": "npm:@preact/[email protected]",
    "react-dom": "npm:@preact/[email protected]",
    "react-ssr-prepass": "npm:preact-ssr-prepass@^1.1.2"
  },
  "devDependencies": {
    "@types/googlemaps": "^3.40.1",
    "@types/node": "^14.14.2",
    "@types/react": "^16.9.53",
    "prettier": "^2.1.2",
    "remark": "^13.0.0",
    "remark-html": "^13.0.1",
    "typescript": "^4.0.5"
  },
  "resolutions": {
    "webpack": "^5.3.2"
  },

wiesson avatar Oct 31 '20 10:10 wiesson

@wiesson nice page :)

Can be that they fixed something in 5.3.2, will test it asap

prisis avatar Oct 31 '20 11:10 prisis

So tested it with yarn and webpack 5.3.0, 5.3.1 and 5.3.2 getting the same error the the wrong node is provided

prisis avatar Oct 31 '20 22:10 prisis

hey @prisis I just tried to repro this again to debug a bit further but I'm not able to reproduce it anymore. Might you be able share reproduction steps with the repository you linked to?

sventschui avatar Nov 12 '20 19:11 sventschui

Hey @sventschui, sorry for the late response, you need to update webpack to 5.3.0|5.3.1|5.3.2 and replace it in yarn https://nextjs.org/blog/next-9-5#webpack-5-support-beta

prisis avatar Nov 18 '20 16:11 prisis

So I dug into this a bit and it seems prefresh does not correctly detect Container from https://github.com/vercel/next.js/blob/f06c58911515d980e25c33874c5f18ade5ac99df/packages/next/pages/_app.tsx#L81 as a functional component but rather treats it as a class based component from how I understand the magics of prefresh.

In https://github.com/JoviDeCroock/prefresh/blob/21f8c4330a29edcb5d4493cda5465e6556a5f92c/packages/core/src/index.js#L65 prefresh assumes that an error is thrown when trying to instantiate a function component with the new keyword. This somehow doesn't hold true in this case but new Container() result in a vnode being returned?!

When adding a breakpoint with the condition typeof newInst.render !== 'function' && (newInst = vnode[_constants__WEBPACK_IMPORTED_MODULE_5__.VNODE_COMPONENT], newInst.constructor = NewType, false) to the line vnode[_constants__WEBPACK_IMPORTED_MODULE_5__.VNODE_COMPONENT] = newInst; (https://github.com/JoviDeCroock/prefresh/blob/21f8c4330a29edcb5d4493cda5465e6556a5f92c/packages/core/src/index.js#L74) HMR works like a charm.

@JoviDeCroock does this even make sense? Might there be a different way to detect functional components?

sventschui avatar Jan 11 '21 22:01 sventschui

@sventschui We could try a similar check to React, however isReactComponent doesn't exist in pure preact https://github.com/facebook/react/blob/master/packages/react-refresh/src/ReactFreshRuntime.js#L676

Will also check https://github.com/vercel/next.js/tree/canary/packages/react-refresh-utils

JoviDeCroock avatar Jan 11 '21 22:01 JoviDeCroock

@prisis is this issue still present for you?

JoviDeCroock avatar May 21 '21 08:05 JoviDeCroock

Hey :), sorry for the late response.

Still getting a error if i try to run nextjs + webpack5 + preactjs 

 Error: Can't detect valid entry point.
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:27:9)
    at /private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:16:19
    at Array.reduce (<anonymous>)
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:13:42)
    at /private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:16:19
    at Array.reduce (<anonymous>)
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:13:42)
Error: Can't detect valid entry point.
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:27:9)
    at /private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:16:19
    at Array.reduce (<anonymous>)
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:13:42)
    at /private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:16:19
    at Array.reduce (<anonymous>)
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:13:42)
Error: Can't detect valid entry point.
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:27:9)
    at /private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:16:19
    at Array.reduce (<anonymous>)
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:13:42)
    at /private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:16:19
    at Array.reduce (<anonymous>)
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:13:42)
Error: Can't detect valid entry point.
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:27:9)
    at /private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:16:19
    at Array.reduce (<anonymous>)
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:13:42)
    at /private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:16:19
    at Array.reduce (<anonymous>)
    at injectEntry (/private/anolilab/next.js-template/node_modules/@prefresh/next/node_modules/@prefresh/webpack/src/utils/injectEntry.js:13:42)

This repository has the current configuration https://github.com/anolilab/next.js-template/tree/webpack5-with-preact

prisis avatar May 24 '21 19:05 prisis

Are you running the latest? It works with latest for me?

JoviDeCroock avatar May 24 '21 19:05 JoviDeCroock

Yeah, using nextjs v10,.2.3, next-plugin-preact v3.0.6, preact v10.5.13, preact-render-to-string v5.19 and preact-ssr-prepass v1.13

Did debug it a bit and the error happens in injectEntry.js line 12-23

originalEntry:

react-refresh {
  import: [
    '/home/danielb/Dokumente/private/anolilab/next.js-template/node_modules/next/node_modules/@next/react-refresh-utils/runtime.js'
  ]
}
import [
  '/home/danielb/Dokumente/private/anolilab/next.js-template/node_modules/next/node_modules/@next/react-refresh-utils/runtime.js'
]
amp { import: [ './node_modules/next/dist/client/dev/amp-dev' ] }
import [ './node_modules/next/dist/client/dev/amp-dev' ]
main {
  import: [ 'preact/debug', './node_modules/next/dist/client/next-dev.js' ]
}
import [ 'preact/debug', './node_modules/next/dist/client/next-dev.js' ]
polyfills {
  import: [
    '/home/danielb/Dokumente/private/anolilab/next.js-template/node_modules/next/dist/client/polyfills.js'
  ]
}
import [
  '/home/danielb/Dokumente/private/anolilab/next.js-template/node_modules/next/dist/client/polyfills.js'
]
pages/_app {
  import: [
    'next-client-pages-loader?page=%2F_app&absolutePagePath=private-next-pages%2F_app.tsx!',
    '/home/danielb/Dokumente/private/anolilab/next.js-template/node_modules/next/dist/client/router.js'
  ],
  filename: undefined,
  layer: undefined,
  runtime: undefined,
  publicPath: undefined,
  chunkLoading: undefined,
  wasmLoading: undefined,
  dependOn: [ 'main' ],
  library: undefined
}
import [
  'next-client-pages-loader?page=%2F_app&absolutePagePath=private-next-pages%2F_app.tsx!',
  '/home/danielb/Dokumente/private/anolilab/next.js-template/node_modules/next/dist/client/router.js'
]
filename undefined

filename with value undefined, is than throwing the error

prisis avatar May 24 '21 22:05 prisis

Yeah, so normally that bug is resolved on the latest @prefresh/webpack when using webpack 5 as that code can't be reached

JoviDeCroock avatar May 24 '21 22:05 JoviDeCroock

Will test it asap, with the newest prefresh/webpack added to package.json

prisis avatar May 25 '21 12:05 prisis