ReactComponent Bundling Errors

I’m struggling to use the ReactComponent, because I don’t understand how the bundling is supposed to work. I’ve been reading and re-reading the bundling guide, but there doesn’t seem to be a fully functioning example for react.

I have:

# confetti.py
import panel as pn
from panel.custom import ReactComponent
pn.extension()

class Confetti(ReactComponent):
    _bundle = './ConfettiButton.bundle.js'

Confetti().servable()

and

// index.js
import { Confetti } from "./confetti";
import * as React from "react";
import { createRoot } from "react-dom/client";
export default { Confetti, React, createRoot };

package.js

{
    "name": "confetti-button",
    "dependencies": {
        "canvas-confetti": "^1.6.0",
        "react": "^18.3.1",
        "react-dom": "^18.3.1"
    }
}

confetti.jsx

import confetti from "canvas-confetti";

export function Confetti() {
  return <h1>Hi</h1>;
}

I then run:
esbuild index.js --bundle --format=esm --outfile=ConfettiButton.bundle.js
and
panel serve confetti.py

But get:

[bokeh 3.6.1] setting log level to: 'info'
bokeh.min.js?v=ab343bc1ea96aa3f04b4b7cc078b778826644f535553eabf00ca2afa504963f0a3b97f72c264d666877921765e160c8a5e75723c10651502c44946ae398026aa:234 [bokeh 3.6.1] Websocket connection 0 is now open
bokeh.min.js?v=ab343bc1ea96aa3f04b4b7cc078b778826644f535553eabf00ca2afa504963f0a3b97f72c264d666877921765e160c8a5e75723c10651502c44946ae398026aa:166 [bokeh 3.6.1] document idle at 214 ms
bokeh.min.js?v=ab343bc1ea96aa3f04b4b7cc078b778826644f535553eabf00ca2afa504963f0a3b97f72c264d666877921765e160c8a5e75723c10651502c44946ae398026aa:164 Bokeh items were rendered successfully
ConfettiButton.bundle.js:158 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `Component`. Error Component Stack
    at Component (c0eff922-dae3-4ef3-921b-eb702f1f515f:126:1)
overrideMethod @ hook.js:608
printWarning @ ConfettiButton.bundle.js:158
error @ ConfettiButton.bundle.js:142
createElementWithValidation @ ConfettiButton.bundle.js:1608
render @ c0eff922-dae3-4ef3-921b-eb702f1f515f:134
finishClassComponent @ ConfettiButton.bundle.js:16652
updateClassComponent @ ConfettiButton.bundle.js:16617
beginWork @ ConfettiButton.bundle.js:17883
beginWork$1 @ ConfettiButton.bundle.js:21711
performUnitOfWork @ ConfettiButton.bundle.js:21156
workLoopSync @ ConfettiButton.bundle.js:21095
renderRootSync @ ConfettiButton.bundle.js:21074
performConcurrentWorkOnRoot @ ConfettiButton.bundle.js:20633
workLoop @ ConfettiButton.bundle.js:2102
flushWork @ ConfettiButton.bundle.js:2081
performWorkUntilDeadline @ ConfettiButton.bundle.js:2289
Show 1 more frame
Show less
ConfettiButton.bundle.js:158 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `Component`. Error Component Stack
    at Component (c0eff922-dae3-4ef3-921b-eb702f1f515f:126:1)
overrideMethod @ hook.js:608
printWarning @ ConfettiButton.bundle.js:158
error @ ConfettiButton.bundle.js:142
createElementWithValidation @ ConfettiButton.bundle.js:1608
render @ c0eff922-dae3-4ef3-921b-eb702f1f515f:134
finishClassComponent @ ConfettiButton.bundle.js:16652
updateClassComponent @ ConfettiButton.bundle.js:16617
beginWork @ ConfettiButton.bundle.js:17883
callCallback2 @ ConfettiButton.bundle.js:5585
invokeGuardedCallbackDev @ ConfettiButton.bundle.js:5610
invokeGuardedCallback @ ConfettiButton.bundle.js:5644
beginWork$1 @ ConfettiButton.bundle.js:21723
performUnitOfWork @ ConfettiButton.bundle.js:21156
workLoopSync @ ConfettiButton.bundle.js:21095
renderRootSync @ ConfettiButton.bundle.js:21074
performConcurrentWorkOnRoot @ ConfettiButton.bundle.js:20633
workLoop @ ConfettiButton.bundle.js:2102
flushWork @ ConfettiButton.bundle.js:2081
performWorkUntilDeadline @ ConfettiButton.bundle.js:2289
Show 1 more frame
Show less
ConfettiButton.bundle.js:22405 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `Component`.
    at createFiberFromTypeAndProps (ConfettiButton.bundle.js:22405:23)
    at createFiberFromElement (ConfettiButton.bundle.js:22426:23)
    at reconcileSingleElement (ConfettiButton.bundle.js:12465:31)
    at reconcileChildFibers2 (ConfettiButton.bundle.js:12502:43)
    at reconcileChildren (ConfettiButton.bundle.js:16243:37)
    at finishClassComponent (ConfettiButton.bundle.js:16671:13)
    at updateClassComponent (ConfettiButton.bundle.js:16617:32)
    at beginWork (ConfettiButton.bundle.js:17883:22)
    at HTMLUnknownElement.callCallback2 (ConfettiButton.bundle.js:5585:22)
    at Object.invokeGuardedCallbackDev (ConfettiButton.bundle.js:5610:24)
createFiberFromTypeAndProps @ ConfettiButton.bundle.js:22405
createFiberFromElement @ ConfettiButton.bundle.js:22426
reconcileSingleElement @ ConfettiButton.bundle.js:12465
reconcileChildFibers2 @ ConfettiButton.bundle.js:12502
reconcileChildren @ ConfettiButton.bundle.js:16243
finishClassComponent @ ConfettiButton.bundle.js:16671
updateClassComponent @ ConfettiButton.bundle.js:16617
beginWork @ ConfettiButton.bundle.js:17883
callCallback2 @ ConfettiButton.bundle.js:5585
invokeGuardedCallbackDev @ ConfettiButton.bundle.js:5610
invokeGuardedCallback @ ConfettiButton.bundle.js:5644
beginWork$1 @ ConfettiButton.bundle.js:21723
performUnitOfWork @ ConfettiButton.bundle.js:21156
workLoopSync @ ConfettiButton.bundle.js:21095
renderRootSync @ ConfettiButton.bundle.js:21074
performConcurrentWorkOnRoot @ ConfettiButton.bundle.js:20633
workLoop @ ConfettiButton.bundle.js:2102
flushWork @ ConfettiButton.bundle.js:2081
performWorkUntilDeadline @ ConfettiButton.bundle.js:2289

Any idea how to get this working? This example is obviously very simple, but I want to break out of writing typescript within a python file… not really the same thing.