divriots / vite-plugin-firebase

Vite plugin for firebase.
MIT License
19 stars 3 forks source link

BUG: Cannot exit cleanly #13

Open Soviut opened 2 years ago

Soviut commented 2 years ago

I have a Vite + Vue 3 project. I installed this plugin to simplify the startup but have found that hitting Ctrl+C doesn't exit cleanly.

vite.config.ts

import path from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueI18n from '@intlify/vite-plugin-vue-i18n'
import firebasePlugin from 'vite-plugin-firebase'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    vueI18n({
      fullInstall: false, // do not install components and directives
      include: path.resolve(__dirname, './src/locales/**'),
    }),
    firebasePlugin({
      projectName: 'myprojectname',
      projectId: 'myprojectname-12345',
      targets: ['hosting', 'functions'],
      showUI: true,
    }),
  ],

  resolve: {
    alias: [
      { find: '@', replacement: '/src' },
      { find: '@@', replacement: '/' },
      {
        find: 'vue-i18n',
        replacement: 'vue-i18n/dist/vue-i18n.runtime.esm-bundler.js',
      },
    ],
  },
})

The project starts fine; I see Firebase emulator start without errors. However, when I hit Ctrl+C to exit, I get the normal emulator shut down messages, but I don't get returned to the command prompt; It just hangs. When I hit Ctrl+C again (where the ^C are), it starts displaying emulator warnings. It still won't return to the command prompt, however.

The only way I'm able to exit is by closing the terminal window. This leaves port 3000 open.

  vite v2.9.12 dev server running at:

  > Local: http://localhost:3000/
  > Network: use `--host` to expose

  ready in 9511ms.

^C 
i  emulators: Received SIGINT (Ctrl-C) for the first time. Starting a clean shutdown.
i  emulators: Please wait for a clean shutdown or send the SIGINT (Ctrl-C) signal again to stop right now.
i  emulators: Shutting down emulators.
i  ui: Stopping Emulator UI
⚠  Emulator UI has exited upon receiving signal: SIGINT
i  functions: Stopping Functions Emulator
i  eventarc: Stopping Eventarc Emulator
i  hub: Stopping emulator hub
i  logging: Stopping Logging Emulator
^C 
⚠  emulators: Received SIGINT (Ctrl-C) 2 times. You have forced the Emulator Suite to exit without waiting for 0 subprocess to finish. These processes may still be running on your machine: 

┌──────────┬───────────┬─────┐
│ Emulator │ Host:Port │ PID │
└──────────┴───────────┴─────┘

To force them to exit run:

kill 

^C 
⚠  emulators: Received SIGINT (Ctrl-C) 3 times. You have forced the Emulator Suite to exit without waiting for 0 subprocess to finish. These processes may still be running on your machine: 

┌──────────┬───────────┬─────┐
│ Emulator │ Host:Port │ PID │
└──────────┴───────────┴─────┘

To force them to exit run:

kill 

^C 
⚠  emulators: Received SIGINT (Ctrl-C) 4 times. You have forced the Emulator Suite to exit without waiting for 0 subprocess to finish. These processes may still be running on your machine: 

┌──────────┬───────────┬─────┐
│ Emulator │ Host:Port │ PID │
└──────────┴───────────┴─────┘

To force them to exit run:

kill 
Soviut commented 2 years ago

An interesting follow up. If I open another terminal and kill port 3000, the port my Vue dev server is running on, the process ends and the currently hanging terminal exits back to the command line with a Killed message.

npx kill-port 3000
Soviut commented 2 years ago

I have been experimenting with this plugin locally and found that these changes seem to allow it to shut down correctly

Remove the following line, we will manually do a clean shutdown later when we detect SIGTERM

// shutdownWhenKilled({})

Remove the monkey patching on the server.close function.

      // patch server.close to close emulators as well
      // const { close: closeServer } = server
      // server.close = async () => {
      //   await Promise.all([closeServer(), cleanShutdown()])
      // }

Finally, create a shutdown function that tells firebase to do a clean shutdown, close the vite dev server and exit the process. Run this shutdown on SIGINT and SIGTERM events.

      const shutdown = async () => {
        await cleanShutdown()
        await server.close()

        // this prevents the process from hanging after server close
        process.exit(0)
      }

      process.on('SIGINT', shutdown)
      process.on('SIGTERM', shutdown)

Now, when you hit Ctrl + C to stop the vite dev server, firebase shuts down cleanly and you're returned to the command prompt.