Eptagone / Vite.AspNetCore

Small library to integrate Vite into ASP.NET projects
MIT License
264 stars 35 forks source link

Replace Vite dev server process with ViteDevServerBackgroundService #92

Closed austins closed 9 months ago

austins commented 10 months ago

Problem: The issue with the current implementation is that the Vite dev server doesn't launch and stop all child processes reliably sometimes.

Proposal: The underlying solution is to launch the Vite binary directly and send a SIGINT on stopping. This PR replaces the current process and stop script logic with a background service and uses CliWrap to launch the Vite dev server.

By having it as a BackgroundService, we can run the process concurrently as executing the command blocks the thread and pipe the output to the application's logs.

We should avoid running the command npm run dev since it doesn't close properly probably due to how npm/pnpm/other package managers spawn Node and manages processes, so I replaced the command to directly call node_modules/.bin/vite (on Windows, it runs vite.CMD). If this doesn't work on Mac/Linux (haven't tested), an alternative would be having node some-script.js file that either programatically starts Vite, or calls Node's exec or execSync to have Node manage the child processes that the command may spawn.

I've removed the logic that checks if the server is running on the port as it seems to now close the Vite processes reliably. However, with the nature of how funky launching a Node process from .NET is, we'll need more testing to see if it closes reliably, otherwise we should bring it back and then add logic in the BackgroundService ExecuteAsync before launching the command to check if it's already running. There could be an edge case where the main app stops unexpectedly during runtime or if the user force closes the app.

About CliWrap: it provides a wrapper around Process. It's MIT licensed, do note their terms of use; without this library, we'd have to abstract some logic around Process for SIGINT and piping output. It sends a SIGINT when the application is stopping, which is like typing CTRL + C when running a Node script/Vite directly, which is more reliable than stopping the process as launching Vite spawns multiple child processes (e.g. Node and esbuild). It also handles cancellation tokens and pipes standard output accordingly.

Environments tested:

@Eptagone So far this seems to work good. Feel free to disregard the PR or make changes (some more refactoring may have to be done to clean up the middleware, etc). It's a bit of an experiment on my end and it needs some testing in other environments. 😃

Related:

Eptagone commented 9 months ago

Hello, I'm not sure. I would prefer not to have to add dependencies if possible.

And also, I would prefer this project to be neutral and not have to get involved in political issues. I say this because of the terms of use of that dependency.

So, I'm sorry but I'm closing this PR. If you find another alternative, feel free to open a new pull request.