Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] WebSocket HMR not working as expected with Nuxt #11165

Open
Sun-ZhenXing opened this issue Sep 27, 2024 · 7 comments
Open

[bug] WebSocket HMR not working as expected with Nuxt #11165

Sun-ZhenXing opened this issue Sep 27, 2024 · 7 comments
Labels
status: needs triage This issue needs to triage, applied to new issues type: bug

Comments

@Sun-ZhenXing
Copy link

Sun-ZhenXing commented Sep 27, 2024

Describe the bug

The methods described in this document does not mark HMR work on mobile devices.

Because Nuxt does not use vite's HMR config. Nuxt rewrite vite config, and uses ws://$host:$port/_nuxt/ to provide HMR:

09-27 18:01:57.473  9019  9019 E Tauri/Console: File: http://tauri.localhost/_nuxt/@vite/client - Line 535 - Msg: WebSocket connection to 'ws://tauri.localhost/_nuxt/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
09-27 18:01:57.473  9019  9019 E Tauri/Console: File: http://tauri.localhost/_nuxt/@vite/client - Line 535 - Msg: Uncaught (in promise) SyntaxError: Failed to construct 'WebSocket': The URL 'ws://localhost:undefined/_nuxt/' is invalid.

It tries to connect to localhost:undefined and tauri.localhost, but this is incorrect.

All endpoints have been tried and there is no WebSocket support. This may require a direct connection to the host.

Reproduction

From official document: https://v2.tauri.app/start/frontend/nuxt/

adb devices # connect a Android devices ...

pnpm tauri android dev

If this is not detailed enough, please call me for reproduction.

Expected behavior

No error.

Full tauri info output

[✔] Environment
    - OS: Windows 10.0.22631 x86_64 (X64)
    ✔ WebView2: 129.0.2792.52
    ✔ MSVC: Visual Studio Community 2022
    ✔ rustc: 1.81.0 (eeb90cda1 2024-09-04)
    ✔ cargo: 1.81.0 (2dbb1af80 2024-08-20)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-x86_64-pc-windows-msvc (default)
    - node: 20.14.0
    - pnpm: 9.11.0
    - npm: 10.7.0
    - bun: 1.1.28

[-] Packages
    - tauri 🦀: 2.0.0-rc.15
    - tauri-build 🦀: 2.0.0-rc.12
    - wry 🦀: 0.43.1
    - tao 🦀: 0.30.1
    - @tauri-apps/api : 2.0.0-rc.5
    - @tauri-apps/cli : 2.0.0-rc.16

[-] Plugins
    - tauri-plugin-log 🦀: 2.0.0-rc.2
    - @tauri-apps/plugin-log : not installed!

[-] App
    - build-type: bundle
    - CSP: connect-src ws://*
    - frontendDist: ../dist
    - devUrl: http://localhost:3000/
    - framework: Vue.js (Nuxt)
    - bundler: Webpack

Stack trace

09-27 18:02:41.207  9019  9019 E Tauri/Console: File: http://tauri.localhost/_nuxt/@vite/client - Line 535 - Msg: WebSocket connection to 'ws://tauri.localhost/_nuxt/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
09-27 18:02:41.209  9019  9019 E Tauri/Console: File: http://tauri.localhost/_nuxt/@vite/client - Line 535 - Msg: Uncaught (in promise) SyntaxError: Failed to construct 'WebSocket': The URL 'ws://localhost:undefined/_nuxt/' is invalid.
09-27 18:04:34.822  9019  9019 I HwViewRootImpl: removeInvalidNode jank list is null
09-27 18:04:37.867  9019  9019 I HwViewRootImpl: removeInvalidNode jank list is null
09-27 18:04:40.996  9019  9019 E Tauri/Console: File: http://tauri.localhost/__nuxt_devtools__/client/_nuxt/l4ouzdbv.js - Line 8 - Msg: Uncaught (in promise) Error: [birpc] timeout on calling "getOptions"
09-27 18:04:41.307  9019  9019 E Tauri/Console: File: http://tauri.localhost/__nuxt_devtools__/client/_nuxt/l4ouzdbv.js - Line 8 - Msg: Uncaught (in promise) Error: [birpc] timeout on calling "getModuleOptions"
09-27 18:04:41.309  9019  9019 E Tauri/Console: File: http://tauri.localhost/__nuxt_devtools__/client/_nuxt/l4ouzdbv.js - Line 8 - Msg: Uncaught (in promise) Error: [birpc] timeout on calling "getOptions"
09-27 18:04:41.312  9019  9019 E Tauri/Console: File: http://tauri.localhost/__nuxt_devtools__/client/_nuxt/l4ouzdbv.js - Line 8 - Msg: Uncaught (in promise) Error: [birpc] timeout on calling "telemetryEvent"
09-27 18:04:41.314  9019  9019 E Tauri/Console: File: http://tauri.localhost/__nuxt_devtools__/client/_nuxt/l4ouzdbv.js - Line 8 - Msg: Uncaught (in promise) Error: [birpc] timeout on calling "getOptions"

