Ship the frontend runtime JavaScript as an installable npm package
Maintainer antworten meist innerhalb von 1 Tag
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Anfängerfreundlichkeit
- 35/100
- Issue-Typ
- Feature
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- bun, javascript, python, react, vite
- Bereich
- backend, build-system, devtools, frontend
Rechercherichtung
Start by reading the pending-work checklist and the implementation branch claude/reflex-frontend-js-package-ockox9, then compare its install-flow changes with #7235 and #7451. Rebase the branch onto current main, open a PR, and review the breaking-change fragment and local-packages documentation. Done means the PR is ready and the release pipeline confirms the tarball is bundled in a pre-release wheel.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Problem
The JavaScript Reflex ships to every app (state.js, react-theme.js, upload.js, the helpers and components under utils/, style-reset.css, the vite plugins) lives in packages/reflex-base/src/reflex_base/.templates/web/ and is copied verbatim into each app's .web/ directory. That design has several costs:
- Compiler/runtime drift. Compiled output and the copied runtime are only guaranteed to match by wiping and re-initializing
.webon every Reflex version change, which also throws awaynode_modulesand lockfiles. - Untestable runtime. The shipped modules import per-app generated artifacts (
$/env.json,$/reflex.json,$/utils/context.js), so they cannot be loaded outside a compiled app, let alone unit-tested.state.jsimportingreflex.jsonis also one of the two causes of non-reproducible builds in #7562. - Dependency versions live in Python. react, react-dom, react-router, socket.io-client, universal-cookie and the build toolchain are maintained as
PackageJson.DEPENDENCIES/DEV_DEPENDENCIESconstants and pinned at the top level of the app'spackage.json; theREACT_VERSION/REACT_ROUTER_VERSIONenv vars are the only override.json5is used but never declared. - Path-coupled imports. Component packages and user custom code reference the runtime through
$/utils/...specifiers tied to the.weblayout.
Proposal
Ship the non-generated frontend runtime as a real npm package, @reflex-dev/reflex-base, at packages/reflex-base/src/reflex_base/frontend/, bundled inside the reflex-base wheel.
Packaging
- A stdlib-only hatch build hook packs a deterministic npm-format tarball into the wheel. The release build has no JS toolchain, and byte-stable tarballs keep the
file:integrity hashes in committedreflex.locklockfiles valid across rebuilds. The sdist keeps the JS source so wheels rebuild from it. - The package version derives from reflex-base's own version.
- A
verify-frontend-tgzrelease check asserts the wheel bundles exactly the right tarball and leaks neither source nornode_modules.
Install into .web
- Each run installs the package like any other dependency (
file:./<tarball>). Editable installs of reflex-base link the live source directory instead (link:for bun,file:for npm) so framework JS edits hot-reload without a reinstall. - The install flow writes the package entry itself and reconciles it: an unchanged entry keeps the frozen-lockfile install byte-for-byte; a superseded tarball frozen-installs first and is rewritten after; an unresolvable entry is rewritten up front. Legacy top-level framework pins are swept, superseded tarballs pruned, and the install cache keyed on the package version.
- A Reflex version change no longer wipes
.web:needs_reinit()narrows to missing-directory cases and a newrefresh_web_directory()overwrite-copies the remaining templates, deletes files owned by older versions and re-renders generated configs, keepingnode_modules, lockfiles and the project hash.
Runtime decoupling
- Shipped modules stop importing generated files. A
@reflex-dev/reflex-base/runtimeregistry is populated by the generatedutils/context.jsviaconfigureReflexRuntime()in its module body; the two module-scope reads of app config (EVENTURL, the embed-modelocationRefseed) become lazy. ColorModeContextmoves intoreact-theme.jsand the generated context re-exports it. Compiled components read env values throughgetEnv()instead of importingenv.json.
Compiler and imports
- Generated code and component import declarations reference the package by bare specifier (
@reflex-dev/reflex-base/state,.../react-theme,.../helpers/*,.../components/*,.../style-reset.css).constants.FrontendPackageis the single Python-side source of these specifiers, with a unit test asserting each resolves to a shipped file. - Back-compat for user code is three-layered:
merge_importsnormalizes legacy$/utils/...specifiers in Python import declarations, the generated vite config aliases them for user JS, and the app root keeps thewindow.__reflex["$/utils/state"]registry key for backend-evaluated dynamic components.Dirs.STATE_PATHandResetStylesheetremain as deprecated fallbacks.
Dependencies
- Runtime framework deps resolve transitively through the package manifest; the app-level toolchain is copied from its
devDependencies;shikiand@glideapps/glide-data-gridare optional peer deps deduped to the app root. - User version control moves to
overridesinreflex.lock/package.json.REACT_VERSION/REACT_ROUTER_VERSIONare deprecated (warn now, removed in 1.0).react-helmetis only installed whenrx.helmetis used.
Tests
- Vitest unit tests live inside the package (
frontend/tests/) and run as ajs-unit-testsCI job;state.jsbecomes unit-testable for the first time. The JS test tooling itself is tracked in #7611.
Pending work
The implementation lives on branch claude/reflex-frontend-js-package-ockox9 (7 commits, +4775/-348 across 99 files). It was validated end to end with reflex compile and reflex export of a scratch app in source mode, bun and npm installs of the packed tarball, and the wheel in a clean venv. No PR has been opened for it yet.
- Rebase onto current
main: the branch is based on #6919 (late August) and predates later changes to the install flow (for example #7235 and the open #7451). - Open the PR; re-check the breaking-change fragment (
news/+frontend-npm-package.breaking.md) and thedocs/wrapping-react/local-packages.mdsection describing thefile:/link:entry andoverrides. - Confirm the release pipeline builds the tarball into the wheel (
verify-frontend-tgzinscripts/release.py) on an actual pre-release.
Related
- #7611 JS unit tests for the shipped frontend
- #7562 / #7564 reproducible production builds
- Vorherrschende Sprache
- Python
- Sterne
- 29k
- Forks
- 1.8k
- Ø Merge
- 2 T. 22 Std.
- Gemergte PRs (30 T.)
- 143
Entwicklungsumgebung
Startet den Dev-Container des Projekts im Browser, mit Ihrem eigenen GitHub-Konto.
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus reflex-dev/reflex
-
Operations on a list[T] | None var throw when the value is NoneEvtl. vergeben @masenf hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
reflex-dev/reflex#7826 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
A dev run stopped before its backend loads leaves .web/nocompile, so the next run or export skips the compileEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
reflex-dev/reflex#7825 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
PropsBase nested serialization applies parent include/exclude filters to child fieldsEvtl. vergeben @harsh21234i hat das vor 1 Tag übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
reflex-dev/reflex#7787 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
OTel: add trace_flags to JSON log records so unsampled trace ids are recognizableEvtl. vergeben @ShaanGS hat das vor 7 Tagen übernommen. Offenenhancement
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
reflex-dev/reflex#7729 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
0.9.12 changelog follow-ups: the #7132 "_get_was_touched" entry describes unreachable behaviour, #7115's hasattr/getattr change is undocumented, #7131's wordingEvtl. wieder frei Ein Pull Request dazu wurde ohne Merge geschlossen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
reflex-dev/reflex#7260 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in reflex-dev/reflex
Ähnliche Issues
-
documentation good first issue priority: P2 status: ready
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 88/100
RhinoLink-Tech/data-fabric#500 ·
Maintainer antworten meist innerhalb von 1 Tag
-
backlog
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
EchoTools/nevr-runtime#2384 ·
Maintainer antworten meist innerhalb von 1 Tag
-
[Bug]: The H2 series' and the H3C's fan 3 is labelled "Chamber Fan", Bambu calls it the exhaust fanOffenarea:ui
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 88/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
btclib-org/btclib#3062 ·
Maintainer antworten meist innerhalb von 1 Tag
-
area:evals area:infra enhancement
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
jse-avl/support-bot#4 · 1 Kommentar ·