Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion reflex/constants/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,20 @@ class Commands(SimpleNamespace):

DEV = "react-router dev --host"
EXPORT = "react-router build"
PROD = "sirv ./build/client --single 404.html --host"

@staticmethod
def get_prod_command(frontend_path: str = "") -> str:
"""Get the prod command with the correct 404.html path for the given frontend_path.

Args:
frontend_path: The frontend path prefix (e.g. "/app").

Returns:
The sirv command with the correct --single fallback path.
"""
stripped = frontend_path.strip("/")
fallback = f"{stripped}/404.html" if stripped else "404.html"
return f"sirv ./build/client --single {fallback} --host"

PATH = "package.json"

Expand Down
5 changes: 4 additions & 1 deletion reflex/utils/frontend_skeleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,14 @@ def _update_react_router_config(config: Config, prerender_routes: bool = False):


def _compile_package_json():
config = get_config()
return templates.package_json_template(
scripts={
"dev": constants.PackageJson.Commands.DEV,
"export": constants.PackageJson.Commands.EXPORT,
"prod": constants.PackageJson.Commands.PROD,
"prod": constants.PackageJson.Commands.get_prod_command(
config.frontend_path
),
},
dependencies=constants.PackageJson.DEPENDENCIES,
dev_dependencies=constants.PackageJson.DEV_DEPENDENCIES,
Expand Down
43 changes: 43 additions & 0 deletions tests/units/test_prerequisites.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
from click.testing import CliRunner

from reflex.config import Config
from reflex.constants.installer import PackageJson
from reflex.reflex import cli
from reflex.testing import chdir
from reflex.utils.decorator import cached_procedure
from reflex.utils.frontend_skeleton import (
_compile_package_json,
_compile_vite_config,
_update_react_router_config,
)
Expand Down Expand Up @@ -90,6 +92,47 @@ def test_initialise_vite_config(config, expected_output):
assert expected_output in output


@pytest.mark.parametrize(
("frontend_path", "expected_command"),
[
("", "sirv ./build/client --single 404.html --host"),
("/", "sirv ./build/client --single 404.html --host"),
("/app", "sirv ./build/client --single app/404.html --host"),
("/app/", "sirv ./build/client --single app/404.html --host"),
("app", "sirv ./build/client --single app/404.html --host"),
(
"/deep/nested/path",
"sirv ./build/client --single deep/nested/path/404.html --host",
),
],
)
def test_get_prod_command(frontend_path, expected_command):
assert PackageJson.Commands.get_prod_command(frontend_path) == expected_command


@pytest.mark.parametrize(
("config", "expected_prod_script"),
[
(
Config(app_name="test"),
"sirv ./build/client --single 404.html --host",
),
(
Config(app_name="test", frontend_path="/app"),
"sirv ./build/client --single app/404.html --host",
),
(
Config(app_name="test", frontend_path="/deep/nested"),
"sirv ./build/client --single deep/nested/404.html --host",
),
],
)
def test_compile_package_json_prod_command(config, expected_prod_script, monkeypatch):
monkeypatch.setattr("reflex.utils.frontend_skeleton.get_config", lambda: config)
output = _compile_package_json()
assert f'"prod": "{expected_prod_script}"' in output


def test_cached_procedure():
call_count = 0

Expand Down
Loading