Browse Source

add option to disable Tailwind (#1842)

Elijah Ahianyo 1 year ago
parent
commit
d81d544b97

+ 1 - 2
reflex/.templates/web/package.json

@@ -24,7 +24,6 @@
   },
   },
   "devDependencies": {
   "devDependencies": {
     "autoprefixer": "^10.4.14",
     "autoprefixer": "^10.4.14",
-    "postcss": "^8.4.24",
-    "tailwindcss": "^3.3.2"
+    "postcss": "^8.4.24"
   }
   }
 }
 }

+ 7 - 1
reflex/compiler/compiler.py

@@ -8,6 +8,7 @@ from typing import List, Set, Tuple, Type
 from reflex import constants
 from reflex import constants
 from reflex.compiler import templates, utils
 from reflex.compiler import templates, utils
 from reflex.components.component import Component, ComponentStyle, CustomComponent
 from reflex.components.component import Component, ComponentStyle, CustomComponent
+from reflex.config import get_config
 from reflex.state import State
 from reflex.state import State
 from reflex.utils import imports
 from reflex.utils import imports
 from reflex.vars import ImportVar
 from reflex.vars import ImportVar
@@ -148,7 +149,12 @@ def _compile_root_stylesheet(stylesheets: List[str]) -> str:
     Raises:
     Raises:
         FileNotFoundError: If a specified stylesheet in assets directory does not exist.
         FileNotFoundError: If a specified stylesheet in assets directory does not exist.
     """
     """
-    sheets = [constants.TAILWIND_ROOT_STYLE_PATH]
+    # Add tailwind css if enabled.
+    sheets = (
+        [constants.TAILWIND_ROOT_STYLE_PATH]
+        if get_config().tailwind is not None
+        else []
+    )
     for stylesheet in stylesheets:
     for stylesheet in stylesheets:
         if not utils.is_valid_url(stylesheet):
         if not utils.is_valid_url(stylesheet):
             # check if stylesheet provided exists.
             # check if stylesheet provided exists.

+ 1 - 1
reflex/config.py

@@ -169,7 +169,7 @@ class Config(Base):
     cors_allowed_origins: List[str] = ["*"]
     cors_allowed_origins: List[str] = ["*"]
 
 
     # Tailwind config.
     # Tailwind config.
-    tailwind: Optional[Dict[str, Any]] = None
+    tailwind: Optional[Dict[str, Any]] = {}
 
 
     # Timeout when launching the gunicorn server. TODO(rename this to backend_timeout?)
     # Timeout when launching the gunicorn server. TODO(rename this to backend_timeout?)
     timeout: int = 120
     timeout: int = 120

+ 2 - 0
reflex/constants.py

@@ -134,6 +134,8 @@ TAILWIND_CONFIG = os.path.join(WEB_DIR, "tailwind.config.js")
 TAILWIND_CONTENT = ["./pages/**/*.{js,ts,jsx,tsx}"]
 TAILWIND_CONTENT = ["./pages/**/*.{js,ts,jsx,tsx}"]
 # Relative tailwind style path to root stylesheet in STYLES_DIR.
 # Relative tailwind style path to root stylesheet in STYLES_DIR.
 TAILWIND_ROOT_STYLE_PATH = "./tailwind.css"
 TAILWIND_ROOT_STYLE_PATH = "./tailwind.css"
+# The Tailwindcss version
+TAILWIND_VERSION = "tailwindcss@^3.3.2"
 # The NextJS config file
 # The NextJS config file
 NEXT_CONFIG_FILE = "next.config.js"
 NEXT_CONFIG_FILE = "next.config.js"
 # The sitemap config file.
 # The sitemap config file.

+ 10 - 3
reflex/utils/prerequisites.py

@@ -432,13 +432,20 @@ def install_frontend_packages(packages: set[str]):
     processes.show_status("Installing base frontend packages", process)
     processes.show_status("Installing base frontend packages", process)
 
 
     config = get_config()
     config = get_config()
-    if config.tailwind is not None and "plugins" in config.tailwind:
+    if config.tailwind is not None:
+        # install tailwind and tailwind plugins as dev dependencies.
         process = processes.new_process(
         process = processes.new_process(
-            [get_install_package_manager(), "add", *config.tailwind["plugins"]],
+            [
+                get_install_package_manager(),
+                "add",
+                "-d",
+                constants.TAILWIND_VERSION,
+                *((config.tailwind or {}).get("plugins", [])),
+            ],
             cwd=constants.WEB_DIR,
             cwd=constants.WEB_DIR,
             shell=constants.IS_WINDOWS,
             shell=constants.IS_WINDOWS,
         )
         )
-        processes.show_status("Installing tailwind packages", process)
+        processes.show_status("Installing tailwind", process)
 
 
     # Install custom packages defined in frontend_packages
     # Install custom packages defined in frontend_packages
     if len(packages) > 0:
     if len(packages) > 0:

+ 30 - 1
tests/compiler/test_compiler.py

@@ -121,7 +121,6 @@ def test_compile_stylesheets(tmp_path, mocker):
     assets_dir.mkdir()
     assets_dir.mkdir()
 
 
     (assets_dir / "styles.css").touch()
     (assets_dir / "styles.css").touch()
-
     mocker.patch("reflex.compiler.compiler.Path.cwd", return_value=project)
     mocker.patch("reflex.compiler.compiler.Path.cwd", return_value=project)
 
 
     stylesheets = [
     stylesheets = [
@@ -141,6 +140,36 @@ def test_compile_stylesheets(tmp_path, mocker):
     )
     )
 
 
 
 
+def test_compile_stylesheets_exclude_tailwind(tmp_path, mocker):
+    """Test that Tailwind is excluded if tailwind config is explicitly set to None.
+
+    Args:
+        tmp_path: The test directory.
+        mocker: Pytest mocker object.
+    """
+    project = tmp_path / "test_project"
+    project.mkdir()
+
+    assets_dir = project / "assets"
+    assets_dir.mkdir()
+    mock = mocker.Mock()
+
+    mocker.patch.object(mock, "tailwind", None)
+    mocker.patch("reflex.compiler.compiler.get_config", return_value=mock)
+
+    (assets_dir / "styles.css").touch()
+    mocker.patch("reflex.compiler.compiler.Path.cwd", return_value=project)
+
+    stylesheets = [
+        "/styles.css",
+    ]
+
+    assert compiler.compile_root_stylesheet(stylesheets) == (
+        os.path.join(".web", "styles", "styles.css"),
+        "@import url('@/styles.css'); \n",
+    )
+
+
 def test_compile_nonexistent_stylesheet(tmp_path, mocker):
 def test_compile_nonexistent_stylesheet(tmp_path, mocker):
     """Test that an error is thrown for non-existent stylesheets.
     """Test that an error is thrown for non-existent stylesheets.