From 51364922992a9d3cbfbcd6f74335c230b9053fa5 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Thu, 28 Aug 2025 14:26:26 -0700 Subject: [PATCH 1/4] add option to disable hmr --- reflex/compiler/templates.py | 4 +++- reflex/environment.py | 3 +++ reflex/utils/frontend_skeleton.py | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/reflex/compiler/templates.py b/reflex/compiler/templates.py index ba286a8decc..131158ec9ad 100644 --- a/reflex/compiler/templates.py +++ b/reflex/compiler/templates.py @@ -502,11 +502,12 @@ def package_json_template( ) -def vite_config_template(base: str): +def vite_config_template(base: str, hmr: bool): """Template for vite.config.js. Args: base: The base path for the Vite config. + hmr: Whether to enable hot module replacement. Returns: Rendered vite.config.js content as string. @@ -559,6 +560,7 @@ def vite_config_template(base: str): }}, }}, }}, + hmr: {"true" if hmr else "false"}, experimental: {{ enableNativePlugin: false, }}, diff --git a/reflex/environment.py b/reflex/environment.py index 5e5eb5ff873..eb8bb8f01c7 100644 --- a/reflex/environment.py +++ b/reflex/environment.py @@ -640,6 +640,9 @@ class EnvironmentVariables: # Enable full logging of debug messages to reflex user directory. REFLEX_ENABLE_FULL_LOGGING: EnvVar[bool] = env_var(False) + # Whether to enable hot module replacement. + VITE_HMR: EnvVar[bool] = env_var(True) + environment = EnvironmentVariables() diff --git a/reflex/utils/frontend_skeleton.py b/reflex/utils/frontend_skeleton.py index a6317ddad68..5ef1c9b4cb1 100644 --- a/reflex/utils/frontend_skeleton.py +++ b/reflex/utils/frontend_skeleton.py @@ -10,6 +10,7 @@ from reflex import constants from reflex.compiler import templates from reflex.config import Config, get_config +from reflex.environment import environment from reflex.utils import console, path_ops from reflex.utils.prerequisites import get_project_hash, get_web_dir from reflex.utils.registry import get_npm_registry @@ -192,7 +193,7 @@ def _compile_vite_config(config: Config): base = "/" if frontend_path := config.frontend_path.strip("/"): base += frontend_path + "/" - return templates.vite_config_template(base=base) + return templates.vite_config_template(base=base, hmr=environment.VITE_HMR.get()) def initialize_vite_config(): From afbcdb658f603d042815578699a55051e3554a9f Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Thu, 28 Aug 2025 14:53:16 -0700 Subject: [PATCH 2/4] make it a fullreload if hmr is enabled --- reflex/compiler/templates.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/reflex/compiler/templates.py b/reflex/compiler/templates.py index 131158ec9ad..edfe435e69b 100644 --- a/reflex/compiler/templates.py +++ b/reflex/compiler/templates.py @@ -538,12 +538,25 @@ def vite_config_template(base: str, hmr: bool): }}; }} +function fullReload() {{ + return {{ + name: "full-reload", + enforce: "pre", + handleHotUpdate({{ server }}) {{ + server.ws.send({{ + type: "full-reload", + }}); + return []; + }} + }}; +}} + export default defineConfig((config) => ({{ plugins: [ alwaysUseReactDomServerNode(), reactRouter(), safariCacheBustPlugin(), - ], + ] + {"[fullReload()]" if not hmr else "[]"}, build: {{ assetsDir: "{base}assets".slice(1), rollupOptions: {{ @@ -560,7 +573,6 @@ def vite_config_template(base: str, hmr: bool): }}, }}, }}, - hmr: {"true" if hmr else "false"}, experimental: {{ enableNativePlugin: false, }}, From b9d9bf7cd37d9bde8f7fb758c246ff6bb6493a75 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Thu, 28 Aug 2025 15:02:55 -0700 Subject: [PATCH 3/4] woops --- reflex/compiler/templates.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reflex/compiler/templates.py b/reflex/compiler/templates.py index edfe435e69b..1ef74a89457 100644 --- a/reflex/compiler/templates.py +++ b/reflex/compiler/templates.py @@ -556,7 +556,7 @@ def vite_config_template(base: str, hmr: bool): alwaysUseReactDomServerNode(), reactRouter(), safariCacheBustPlugin(), - ] + {"[fullReload()]" if not hmr else "[]"}, + ].concat({"[fullReload()]" if not hmr else "[]"}), build: {{ assetsDir: "{base}assets".slice(1), rollupOptions: {{ From 5cf2517deac7dff60b130d6f6cca424d451d1ba2 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Thu, 28 Aug 2025 15:25:02 -0700 Subject: [PATCH 4/4] add both options --- reflex/compiler/templates.py | 6 ++++-- reflex/environment.py | 5 ++++- reflex/utils/frontend_skeleton.py | 6 +++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/reflex/compiler/templates.py b/reflex/compiler/templates.py index 1ef74a89457..0f28cc401ea 100644 --- a/reflex/compiler/templates.py +++ b/reflex/compiler/templates.py @@ -502,12 +502,13 @@ def package_json_template( ) -def vite_config_template(base: str, hmr: bool): +def vite_config_template(base: str, hmr: bool, force_full_reload: bool): """Template for vite.config.js. Args: base: The base path for the Vite config. hmr: Whether to enable hot module replacement. + force_full_reload: Whether to force a full reload on changes. Returns: Rendered vite.config.js content as string. @@ -556,7 +557,7 @@ def vite_config_template(base: str, hmr: bool): alwaysUseReactDomServerNode(), reactRouter(), safariCacheBustPlugin(), - ].concat({"[fullReload()]" if not hmr else "[]"}), + ].concat({"[fullReload()]" if force_full_reload else "[]"}), build: {{ assetsDir: "{base}assets".slice(1), rollupOptions: {{ @@ -578,6 +579,7 @@ def vite_config_template(base: str, hmr: bool): }}, server: {{ port: process.env.PORT, + hmr: {"true" if hmr else "false"}, watch: {{ ignored: [ "**/.web/backend/**", diff --git a/reflex/environment.py b/reflex/environment.py index eb8bb8f01c7..30ff71880d1 100644 --- a/reflex/environment.py +++ b/reflex/environment.py @@ -640,9 +640,12 @@ class EnvironmentVariables: # Enable full logging of debug messages to reflex user directory. REFLEX_ENABLE_FULL_LOGGING: EnvVar[bool] = env_var(False) - # Whether to enable hot module replacement. + # Whether to enable hot module replacement VITE_HMR: EnvVar[bool] = env_var(True) + # Whether to force a full reload on changes. + VITE_FORCE_FULL_RELOAD: EnvVar[bool] = env_var(False) + environment = EnvironmentVariables() diff --git a/reflex/utils/frontend_skeleton.py b/reflex/utils/frontend_skeleton.py index 5ef1c9b4cb1..2b704c9bb24 100644 --- a/reflex/utils/frontend_skeleton.py +++ b/reflex/utils/frontend_skeleton.py @@ -193,7 +193,11 @@ def _compile_vite_config(config: Config): base = "/" if frontend_path := config.frontend_path.strip("/"): base += frontend_path + "/" - return templates.vite_config_template(base=base, hmr=environment.VITE_HMR.get()) + return templates.vite_config_template( + base=base, + hmr=environment.VITE_HMR.get(), + force_full_reload=environment.VITE_FORCE_FULL_RELOAD.get(), + ) def initialize_vite_config():