瀏覽代碼

allow for non-installable imports (#1843)

Thomas Brandého 1 年之前
父節點
當前提交
15ced6b795
共有 5 個文件被更改,包括 33 次插入16 次删除
  1. 4 2
      reflex/app.py
  2. 6 5
      reflex/compiler/utils.py
  3. 12 8
      reflex/components/component.py
  4. 9 1
      reflex/vars.py
  5. 2 0
      reflex/vars.pyi

+ 4 - 2
reflex/app.py

@@ -51,6 +51,7 @@ from reflex.route import (
 )
 from reflex.state import DefaultState, State, StateManager, StateUpdate
 from reflex.utils import console, format, prerequisites, types
+from reflex.vars import ImportVar
 
 # Define custom types.
 ComponentCallable = Callable[[], Component]
@@ -508,7 +509,7 @@ class App(Base):
 
             admin.mount_to(self.api)
 
-    def get_frontend_packages(self, imports: Dict[str, str]):
+    def get_frontend_packages(self, imports: Dict[str, set[ImportVar]]):
         """Gets the frontend packages to be installed and filters out the unnecessary ones.
 
         Args:
@@ -519,13 +520,14 @@ class App(Base):
         """
         page_imports = {
             i
-            for i in imports
+            for i, tags in imports.items()
             if i not in compiler.DEFAULT_IMPORTS.keys()
             and i != "focus-visible/dist/focus-visible"
             and "next" not in i
             and not i.startswith("/")
             and not i.startswith(".")
             and i != ""
+            and any(tag.install for tag in tags)
         }
         frontend_packages = get_config().frontend_packages
         _frontend_packages = []

+ 6 - 5
reflex/compiler/utils.py

@@ -25,7 +25,7 @@ from reflex.components.component import Component, ComponentStyle, CustomCompone
 from reflex.state import Cookie, LocalStorage, State
 from reflex.style import Style
 from reflex.utils import format, imports, path_ops
-from reflex.vars import ImportVar, NoRenderImportVar
+from reflex.vars import ImportVar
 
 # To re-export this function.
 merge_imports = imports.merge_imports
@@ -42,8 +42,8 @@ def compile_import_statement(fields: Set[ImportVar]) -> Tuple[str, Set[str]]:
         default: default library. When install "import def from library".
         rest: rest of libraries. When install "import {rest1, rest2} from library"
     """
-    # ignore the NoRenderImportVar fields during compilation
-    fields = {field for field in fields if not isinstance(field, NoRenderImportVar)}
+    # ignore the ImportVar fields with render=False during compilation
+    fields = {field for field in fields if field.render}
 
     # Check for default imports.
     defaults = {field for field in fields if field.is_default}
@@ -91,8 +91,9 @@ def compile_imports(imports: imports.ImportDict) -> List[dict]:
     import_dicts = []
     for lib, fields in imports.items():
         default, rest = compile_import_statement(fields)
-        # prevent lib from being rendered on the page if all imports are NoRenderImportVar
-        if all({isinstance(f, NoRenderImportVar) for f in fields}):  # type: ignore
+
+        # prevent lib from being rendered on the page if all imports are non rendered kind
+        if all({not f.render for f in fields}):  # type: ignore
             continue
 
         if not lib:

+ 12 - 8
reflex/components/component.py

@@ -22,7 +22,7 @@ from reflex.event import (
 )
 from reflex.style import Style
 from reflex.utils import format, imports, types
-from reflex.vars import BaseVar, ImportVar, NoRenderImportVar, Var
+from reflex.vars import BaseVar, ImportVar, Var
 
 
 class Component(Base, ABC):
@@ -546,13 +546,16 @@ class Component(Base, ABC):
         # Return the dynamic imports
         return dynamic_imports
 
+    def _get_dependencies_imports(self):
+        return {
+            dep: {ImportVar(tag=None, render=False)} for dep in self.lib_dependencies
+        }
+
     def _get_imports(self) -> imports.ImportDict:
         imports = {}
         if self.library is not None and self.tag is not None:
             imports[self.library] = {self.import_var}
-        for dep in self.lib_dependencies:
-            imports[dep] = {NoRenderImportVar()}  # type: ignore
-        return imports
+        return {**imports, **self._get_dependencies_imports()}
 
     def get_imports(self) -> imports.ImportDict:
         """Get all the libraries and fields that are used by the component.
@@ -870,10 +873,11 @@ class NoSSRComponent(Component):
     def _get_imports(self):
         imports = {"next/dynamic": {ImportVar(tag="dynamic", is_default=True)}}
 
-        for dep in [self.library, *self.lib_dependencies]:
-            imports[dep] = {NoRenderImportVar()}  # type: ignore
-
-        return imports
+        return {
+            **imports,
+            self.library: {ImportVar(tag=None, render=False)},
+            **self._get_dependencies_imports(),
+        }
 
     def _get_dynamic_imports(self) -> str:
         opts_fragment = ", { ssr: false });"

+ 9 - 1
reflex/vars.py

@@ -1332,6 +1332,12 @@ class ImportVar(Base):
     # The tag alias.
     alias: Optional[str] = None
 
+    # Whether this import need to install the associated lib
+    install: Optional[bool] = True
+
+    # whether this import should be rendered or not
+    render: Optional[bool] = True
+
     @property
     def name(self) -> str:
         """The name of the import.
@@ -1347,12 +1353,14 @@ class ImportVar(Base):
         Returns:
             The hash of the var.
         """
-        return hash((self.tag, self.is_default, self.alias))
+        return hash((self.tag, self.is_default, self.alias, self.install, self.render))
 
 
 class NoRenderImportVar(ImportVar):
     """A import that doesn't need to be rendered."""
 
+    render: Optional[bool] = False
+
 
 def get_local_storage(key: Var | str | None = None) -> BaseVar:
     """Provide a base var as payload to get local storage item(s).

+ 2 - 0
reflex/vars.pyi

@@ -120,6 +120,8 @@ class ImportVar(Base):
     tag: Optional[str]
     is_default: Optional[bool] = False
     alias: Optional[str] = None
+    install: Optional[bool] = True
+    render: Optional[bool] = True
     @property
     def name(self) -> str: ...
     def __hash__(self) -> int: ...