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

Lost connection retry hits backend integration server rather than the Vite server #2345

Closed
mwojtul opened this issue Mar 2, 2021 · 8 comments

Comments

@mwojtul
Copy link

mwojtul commented Mar 2, 2021

Describe the bug

When running Vite with a traditional backend (https://vitejs.dev/guide/backend-integration.html) and the Vite server connection is lost, the traditional backend server is pinged to retry the connection rather than the Vite server.

I've tried setting the port and HMR port in the config, but looking at the code it seems config.base is used with a fallback to / for the ping location, so there's never a chance to customize it when using a separate backend server.

Reproduction

https://github.com/mwojtul/vite-backend-integration-polling

This example is contrived, but you can see it pinging the Express server rather than the Vite server. It just fails and simply reloads the page, but in our real world Django application, the Django dev server continually gets polled and has to be restarted after the connection to the Vite server is lost.

System Info

  • vite version: 2.0.3
  • Operating System: macOS
  • Node version: 14.16.0
  • Package manager: npm (6.14.11)
@leevigraham
Copy link

@mwojtul I had the same issue… my solution was to set server.hmr.host to the same host as the dev server. By default I think that would be 127.0.0.1.

The https://github.com/vitejs/vite/blob/main/packages/vite/src/client/client.ts#L18 script replaces __HMR_HOSTNAME__ with config.server.hmr.host in some part of the build process I don't fully understand.

The fact config.server.hmr.host is null means the client falls back to the location.hostname

@mwojtul
Copy link
Author

mwojtul commented Mar 4, 2021

@leevigraham Thanks, I've tried setting config.server.hmr.host as you suggested but when the connection is lost, it still hits port 3000 (the separate backend server) rather than port 3001 (vite dev server).

The event listener https://github.com/vitejs/vite/blob/main/packages/vite/src/client/client.ts#L176 that pings the server uses base, so the __HMR_PORT__ never makes it into the URL, unless I'm missing something.

@leevigraham
Copy link

leevigraham commented Mar 4, 2021

@mwojtul hmmm…

here's my config and debug output if that helps:

my php server is: 127.0.0.1:8000
my vite dev server is: local.mytiki.life:3000 (custom host)
my vite hmr server is: local.mytiki.life:3000 (custom host)

import * as dotenvFlow  from 'dotenv-flow'
dotenvFlow.config();

import { defineConfig } from 'vite'

export default defineConfig({
    // https://vitejs.dev/config/#root
    // Project root directory (where index.html is located).
    // Can be an absolute path, or a path relative from the location of the config file itself.
    root: './theme/',
    // https://vitejs.dev/config/#base
    // Base public path when served in development or production.
    // We're serving out of /public and building in /public/theme so we need to add /theme
    base: '/theme/',
    build: {
        // The output directory relative to project root.
        outDir: '../public/theme/',
        // Remove everything from the outputDir when building
        emptyOutDir: true,
        // the directory to nest generated assets under (relative to build.outDir)
        assetsDir: './',
        // create a manifest
        manifest: true,
        // Directly customize the underlying Rollup bundle.
        rollupOptions: {
            // Instead of checking
            input: './theme/scripts/index.js'
        }
    },
    server: {
        https: {
            key: process.env.SSL_KEY,
            cert: process.env.SSL_CERT,
        },
        host: 'local.mytiki.life',
        hmr: {
            host: 'local.mytiki.life',
        },
        open: '/theme/index.html'
    }
})
  vite:config using resolved config: {
  vite:config   root: '/Volumes/Sites/Personal/mytiki.life-twig/theme',
  vite:config   base: '/theme/',
  vite:config   build: {
  vite:config     target: [ 'es2019', 'edge16', 'firefox60', 'chrome61', 'safari11' ],
  vite:config     polyfillDynamicImport: true,
  vite:config     outDir: '../public/theme/',
  vite:config     assetsDir: './',
  vite:config     assetsInlineLimit: 4096,
  vite:config     cssCodeSplit: true,
  vite:config     sourcemap: false,
  vite:config     rollupOptions: { input: './theme/scripts/index.js' },
  vite:config     commonjsOptions: { include: [Array], extensions: [Array] },
  vite:config     minify: 'terser',
  vite:config     terserOptions: {},
  vite:config     cleanCssOptions: {},
  vite:config     write: true,
  vite:config     emptyOutDir: true,
  vite:config     manifest: true,
  vite:config     lib: false,
  vite:config     ssr: false,
  vite:config     ssrManifest: false,
  vite:config     brotliSize: true,
  vite:config     chunkSizeWarningLimit: 500
  vite:config   },
  vite:config   server: {
  vite:config     https: {
  vite:config       key: '/Volumes/Sites/Personal/mytiki.life-twig/local.mytiki.life-key.pem',
  vite:config       cert: '/Volumes/Sites/Personal/mytiki.life-twig/local.mytiki.life.pem'
  vite:config     },
  vite:config     host: 'local.mytiki.life',
  vite:config     hmr: { host: 'local.mytiki.life' },
  vite:config     open: '/theme/index.html'
  vite:config   },
  vite:config   configFile: '/Volumes/Sites/Personal/mytiki.life-twig/vite.config.js',
  vite:config   inlineConfig: {
  vite:config     root: undefined,
  vite:config     base: undefined,
  vite:config     mode: undefined,
  vite:config     configFile: undefined,
  vite:config     logLevel: undefined,
  vite:config     clearScreen: undefined,
  vite:config     server: {}
  vite:config   },
  vite:config   resolve: { dedupe: undefined, alias: [ [Object] ] },
  vite:config   publicDir: '/Volumes/Sites/Personal/mytiki.life-twig/theme/public',
  vite:config   command: 'serve',
  vite:config   mode: 'development',
  vite:config   isProduction: false,
  vite:config   optimizeCacheDir: '/Volumes/Sites/Personal/mytiki.life-twig/node_modules/.vite',
  vite:config   plugins: [
  vite:config     'vite:pre-alias',
  vite:config     'alias',
  vite:config     'vite:dynamic-import-polyfill',
  vite:config     'vite:resolve',
  vite:config     'vite:html',
  vite:config     'vite:css',
  vite:config     'vite:esbuild',
  vite:config     'vite:json',
  vite:config     'vite:wasm',
  vite:config     'vite:worker',
  vite:config     'vite:asset',
  vite:config     'vite:define',
  vite:config     'vite:css-post',
  vite:config     'vite:client-inject',
  vite:config     'vite:import-analysis'
  vite:config   ],
  vite:config   env: { BASE_URL: '/theme/', MODE: 'development', DEV: true, PROD: false },
  vite:config   assetsInclude: [Function: assetsInclude],
  vite:config   logger: {
  vite:config     hasWarned: false,
  vite:config     info: [Function: info],
  vite:config     warn: [Function: warn],
  vite:config     error: [Function: error],
  vite:config     clearScreen: [Function: clearScreen]
  vite:config   },
  vite:config   createResolver: [Function: createResolver]
  vite:config } +6ms

@Bohreromir
Copy link

Bohreromir commented Mar 30, 2021

What helped me was setting
server: { host: "127.0.0.1", hmr: { host: "127.0.0.1", protocol: "ws" } }
If if the protocol is wss I get an error that its an insecure connection

@mbacalan
Copy link

I'm having this issue while using Vite with a ASP.NET Razor Pages project. I tried above suggestions to set the server.host server.hmr but they seem to be ignored?

Here is my config:

import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    // generate manifest.json in outDir
    manifest: true,
    root: './Pages/Shared/',
    rollupOptions: {
      // overwrite default .html entry
      input: './wwwroot/js/site.js',
      outDir: './wwwroot/',
    },
    server: {
      host: "127.0.0.1",
      protocol: "ws",
      port: 3000,
      watch: {
        usePolling: true
      },
      hmr: {
        host: "127.0.0.1",
        protocol: "ws",
        port: 3000
      }
    }
  }
});