Additional context

No response

@Sun-ZhenXing Sun-ZhenXing added status: needs triage This issue needs to triage, applied to new issues type: bug labels Sep 27, 2024
@Sun-ZhenXing
Copy link
Author

I found a workaround:

{
  devServer: {
    host: isMobile ? '0.0.0.0' : undefined,
  },
  hooks: {
    'vite:extend': function ({ config }) {
      if (config.server && config.server.hmr && config.server.hmr !== true) {
        config.server.hmr.protocol = 'ws'
        config.server.hmr.host = '192.168.XXX.XXX'
        config.server.hmr.port = 3000
      }
    },
  },
  vite: {
    clearScreen: false,
    envPrefix: ['VITE_', 'TAURI_'],
    server: {
      strictPort: true,
      watch: {
        ignored: ['**/src-tauri/**'],
      },
    },
  },
}

But I think undefined appearing in URLs is a bug.

@gkkirilov
Copy link

gkkirilov commented Nov 16, 2024

Hey @Sun-ZhenXing can you share a working example, as I am getting a white screen creating a nuxt based app for mobile

@gkkirilov
Copy link

I dig a little bit further and saw those errors as the culprit of the white screen

11-18 01:04:14.193 15907 15907 E Tauri/Console: File: - Line 138 - Msg: Uncaught TypeError: Cannot redefine property: postMessage
11-18 01:04:14.194 15907 15907 E Tauri/Console: File: - Line 2 - Msg: Uncaught TypeError: Cannot redefine property: metadata
11-18 01:04:14.194 15907 15907 E Tauri/Console: File: - Line 25 - Msg: Uncaught TypeError: Cannot redefine property: TAURI_PATTERN
11-18 01:04:14.194 15907 15907 E Tauri/Console: File: - Line 5 - Msg: Uncaught TypeError: Cannot redefine property: path

image

@igvoloj
Copy link

igvoloj commented Nov 27, 2024

@gkkirilov Im suspecting about the blank screen is caused (correct me if Im wrong, those folders dont need to be generated for dev but I suspect Tauri needs it for app dev) because dist and .output folders are empty. When running npx tauri android dev after nuxi generate both folders content wipe with no reason apparently i don't know if Tauri is gonna use those folders because they ask to run nuxi generate... Ive taken some snapshots while npx tauri android dev --verbose was running and I got this 5 different both folders state:

FIRST STATE:
issue1

SECOND STATE: (Notice that nitro.json is removed)
issue2

THIRD STATE:
issue3

FOURTH STATE:
issue4

FIFTH STATE:
issue5

The wipe of both folders occurs exactly at this part of the logging:

issue6

If I remove ssr: false the blank screen dissapears and content appears but looks messy obviously because ssr has no place here... anyways sometimes I get the app correctly rendered... those are the 3 possible cases but HMR still not working with @Sun-ZhenXing solution. In both cases the initial loading page of Nuxt appears as usual.

FIRST CASE:

issue7

SECOND CASE:

issue8

THIRD CASE:

issue9

Any clues?

@JessicaSachs
Copy link

JessicaSachs commented Nov 30, 2024

Here's my minimal working config. (Some of) the lengthy fs ignores are necessary to keep the server startup time low. It was taking well over 1 minute to startup without putting these ignores in.

The entire setup took me quite a few hours to figure out.

The main issue with HMR is the undefined value for the Vite WS port.

Screenshot 2024-11-30 at 12 45 18 AM

The vite:hook example above helped, but I needed to leave the original devServer values alone (better to take in what Tauri gives you anyway).

