Skip to content

Commit 6b4b1c0

Browse files
committed
ENG-6363: remix: ignore some changes in .web to reduce reloads (#5473)
* remix: ignore some changes in .web to reduce reloads ignore .web/backend and .web/reflex.install_frontend_packages.cached to avoid spurious additional full-reload * ENG-6363: Ensure ErrorBoundary is always in the AppWrap If the app is stateless, then the on_error is a no-op, but having it here means that any issues arising during HMR are caught by _our_ boundary, not the default, which halts execution of the script, when simply reloading again can resolve the issue. * update test expectation now that ErrorBoundary is always there * test_call_script: Poll for the last external function to be defined
1 parent 8365891 commit 6b4b1c0

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

reflex/.templates/web/vite.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ export default defineConfig((config) => ({
1111
},
1212
server: {
1313
port: process.env.PORT,
14+
watch: {
15+
ignored: [
16+
"**/.web/backend/**",
17+
"**/.web/reflex.install_frontend_packages.cached",
18+
],
19+
},
1420
},
1521
resolve: {
1622
mainFields: ["browser", "module", "jsnext"],

reflex/app.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
EventType,
7878
IndividualEventType,
7979
get_hydrate_event,
80+
noop,
8081
)
8182
from reflex.model import Model, get_db_status
8283
from reflex.page import DECORATED_PAGES
@@ -213,17 +214,21 @@ def default_overlay_components():
213214
return Fragment.create(memo(default_overlay_components)())
214215

215216

216-
def default_error_boundary(*children: Component) -> Component:
217+
def default_error_boundary(*children: Component, **props) -> Component:
217218
"""Default error_boundary attribute for App.
218219
219220
Args:
220221
*children: The children to render in the error boundary.
222+
**props: The props to pass to the error boundary.
221223
222224
Returns:
223225
The default error_boundary, which is an ErrorBoundary.
224226
225227
"""
226-
return ErrorBoundary.create(*children)
228+
return ErrorBoundary.create(
229+
*children,
230+
**props,
231+
)
227232

228233

229234
class OverlayFragment(Fragment):
@@ -345,7 +350,9 @@ class App(MiddlewareMixin, LifespanMixin):
345350
dataclasses.field(
346351
default_factory=lambda: {
347352
(55, "ErrorBoundary"): (
348-
lambda stateful: default_error_boundary() if stateful else None
353+
lambda stateful: default_error_boundary(
354+
**({"on_error": noop()} if not stateful else {})
355+
)
349356
),
350357
(5, "Overlay"): (
351358
lambda stateful: default_overlay_component() if stateful else None

tests/integration/test_call_script.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,9 @@ def assert_token(driver: WebDriver) -> str:
406406
"""
407407
ss = SessionStorage(driver)
408408
assert AppHarness._poll_for(lambda: ss.get("token") is not None), "token not found"
409+
assert AppHarness._poll_for(
410+
lambda: driver.execute_script("return typeof external4 !== 'undefined'")
411+
), "scripts not loaded"
409412
return ss.get("token")
410413

411414

tests/units/test_app.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,9 +1370,11 @@ def test_app_wrap_compile_theme(
13701370
lines = "".join(app_js_lines)
13711371
expected = (
13721372
"function AppWrap({children}) {"
1373+
"const [addEvents, connectErrors] = useContext(EventLoopContext);"
13731374
"return ("
13741375
+ ("jsx(StrictMode,{}," if react_strict_mode else "")
1375-
+ "jsx(RadixThemesColorModeProvider,{},"
1376+
+ """jsx(ErrorBoundary,{fallbackRender:((event_args) => (jsx("div", ({css:({ ["height"] : "100%", ["width"] : "100%", ["position"] : "absolute", ["display"] : "flex", ["alignItems"] : "center", ["justifyContent"] : "center" })}), (jsx("div", ({css:({ ["display"] : "flex", ["flexDirection"] : "column", ["gap"] : "1rem" })}), (jsx("div", ({css:({ ["display"] : "flex", ["flexDirection"] : "column", ["gap"] : "1rem", ["maxWidth"] : "50ch", ["border"] : "1px solid #888888", ["borderRadius"] : "0.25rem", ["padding"] : "1rem" })}), (jsx("h2", ({css:({ ["fontSize"] : "1.25rem", ["fontWeight"] : "bold" })}), (jsx(Fragment, ({}), "An error occurred while rendering this page.")))), (jsx("p", ({css:({ ["opacity"] : "0.75" })}), (jsx(Fragment, ({}), "This is an error with the application itself.")))), (jsx("details", ({}), (jsx("summary", ({css:({ ["padding"] : "0.5rem" })}), (jsx(Fragment, ({}), "Error message")))), (jsx("div", ({css:({ ["width"] : "100%", ["maxHeight"] : "50vh", ["overflow"] : "auto", ["background"] : "#000", ["color"] : "#fff", ["borderRadius"] : "0.25rem" })}), (jsx("div", ({css:({ ["padding"] : "0.5rem", ["width"] : "fit-content" })}), (jsx("pre", ({}), (jsx(Fragment, ({}), event_args.error.stack)))))))), (jsx("button", ({css:({ ["padding"] : "0.35rem 0.75rem", ["margin"] : "0.5rem", ["background"] : "#fff", ["color"] : "#000", ["border"] : "1px solid #000", ["borderRadius"] : "0.25rem", ["fontWeight"] : "bold" }),onClick:((_e) => (addEvents([(Event("_call_function", ({ ["function"] : (() => (navigator["clipboard"]["writeText"](event_args.error.stack))), ["callback"] : null }), ({ })))], [_e], ({ }))))}), (jsx(Fragment, ({}), "Copy")))))))), (jsx("hr", ({css:({ ["borderColor"] : "currentColor", ["opacity"] : "0.25" })}))), (jsx("a", ({href:"https://reflex.dev"}), (jsx("div", ({css:({ ["display"] : "flex", ["alignItems"] : "baseline", ["justifyContent"] : "center", ["fontFamily"] : "monospace", ["--default-font-family"] : "monospace", ["gap"] : "0.5rem" })}), (jsx(Fragment, ({}), "Built with ")), (jsx("svg", ({"aria-label":"Reflex",css:({ ["fill"] : "currentColor" }),height:"12",role:"img",width:"56",xmlns:"http://www.w3.org/2000/svg"}), (jsx("path", ({d:"M0 11.5999V0.399902H8.96V4.8799H6.72V2.6399H2.24V4.8799H6.72V7.1199H2.24V11.5999H0ZM6.72 11.5999V7.1199H8.96V11.5999H6.72Z"}))), (jsx("path", ({d:"M11.2 11.5999V0.399902H17.92V2.6399H13.44V4.8799H17.92V7.1199H13.44V9.3599H17.92V11.5999H11.2Z"}))), (jsx("path", ({d:"M20.16 11.5999V0.399902H26.88V2.6399H22.4V4.8799H26.88V7.1199H22.4V11.5999H20.16Z"}))), (jsx("path", ({d:"M29.12 11.5999V0.399902H31.36V9.3599H35.84V11.5999H29.12Z"}))), (jsx("path", ({d:"M38.08 11.5999V0.399902H44.8V2.6399H40.32V4.8799H44.8V7.1199H40.32V9.3599H44.8V11.5999H38.08Z"}))), (jsx("path", ({d:"M47.04 4.8799V0.399902H49.28V4.8799H47.04ZM53.76 4.8799V0.399902H56V4.8799H53.76ZM49.28 7.1199V4.8799H53.76V7.1199H49.28ZM47.04 11.5999V7.1199H49.28V11.5999H47.04ZM53.76 11.5999V7.1199H56V11.5999H53.76Z"}))), (jsx("title", ({}), (jsx(Fragment, ({}), "Reflex"))))))))))))))),onError:((_error, _info) => (addEvents([(Event("_call_function", ({ ["function"] : (() => null), ["callback"] : null }), ({ })))], [_error, _info], ({ }))))},"""
1377+
"jsx(RadixThemesColorModeProvider,{},"
13761378
"jsx(RadixThemesTheme,{accentColor:\"plum\",css:{...theme.styles.global[':root'], ...theme.styles.global.body}},"
13771379
"jsx(Fragment,{},"
13781380
"jsx(MemoizedToastProvider,{},),"
@@ -1381,6 +1383,7 @@ def test_app_wrap_compile_theme(
13811383
"),"
13821384
"),"
13831385
"),"
1386+
"),"
13841387
")" + (",)" if react_strict_mode else "") + ")"
13851388
"}"
13861389
)
@@ -1438,17 +1441,19 @@ def page():
14381441
lines = "".join(app_js_lines)
14391442
expected = (
14401443
"function AppWrap({children}) {"
1444+
"const [addEvents, connectErrors] = useContext(EventLoopContext);"
14411445
"return ("
14421446
+ ("jsx(StrictMode,{}," if react_strict_mode else "")
14431447
+ "jsx(RadixThemesBox,{},"
1448+
"""jsx(ErrorBoundary,{fallbackRender:((event_args) => (jsx("div", ({css:({ ["height"] : "100%", ["width"] : "100%", ["position"] : "absolute", ["display"] : "flex", ["alignItems"] : "center", ["justifyContent"] : "center" })}), (jsx("div", ({css:({ ["display"] : "flex", ["flexDirection"] : "column", ["gap"] : "1rem" })}), (jsx("div", ({css:({ ["display"] : "flex", ["flexDirection"] : "column", ["gap"] : "1rem", ["maxWidth"] : "50ch", ["border"] : "1px solid #888888", ["borderRadius"] : "0.25rem", ["padding"] : "1rem" })}), (jsx("h2", ({css:({ ["fontSize"] : "1.25rem", ["fontWeight"] : "bold" })}), (jsx(Fragment, ({}), "An error occurred while rendering this page.")))), (jsx("p", ({css:({ ["opacity"] : "0.75" })}), (jsx(Fragment, ({}), "This is an error with the application itself.")))), (jsx("details", ({}), (jsx("summary", ({css:({ ["padding"] : "0.5rem" })}), (jsx(Fragment, ({}), "Error message")))), (jsx("div", ({css:({ ["width"] : "100%", ["maxHeight"] : "50vh", ["overflow"] : "auto", ["background"] : "#000", ["color"] : "#fff", ["borderRadius"] : "0.25rem" })}), (jsx("div", ({css:({ ["padding"] : "0.5rem", ["width"] : "fit-content" })}), (jsx("pre", ({}), (jsx(Fragment, ({}), event_args.error.stack)))))))), (jsx("button", ({css:({ ["padding"] : "0.35rem 0.75rem", ["margin"] : "0.5rem", ["background"] : "#fff", ["color"] : "#000", ["border"] : "1px solid #000", ["borderRadius"] : "0.25rem", ["fontWeight"] : "bold" }),onClick:((_e) => (addEvents([(Event("_call_function", ({ ["function"] : (() => (navigator["clipboard"]["writeText"](event_args.error.stack))), ["callback"] : null }), ({ })))], [_e], ({ }))))}), (jsx(Fragment, ({}), "Copy")))))))), (jsx("hr", ({css:({ ["borderColor"] : "currentColor", ["opacity"] : "0.25" })}))), (jsx("a", ({href:"https://reflex.dev"}), (jsx("div", ({css:({ ["display"] : "flex", ["alignItems"] : "baseline", ["justifyContent"] : "center", ["fontFamily"] : "monospace", ["--default-font-family"] : "monospace", ["gap"] : "0.5rem" })}), (jsx(Fragment, ({}), "Built with ")), (jsx("svg", ({"aria-label":"Reflex",css:({ ["fill"] : "currentColor" }),height:"12",role:"img",width:"56",xmlns:"http://www.w3.org/2000/svg"}), (jsx("path", ({d:"M0 11.5999V0.399902H8.96V4.8799H6.72V2.6399H2.24V4.8799H6.72V7.1199H2.24V11.5999H0ZM6.72 11.5999V7.1199H8.96V11.5999H6.72Z"}))), (jsx("path", ({d:"M11.2 11.5999V0.399902H17.92V2.6399H13.44V4.8799H17.92V7.1199H13.44V9.3599H17.92V11.5999H11.2Z"}))), (jsx("path", ({d:"M20.16 11.5999V0.399902H26.88V2.6399H22.4V4.8799H26.88V7.1199H22.4V11.5999H20.16Z"}))), (jsx("path", ({d:"M29.12 11.5999V0.399902H31.36V9.3599H35.84V11.5999H29.12Z"}))), (jsx("path", ({d:"M38.08 11.5999V0.399902H44.8V2.6399H40.32V4.8799H44.8V7.1199H40.32V9.3599H44.8V11.5999H38.08Z"}))), (jsx("path", ({d:"M47.04 4.8799V0.399902H49.28V4.8799H47.04ZM53.76 4.8799V0.399902H56V4.8799H53.76ZM49.28 7.1199V4.8799H53.76V7.1199H49.28ZM47.04 11.5999V7.1199H49.28V11.5999H47.04ZM53.76 11.5999V7.1199H56V11.5999H53.76Z"}))), (jsx("title", ({}), (jsx(Fragment, ({}), "Reflex"))))))))))))))),onError:((_error, _info) => (addEvents([(Event("_call_function", ({ ["function"] : (() => null), ["callback"] : null }), ({ })))], [_error, _info], ({ }))))},"""
14441449
'jsx(RadixThemesText,{as:"p"},'
14451450
"jsx(RadixThemesColorModeProvider,{},"
14461451
"jsx(Fragment2,{},"
14471452
"jsx(Fragment,{},"
14481453
"jsx(MemoizedToastProvider,{},),"
14491454
"jsx(Fragment,{},"
14501455
"children"
1451-
",),),),),)" + (",)" if react_strict_mode else "")
1456+
",),),),),),)" + (",)" if react_strict_mode else "")
14521457
)
14531458
assert expected in lines
14541459

0 commit comments

Comments
 (0)