diff --git a/reflex/constants.py b/reflex/constants.py index 023817b32..442fcfe93 100644 --- a/reflex/constants.py +++ b/reflex/constants.py @@ -116,6 +116,18 @@ BUN_ROOT_PATH = "$HOME/.bun" BUN_PATH = get_value("BUN_PATH", f"{BUN_ROOT_PATH}/bin/bun") # Command to install bun. INSTALL_BUN = f"curl -fsSL https://bun.sh/install | bash -s -- bun-v{MAX_BUN_VERSION}" +# Command to install nvm. +INSTALL_NVM = ( + "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash" +) +# nvm root location. +NVM_ROOT_PATH = f"$HOME/.nvm" +# The default path where node is installed. +NODE_PATH = get_value( + "NODE_PATH", f"{NVM_ROOT_PATH}/versions/node/v{MIN_NODE_VERSION}/bin/node" +) +# Command to install node. +INSTALL_NODE = f". {NVM_ROOT_PATH}/nvm.sh && nvm install {MIN_NODE_VERSION}" # Default host in dev mode. BACKEND_HOST = get_value("BACKEND_HOST", "0.0.0.0") # The default timeout when launching the gunicorn server. diff --git a/reflex/reflex.py b/reflex/reflex.py index 3aa47b0ac..140945be5 100644 --- a/reflex/reflex.py +++ b/reflex/reflex.py @@ -44,6 +44,7 @@ def init( console.rule(f"[bold]Initializing {app_name}") # Set up the web directory. prerequisites.validate_and_install_bun() + prerequisites.validate_and_install_node() prerequisites.initialize_web_directory() # Migrate Pynecone projects to Reflex. diff --git a/reflex/utils/prerequisites.py b/reflex/utils/prerequisites.py index 0751c4734..f8c427221 100644 --- a/reflex/utils/prerequisites.py +++ b/reflex/utils/prerequisites.py @@ -73,18 +73,9 @@ def get_package_manager() -> str: Raises: FileNotFoundError: If bun or npm is not installed. - Exit: If the app directory is invalid. - """ config = get_config() - # Check that the node version is valid. - if not check_node_version(): - console.print( - f"[red]Node.js version {constants.MIN_NODE_VERSION} or higher is required to run Reflex." - ) - raise typer.Exit() - # On Windows, we use npm instead of bun. if platform.system() == "Windows" or config.disable_bun: npm_path = path_ops.which("npm") @@ -276,6 +267,47 @@ def remove_existing_bun_installation(): path_ops.rm(os.path.expandvars(constants.BUN_ROOT_PATH)) +def validate_and_install_node(): + """Validate nodejs have install or not.""" + if not check_node_version(): + install_node() + + +def install_node(): + """Install nvm and nodejs onto the user's system. + + + Raises: + FileNotFoundError: if unzip or curl packages are not found. + Exit: if installation failed + """ + if platform.system() != "Windows": + # Only install if bun is not already installed. + console.log("Installing nvm...") + + # Check if curl is installed + curl_path = path_ops.which("curl") + if curl_path is None: + raise FileNotFoundError("Reflex requires curl to be installed.") + + result = subprocess.run(constants.INSTALL_NVM, shell=True) + + if result.returncode != 0: + raise typer.Exit(code=result.returncode) + + console.log("Installing node...") + result = subprocess.run(constants.INSTALL_NODE, shell=True) + + if result.returncode != 0: + raise typer.Exit(code=result.returncode) + + else: + console.print( + f"[red]Node.js version {constants.MIN_NODE_VERSION} or higher is required to run Reflex." + ) + raise typer.Exit() + + def install_bun(): """Install bun onto the user's system.