export default defineNuxtConfig({
  // (optional) Enable the Nuxt devtools
  devtools: { enabled: true },

  // Enable SSG
  ssr: false,
  ignore: ['**/src-tauri/**', '**/node_modules/**', '**/dist/**', '**/.git/**', '**/.nuxt/**', '**/.output/**'],

  // Enables the development server to be discoverable by other devices when running on iOS physical devices
  devServer: { host: process.env.TAURI_DEV_HOST || 'localhost' },

  vite: {
    // Better support for Tauri CLI output
    clearScreen: false,
    // Enable environment variables
    // Additional environment variables can be found at
    // https://v2.tauri.app/reference/environment-variables/
    envPrefix: ['VITE_', 'TAURI_'],
    server: {
      // Tauri requires a consistent port
      strictPort: true,
      watch: {
        ignored: [
          '**/src-tauri/**',
          '**/node_modules/**',
          '**/dist/**',
          '**/.git/**',
          '**/.nuxt/**',
          '**/public/**',
          '**/.output/**'
        ]
      }
    },
  },

  hooks: {
    'vite:extend': function ({ config }) {
      if (config.server && config.server.hmr && config.server.hmr !== true) {
        config.server.hmr.port = 3000
      }
    },
  },

  compatibilityDate: '2024-11-29'
});

@codywakeford
Copy link

This got my HMR working. Thanks

    hooks: {
        'vite:extend': function ({ config }) {
            if (config.server && config.server.hmr && config.server.hmr !== true) {
                config.server.hmr.port = 3000
            }
        },
    },

    vite: {
        clearScreen: false,
        envPrefix: ['VITE_', 'TAURI_'],
        server: {
            watch: {
                ignored: ["**/src-tauri/**"],
                usePolling: true
            },
            strictPort: true,
            hmr: {
                host: '192.168.0.15',
                port: 5137,
                protocol: "ws"
            },
            
        },

        
        css: {
            preprocessorOptions: {
                scss: {
                    additionalData: '@use "@/assets/scss/variables.scss" as *;',
                },
            },
        },
    },
    
    ````

@Sun-ZhenXing
Copy link
Author

Cargo.zip

When reproducing on my Android phone, I encountered another new issue tauri-apps/wry#1420.

I am attaching the Cargo lock file that works so that it can be debugged properly. Until the above issue is fixed, I can't confirm that the latest Tauri will work on my Android phone.

# Cargo.toml
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2021"
rust-version = "1.77.2"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
# Do not update tauri, till the issue is resolved

[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "lib"]

[build-dependencies]
tauri-build = { version = "2.0.0", features = [] }

[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
log = { version = "0.4" }
tauri = { version = "2.0.0", features = [] }
tauri-plugin-log = "2.0.0"
// nuxt.config.ts
// ...
import process from 'node:process'

const isMobile = !!/android|ios/.exec(process.env.TAURI_ENV_PLATFORM || '')
const host = process.env.NUXT_HMR_HOST || process.env.TAURI_DEV_HOST || undefined

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devServer: {
    host: isMobile ? '0.0.0.0' : undefined,
  },
  ignore: [
    '**/src-tauri/**',
    '**/node_modules/**',
    '**/dist/**',
    '**/.git/**',
    '**/.nuxt/**',
    '**/.output/**',
  ],
  hooks: {
    // [BUG] https://github.com/tauri-apps/tauri/issues/11165
    'vite:extend': host && isMobile
      ? ({ config }) => {
          if (config.server && config.server.hmr && config.server.hmr !== true) {
            config.server.hmr.protocol = 'ws'
            config.server.hmr.host = host
            config.server.hmr.port = 3000
          }
        }
      : undefined,
  },
  vite: {
    clearScreen: false,
    envPrefix: ['VITE_', 'TAURI_'],
    server: {
      watch: {
        ignored: ['**/src-tauri/**'],
        usePolling: true,
      },
      strictPort: true,
    },
    css: {
      preprocessorOptions: {
        scss: { api: 'modern-compiler' },
      },
    },
  },
})

I'm pretty sure that this problem can't be solved at the moment, because WebSocket doesn't seem to be able to be proxied yet.

So this workaround will work for a long time yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage This issue needs to triage, applied to new issues type: bug
Projects
None yet
Development

No branches or pull requests

5 participants