I’m trying to make transpiler to run as stand-alone node script.
// build.js
import esbuild from 'esbuild';
import path from 'path';
import { renderToString } from 'react-dom/server';
import React, { createElement } from 'react';
const params = {
common: {
bundle: true,
format: "esm",
jsxFactory: 'React.createElement',
jsxFragment: 'React.Fragment',
},
dev: {
sourcemap: true,
},
prod: {
sourcemap: false,
minify: true
}
}
const loader = {
common: {
'.js': 'jsx',
},
dev: {},
prod: {}
}
export const build = async (entryPoints, outdir, env="dev") => {
return await esbuild.build({
...params["common"],
...params[env],
entryPoints: entryPoints,
outdir: outdir,
write: true,
loader: {...loader["common"], ...loader[env]},
})
}
export const make_importer = async (entryPoints, outdir) => {
const files = entryPoints.map((p) => path.parse(p))
const output = path.parse(outdir)
return files.reduce((out, fh, i) => {
const output = path.join(outdir, `${fh.name}.js`)
out[fh.name] = {
import: async () => await import(output),
path: output
}
return out
}, {})
}
export const generate_ssr = async (entryPoints, outdir, env="dev") => {
await build(entryPoints, outdir, env)
const files = await make_importer(entryPoints, outdir)
return Object.entries(files).map(async ([k,v]) => {
const component = await v.import()
\ HERE LIES PROBLEM
const elem = createElement(component[k], {})
console.log(elem)
return renderToString(elem)
})
}
Can’t figure out how to make element with states:
export function Stuff() {
// const [isActive, setIsActive] = useState(false);
return (
<div className="App">
</div>
);
}
With this its OK:
{
'$$typeof': Symbol(react.element),
type: [Function: Stuff],
key: null,
ref: null,
props: {},
_owner: null,
_store: {}
}
<div class="App"></div>
But when i uncomment useState
:
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
...
[JSE] TypeError: Cannot read properties of null (reading 'useState')
[JSE] at useState2 (file:///static/Stuff.js:1089:29)
[JSE] at Stuff (file:///static/Stuff.js:1917:61)
...
package.json
{
"name": "esbuild-core",
"version": "1.0.0",
"description": "Esbuild js builder.",
"main": "index.ts",
"type": "module",
"entry": "./esbuild_core/public/index.tsx",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@types/node": "^20.12.10",
"@types/react": "^18.3",
"@types/react-dom": "^18.3",
"esbuild": "^0.20.2",
"react": "^18.3",
"react-dom": "^18.3",
"react-router-dom": "^6.23.0"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"outDir": "./dist",
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react",
"strictNullChecks": true,
"noEmit": false
}
}
Please help! I am out of ideas why internal React Dispatcher
is null.
Tried some combination of tsconfig ….
But nothing helps. Probably I am doing some dum-ass mistake.
New contributor
Matouš Polauf is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.