Issues 1633 Add frontend_path to config to support running multiple reflex apps off the same domain, and 1583 Show the correct info on where the site is being served. (#1724)

* Support setting Next.js basePath in Reflex config. (#1633)

- Tests.
- And sorted config in next.config.js template.

* Display the correct running at url with basePath if it is set. (#1583)

* Formatting, fixed by black.

* Fix indenting in test data.

* Fixed that conflict resolution shouldnt have included console.debug line.

* Rmove use of :=. Add http:// to url. Use urljoin to build url.
This commit is contained in:
Nev Delap 2023-09-02 23:38:22 +10:00 committed by GitHub
parent f9fad58769
commit 41e97bbc46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 144 additions and 14 deletions

View File

@ -1,5 +1,6 @@
module.exports = { module.exports = {
reactStrictMode: true, basePath: "",
compress: true, compress: true,
reactStrictMode: true,
trailingSlash: true, trailingSlash: true,
}; };

View File

@ -138,6 +138,9 @@ class Config(Base):
# The port to run the frontend on. # The port to run the frontend on.
frontend_port: int = 3000 frontend_port: int = 3000
# The path to run the frontend on.
frontend_path: str = ""
# The port to run the backend on. # The port to run the backend on.
backend_port: int = 8000 backend_port: int = 8000

View File

@ -6,8 +6,10 @@ import hashlib
import json import json
import os import os
import platform import platform
import re
import sys import sys
from pathlib import Path from pathlib import Path
from urllib.parse import urljoin
import psutil import psutil
import uvicorn import uvicorn
@ -83,13 +85,15 @@ def run_process_and_launch_url(run_command: list[str]):
) )
if process.stdout: if process.stdout:
for line in processes.stream_logs("Starting frontend", process): for line in processes.stream_logs("Starting frontend", process):
if "ready started server on" in line: match = re.search("ready started server on ([0-9.:]+)", line)
if match:
if first_run: if first_run:
url = line.split("url: ")[-1].strip() url = f"http://{match.group(1)}"
if get_config().frontend_path != "":
url = urljoin(url, get_config().frontend_path)
console.print(f"App running at: [bold green]{url}") console.print(f"App running at: [bold green]{url}")
first_run = False
else: else:
console.print(f"New packages detected updating app...") console.print("New packages detected updating app...")
else: else:
console.debug(line) console.debug(line)
new_hash = detect_package_change(json_file_path) new_hash = detect_package_change(json_file_path)

View File

@ -23,7 +23,7 @@ from packaging import version
from redis import Redis from redis import Redis
from reflex import constants, model from reflex import constants, model
from reflex.config import get_config from reflex.config import Config, get_config
from reflex.utils import console, path_ops, processes from reflex.utils import console, path_ops, processes
@ -216,16 +216,11 @@ def initialize_web_directory():
next_config_file = os.path.join(constants.WEB_DIR, constants.NEXT_CONFIG_FILE) next_config_file = os.path.join(constants.WEB_DIR, constants.NEXT_CONFIG_FILE)
with open(next_config_file, "r") as file: with open(next_config_file, "r") as file:
lines = file.readlines() next_config = file.read()
for i, line in enumerate(lines): next_config = update_next_config(next_config, get_config())
if "compress:" in line:
new_line = line.replace(
"true", "true" if get_config().next_compression else "false"
)
lines[i] = new_line
with open(next_config_file, "w") as file: with open(next_config_file, "w") as file:
file.writelines(lines) file.write(next_config)
# Initialize the reflex json file. # Initialize the reflex json file.
init_reflex_json() init_reflex_json()
@ -245,6 +240,29 @@ def init_reflex_json():
path_ops.update_json_file(constants.REFLEX_JSON, reflex_json) path_ops.update_json_file(constants.REFLEX_JSON, reflex_json)
def update_next_config(next_config: str, config: Config) -> str:
"""Update Next.js config from Reflex config. Is its own function for testing.
Args:
next_config: Content of next.config.js.
config: A reflex Config object.
Returns:
The next_config updated from config.
"""
next_config = re.sub(
"compress: (true|false)",
f'compress: {"true" if config.next_compression else "false"}',
next_config,
)
next_config = re.sub(
'basePath: ".*?"',
f'basePath: "{config.frontend_path or ""}"',
next_config,
)
return next_config
def remove_existing_bun_installation(): def remove_existing_bun_installation():
"""Remove existing bun installation.""" """Remove existing bun installation."""
console.debug("Removing existing bun installation.") console.debug("Removing existing bun installation.")

View File

@ -47,6 +47,7 @@ def test_deprecated_params(base_config_values, param):
[ [
("APP_NAME", "my_test_app"), ("APP_NAME", "my_test_app"),
("FRONTEND_PORT", 3001), ("FRONTEND_PORT", 3001),
("FRONTEND_PATH", "/test"),
("BACKEND_PORT", 8001), ("BACKEND_PORT", 8001),
("API_URL", "https://mybackend.com:8000"), ("API_URL", "https://mybackend.com:8000"),
("DEPLOY_URL", "https://myfrontend.com"), ("DEPLOY_URL", "https://myfrontend.com"),

103
tests/test_prerequites.py Normal file
View File

@ -0,0 +1,103 @@
import pytest
from reflex.config import Config
from reflex.utils.prerequisites import update_next_config
@pytest.mark.parametrize(
"template_next_config, reflex_config, expected_next_config",
[
(
"""
module.exports = {
basePath: "",
compress: true,
reactStrictMode: true,
trailingSlash: true,
};
""",
Config(
app_name="test",
),
"""
module.exports = {
basePath: "",
compress: true,
reactStrictMode: true,
trailingSlash: true,
};
""",
),
(
"""
module.exports = {
basePath: "",
compress: true,
reactStrictMode: true,
trailingSlash: true,
};
""",
Config(
app_name="test",
next_compression=False,
),
"""
module.exports = {
basePath: "",
compress: false,
reactStrictMode: true,
trailingSlash: true,
};
""",
),
(
"""
module.exports = {
basePath: "",
compress: true,
reactStrictMode: true,
trailingSlash: true,
};
""",
Config(
app_name="test",
frontend_path="/test",
),
"""
module.exports = {
basePath: "/test",
compress: true,
reactStrictMode: true,
trailingSlash: true,
};
""",
),
(
"""
module.exports = {
basePath: "",
compress: true,
reactStrictMode: true,
trailingSlash: true,
};
""",
Config(
app_name="test",
frontend_path="/test",
next_compression=False,
),
"""
module.exports = {
basePath: "/test",
compress: false,
reactStrictMode: true,
trailingSlash: true,
};
""",
),
],
)
def test_update_next_config(template_next_config, reflex_config, expected_next_config):
assert (
update_next_config(template_next_config, reflex_config) == expected_next_config
)