diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 12587e02e2..e37fe11b1e 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -36,7 +36,6 @@ jobs: matrix: # Show OS combos first in GUI os: [ubuntu-latest, windows-latest, macos-latest] - node-version: ['16.x'] python-version: ['3.8.18', '3.9.18', '3.10.13', '3.11.5', '3.12.0'] exclude: - os: windows-latest @@ -56,10 +55,6 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - uses: ./.github/actions/setup_build_env with: python-version: ${{ matrix.python-version }} @@ -104,17 +99,12 @@ jobs: # Show OS combos first in GUI os: [ubuntu-latest, windows-latest, macos-latest] python-version: ['3.10.10', '3.11.4'] - node-version: ['16.x'] env: REFLEX_WEB_WINDOWS_OVERRIDE: '1' runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - uses: ./.github/actions/setup_build_env with: python-version: ${{ matrix.python-version }} diff --git a/reflex/constants/installer.py b/reflex/constants/installer.py index 5de0d013d9..0bac7f5ada 100644 --- a/reflex/constants/installer.py +++ b/reflex/constants/installer.py @@ -71,7 +71,7 @@ class Node(SimpleNamespace): # The Node version. VERSION = "18.17.0" # The minimum required node version. - MIN_VERSION = "16.8.0" + MIN_VERSION = "18.17.0" # The node bin path. BIN_PATH = os.path.join( diff --git a/reflex/utils/prerequisites.py b/reflex/utils/prerequisites.py index 5808726a94..860a3cba04 100644 --- a/reflex/utils/prerequisites.py +++ b/reflex/utils/prerequisites.py @@ -34,6 +34,8 @@ from reflex.config import Config, get_config from reflex.utils import console, path_ops, processes +CURRENTLY_INSTALLING_NODE = False + def check_latest_package_version(package_name: str): """Check if the latest version of the package is installed. @@ -103,8 +105,11 @@ def get_node_version() -> version.Version | None: Returns: The version of node. """ + node_path = path_ops.get_node_path() + if node_path is None: + return None try: - result = processes.new_process([path_ops.get_node_path(), "-v"], run=True) + result = processes.new_process([node_path, "-v"], run=True) # The output will be in the form "vX.Y.Z", but version.parse() can handle it return version.parse(result.stdout) # type: ignore except (FileNotFoundError, TypeError): @@ -606,6 +611,11 @@ def install_node(): console.debug("") return + # Skip installation if check_node_version() checks out + if check_node_version(): + console.debug("Skipping node installation as it is already installed.") + return + path_ops.mkdir(constants.Fnm.DIR) if not os.path.exists(constants.Fnm.EXE): download_and_extract_fnm_zip() @@ -622,10 +632,6 @@ def install_node(): ], ) else: # All other platforms (Linux, MacOS). - # TODO we can skip installation if check_node_version() checks out - if check_node_version(): - console.debug("Skipping node installation as it is already installed.") - return # Add execute permissions to fnm executable. os.chmod(constants.Fnm.EXE, stat.S_IXUSR) # Install node. @@ -926,8 +932,12 @@ def initialize_frontend_dependencies(): """Initialize all the frontend dependencies.""" # validate dependencies before install validate_frontend_dependencies() + # Avoid warning about Node installation while we're trying to install it. + global CURRENTLY_INSTALLING_NODE + CURRENTLY_INSTALLING_NODE = True # Install the frontend dependencies. processes.run_concurrently(install_node, install_bun) + CURRENTLY_INSTALLING_NODE = False # Set up the web directory. initialize_web_directory() diff --git a/reflex/utils/processes.py b/reflex/utils/processes.py index ce165d70c7..025f22ee7b 100644 --- a/reflex/utils/processes.py +++ b/reflex/utils/processes.py @@ -135,13 +135,20 @@ def new_process(args, run: bool = False, show_logs: bool = False, **kwargs): Returns: Execute a child program in a new process. + + Raises: + Exit: When attempting to run a command with a None value. """ node_bin_path = path_ops.get_node_bin_path() - if not node_bin_path: + if not node_bin_path and not prerequisites.CURRENTLY_INSTALLING_NODE: console.warn( "The path to the Node binary could not be found. Please ensure that Node is properly " - "installed and added to your system's PATH environment variable." + "installed and added to your system's PATH environment variable or try running " + "`reflex init` again." ) + if None in args: + console.error(f"Invalid command: {args}") + raise typer.Exit(1) # Add the node bin path to the PATH environment variable. env = { **os.environ,