But it kept sending the __vite_ping request to the .NET server. I had to edit Vite's client file in node_modules to point it to ws://localhost:3000

const socketProtocol = 'ws'
const socketHost = 'localhost:3000'
const socket = new WebSocket(`${socketProtocol}://${socketHost}`, 'vite-hmr')
const base = __BASE__ || '/'

@RentecTravis
Copy link

I was having a similar problem. Our dev servers are remote, but Vite runs locally. Vite was trying to connect to the websocket at dev.example.com:3000 instead of to localhost:3000.

Just setting server.hmr.host to localhost and stopping and rerunning Vite fixed the problem

@jessarcher
Copy link
Contributor

I'm having the same issue and I don't believe any of the suggested fixes are for the same problem originally mentioned by @mwojtul.

In my scenario, the local web server is running on http://127.0.0.1:8000 and Vite is running on http://127.0.0.1:3000 (the default). Everything works fine when loading the page.

The problem occurs when the connection to Vite is lost (for example when restarting Vite).

The client continually pings ${base}/__vite_ping, where ${base} comes from the base config option or defaults to /. In development mode, if a full URL is provided, Vite will only use the pathname component.

This means the ping URI is always relative (e.g. /__vite_ping) and so the browser makes the request to the webserver, instead of the Vite server. This results in an endless 404 that doesn't rectify itself once Vite is running again.

I'm happy to have a go at PRing this, but I'm currently confused between server.port, server.hmr.port, and server.hmr.clientPort.

@patak-dev
Copy link
Member

This should be fixed by #6819, let us know here if that PR isn't working for you or create a new issue. Thanks!

Note: #6819 will be included in vite@3.0.0-beta.0 to be released in the next weeks

@github-actions github-actions bot locked and limited conversation to collaborators May 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants