diff --git a/reflex/.templates/jinja/web/pages/_app.js.jinja2 b/reflex/.templates/jinja/web/pages/_app.js.jinja2 index 97c31925d..c893e19e2 100644 --- a/reflex/.templates/jinja/web/pages/_app.js.jinja2 +++ b/reflex/.templates/jinja/web/pages/_app.js.jinja2 @@ -7,10 +7,9 @@ import '/styles/styles.css' {% block declaration %} import { EventLoopProvider, StateProvider, defaultColorMode } from "/utils/context.js"; import { ThemeProvider } from 'next-themes' -import * as React from "react"; -import * as utils_context from "/utils/context.js"; -import * as utils_state from "/utils/state.js"; -import * as radix from "@radix-ui/themes"; +{% for library_alias, library_path in window_libraries %} +import * as {{library_alias}} from "{{library_path}}"; +{% endfor %} {% for custom_code in custom_codes %} {{custom_code}} @@ -33,10 +32,9 @@ export default function MyApp({ Component, pageProps }) { React.useEffect(() => { // Make contexts and state objects available globally for dynamic eval'd components let windowImports = { - "react": React, - "@radix-ui/themes": radix, - "/utils/context": utils_context, - "/utils/state": utils_state, +{% for library_alias, library_path in window_libraries %} + "{{library_path}}": {{library_alias}}, +{% endfor %} }; window["__reflex"] = windowImports; }, []); diff --git a/reflex/compiler/compiler.py b/reflex/compiler/compiler.py index edf03039e..a1597bfed 100644 --- a/reflex/compiler/compiler.py +++ b/reflex/compiler/compiler.py @@ -4,6 +4,7 @@ from __future__ import annotations import os from datetime import datetime +from importlib.util import find_spec from pathlib import Path from typing import Dict, Iterable, Optional, Type, Union @@ -49,10 +50,25 @@ def _compile_app(app_root: Component) -> str: Returns: The compiled app. """ + chakra_available = find_spec("reflex_chakra") is not None + return templates.APP_ROOT.render( imports=utils.compile_imports(app_root._get_all_imports()), custom_codes=app_root._get_all_custom_code(), hooks={**app_root._get_all_hooks_internal(), **app_root._get_all_hooks()}, + window_libraries=[ + ("React", "react"), + ("utils_context", f"/{constants.Dirs.UTILS}/context.js"), + ("utils_state", f"/{constants.Dirs.UTILS}/state.js"), + ("radix", "@radix-ui/themes"), + ] + + ( + [ + ("chakra", "@chakra-ui/react"), + ] + if chakra_available + else [] + ), render=app_root.render(), ) diff --git a/reflex/components/dynamic.py b/reflex/components/dynamic.py index 390b6e688..da5bf1460 100644 --- a/reflex/components/dynamic.py +++ b/reflex/components/dynamic.py @@ -1,5 +1,7 @@ """Components that are dynamically generated on the backend.""" +from importlib.util import find_spec + from reflex import constants from reflex.utils import imports from reflex.utils.format import format_library_name @@ -58,10 +60,13 @@ def load_dynamic_serializer(): ) ] = None + chakra_available = find_spec("reflex_chakra") is not None + libs_in_window = [ "react", "@radix-ui/themes", - ] + "@chakra-ui/react", + ] + (["@chakra-ui/react"] if chakra_available else []) imports = {} for lib, names in component._get_all_imports().items(): @@ -69,10 +74,7 @@ def load_dynamic_serializer(): if ( not lib.startswith((".", "/")) and not lib.startswith("http") - and all( - formatted_lib_name != lib_in_window - for lib_in_window in libs_in_window - ) + and formatted_lib_name not in libs_in_window ): imports[get_cdn_url(lib)] = names else: