preact
preact copied to clipboard
Uncaught TypeError: Cannot read properties of undefined (reading '__H')
Got a problem when bundling preact with typescript
main.bundle.js:1 Uncaught TypeError: Cannot read properties of undefined (reading '__H') at main.bundle.js:1:12917 at main.bundle.js:1:12990 at ne (main.bundle.js:1:13138) at main.bundle.js:1:14979 at main.bundle.js:1:15040 at main.bundle.js:1:15062
I just added preact/hook import on a file. I have already tried to see if I was calling render more times, or id webpack is duplicating the module, but look,
I saw already some issues like this, all closed without a big explanation why it started to work.
I mean, we will need a bit more of a reproduction 😅 generally these issues are caused by duplicate copies of Preact
I gonna try to reproduce this, unfortunately my setup has webpack 5 and node 18, I gonna try to re-recreate a demo with same webpack+typescript configuration and uploaded it
I made some modifications on a base typescript project and I end up reproducing the issue
I have node 18, windows 11, and using powershell
the code with the issue is on here
The link is to your profile, looks like this is a preact-cli issue though so I will move it there, best to include some reproduction steps though
I updated the link, sorry about missing the right repo, I was sure that I was in the right place. I used the cli, but I am using webpack 5
Is it a Preact-CLI issue? You have various Webpack dependencies and a webpack.config.js
sitting there.
It's unclear whether you're using Webpack directly or using Preact-CLI.
I dont thing is Preact-CLI, I am using
npx webpack serve
Some transferred this, by I thing this is preact, maybe caused by something new that webpack 5 is doing, not sure
Heh, sorry hence the ask for reproduction steps 😅 I saw preact-cli in the package json and that worked fine for me
@JoviDeCroock Should I transfer this back?
@nmocruz It'd really help in that case to cut down your app to the minimal reproduction. It doesn't make much sense to have preact-cli
installed (and scripts using Preact-CLI) when you're not actually using it.
@rschristian I used the cli just to generate a demo, and then I adjusted the demo to use webpack 5, ts-loader and instead to be near my other project. My other project is using dotnet core, maybe hard to setup and run, but I was able to reproduce it like this
That's totally fine, but you can probably imagine how maintainers might get confused? You say you use npx webpack serve
, and yet your scripts don't show that at all:
"scripts": {
"build": "preact build",
"serve": "SET NODE_OPTIONS=--openssl-legacy-provider sirv build --cors --single",
"dev": "preact watch",
"lint": "eslint src",
"test": "jest"
},
The ReadMe in your project says npm run build
is how to generate a build: https://github.com/nmocruz/preactjsdemo#cli-commands
It'd help us track down your problem if you removed these things and provided clear instructions alongside a minimal reproduction.
yes, as I said I used the cli to build a quick/repo demo to show you the issue. I could remove all cli references on the original code generated by the cli or maybe have started one from scratch. but I fully understand the readme and the scripts should have that removed to not mislead you. I have going to updated the demo, so no one else gets confused. ps, done
it seems like the problem is webpack or loaders on version 5, I downgraded the webpack toolset to use webpack 4 instead of 5 and it started to work
I haven't looked too deep into your setup, however I have played with mine a bit which is also webpack 5 an example can be found here the bigger differences I saw were babel-loader
, something might be related to those tsconfig paths and maybe webpack 5 needs an alias for Preact itself due to it being eager on duplicating stuff 😅
Might have some time to look into your specific one over the weekend
ok, I didn't try babel-loader, only ts-loader. I'm not 100% sure if I tried esbuild-loader, but I have an idea that was my first attempt, and then I switched to ts-loader. But it can be also so problems on my tsconfig that is not clear that it will break the hooks import
Just opened your application and everything works fine, all I had to do was add mode: 'development'
to your webpack config (which it was warning you about) and the UI renders fine
that is strange, smells like it's an environment thing (node related with mode:development, because I also tried). do you tested with node 18 or 16? windows or linux? I saw on the past issue just because people used old powershell to run nodejs tools.
Node 16 and 18, macOS
Wondering if this can be webpack missing module types, like mjs with es6, or others? I am trying to bundle something to run SSR on a JavaScript engine under/bound to Dotnet core framework, not nodejs. Is a V8 engine so I think maybe the webpack is picking wrong module when mixing server rendering, preact and hooks with different module types
still without any solution, I tried many modules types a few bundles it seems like the problem when render to string the currentComponent is null, not sure if I'm using this library right or not.
The main reason currentComponent
is null
is when you have multiple versions of preact in your bundle. Hooks by design have to rely on a shared singleton. The preact/hooks
import, loads preact
and if that version is different from the Preact version you're using to render your application you'll get this exact error.
Like @JoviDeCroock, I cannot reproduce the error on my end. Just had to add mode: "development"
to the webpack config to make the webpack error go away. Basically followed the instructions of the error message.
It seems like my issue now can have same error but is a bit diferent
import { render } from 'preact-render-to-string';
import { createApp } from './pages/app';
render(createApp(url, data), {}, {})
and app
export function createApp (initialUrl: string, initialData: any){
const [route, setRoute] = useState(initialUrl);
function OnRouteChanged(event: any){
setRoute(event.src)
}
useEffect(() => {
window.addEventListener('navidate', OnRouteChanged);
return () => window.removeEventListener('navigate', OnRouteChanged);
}, []);
const { Component } = getRoute(route)
return <div>
<Component />
</div>
}
it seems like createApp is not a component but just a function that returns one, and hooks is not seeing that function as a component.
It more like a lack of knowledge and confusion on what that error was really telling us.
@nmocruz that is because you're not calling it like a component. Hooks are only allowed to be used inside components.
- function createApp(url: string, data: any) {
+ function App({ url, data }) {
const [route, setRoute] = useState(url);
// ...
}
- render(createApp(url, data), {}, {})
+ render(<App url={url} data={data} />)
Or if you're nodejs pipeline isn't set up for JSX, you could call the JSX factory function manually:
import { createElement } from "preact";
render(createElement(App, { url, data }))
The reason for this, is that the JSX-transform (or manually calling the JSX factory) is what ultimately turns a plain function into a component.
It works now, was just my lack of knowledge about using hooks on functions, or the difference between a function a component. I just recommend putting maybe that info handier, because I was spending time trying stuff around the bundling.