Skip to content
This repository has been archived by the owner on Nov 6, 2023. It is now read-only.

example of setup with vite istead of vuecli? #93

Open
zoranpopovic opened this issue Apr 28, 2021 · 7 comments
Open

example of setup with vite istead of vuecli? #93

zoranpopovic opened this issue Apr 28, 2021 · 7 comments

Comments

@zoranpopovic
Copy link

I think it would be great if there was an example of how to setup with vite instead of vue-cli. it seems that the middleware is general enough that this should be possible.

@EEParker
Copy link
Owner

EEParker commented Apr 28, 2021

I think the only change would be to the regex for whatever the export of Vite shows on the console when the web app is ready. Also, be sure to replace the contents of ClientApp with a Vite app instead of vue-cli.

https://github.com/EEParker/aspnetcore-vueclimiddleware/blob/master/samples/Vue3/Startup.cs#L67

                endpoints.MapToVueCliProxy(
                    "{*path}",
                    new SpaOptions { SourcePath = "ClientApp" },
                    npmScript: (System.Diagnostics.Debugger.IsAttached) ? "serve" : null, // make sure `serve` is the correct command
                    regex: "Compiled successfully", // change this to vite output
                    forceKill: true
                    );

@coolhome
Copy link

coolhome commented May 3, 2021

At the moment without these two tickets I'm not sure how far you can get with this.

The HMR requires websockets to be proxied. You can use something like AspNetCore.Proxy to forward the websockets but there is no way to tell Vite the port to actually run the HMR (runtimePort) and what to use in the HTML (hmr port - need to be the proxy server port).

An alterative approach however is to use Vite's proxy feature and skip this plugin and continue to use AddSpaStaticFiles/UseSpaStaticFiles for production builds. You would need to start the SPA project separately and use those endpoints instead. This approach does require the proxy url to be different than the vite project.

Run this command or use alternative methods for generating a SSL certificate. I used the following msbuild target.

    <Target Name="GetHttpsForLocal" BeforeTargets="Build">
        <Exec WorkingDirectory="$(SpaRoot)" Command="dotnet dev-certs https -ep ./localhost-key.pfx -p dev-passphrase" ContinueOnError="true">
            <Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
        </Exec>
        <Error Condition="'$(ErrorCode)' != '0'" Text="Failed to get localhost key" />
    </Target>

vite.config.ts

import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import { readFileSync } from 'fs'

const key = readFileSync('localhost-key.pfx');

export default defineConfig({
    plugins: [vue()],
    server: {
        https: {
            pfx: key,
            passphrase: 'dev-passphrase' // required for some reason -- maybe easier way?
        },
        proxy: {
            '^/api/.*': {
                target: 'https://localhost:5001',
                rewrite: (path) => path.replace(/^\/api/, ''),
                changeOrigin: true,
                secure: false
            },
            '^/swagger': {
                target: 'https://localhost:5001',
                changeOrigin: true,
                secure: false                
            }
        }
    }
})

@zoranpopovic
Copy link
Author

So does this mean that all traffic goes through vite first, which forwards specific routes to dotnet while serving the vue routes directly? Are swagger supposed to go to dotnet?

@EEParker
Copy link
Owner

EEParker commented Jul 9, 2021

What about vite for production build?

This tool is meant for development only and to facility HMR and other features. Production should serve the static files directly using standard AspNet static file methods.

@abezulski
Copy link

I gave it a try and eventually hit a wall.

  • Windows 10
  • Node v14.16.0
  • .net core 3.1

When using MapToVueCliProxy I got the error message related to the port parameter as it tries to append port to the npmScript command:

info: VueCliMiddleware[0]
      > echo Starting the development server && vite build --mode development "--port" "8080"
info: VueCliMiddleware[0]
      Starting the development server

fail: VueCliMiddleware[0]
      E:\vite-setup\vueapp\node_modules\vite\dist\node\cli.js:426

fail: VueCliMiddleware[0]
                throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);

fail: VueCliMiddleware[0]
                ^

fail: VueCliMiddleware[0]
      CACError: Unknown option `--port`

To accommodate regex changes for Vite (mentioned by @EEParker) I modified my npm script:
"build-dev": "echo Starting the development server && vite build --mode development".

I guess one of two things need to happen:

  • VueCliMiddleware needs to stop appending --port param and assume that whatever is default will be used (port in VueCli and Vite configs and be changed), or
  • ViteJS does add --port param to the command

@yitzolsberg
Copy link

yitzolsberg commented Sep 12, 2022

I've got this mostly working now (albeit with Vue 2) due to the following 2 fixes in Vite:

In vite.config.js:

defineConfig({
    ///....
    server: {
        hmr: {
            clientPort: 44308,
        }
    }
})

package.json:

"scripts": {
    "dev": "vite",
    "serve": "vite preview",
    "build": "vite build"
  }

Program.cs (or Startup.cs):

endpoints.MapToVueCliProxy(
    "{*path}",
    new SpaOptions { SourcePath = "ClientApp" },
    npmScript: isDevelopement ? "dev" : null,
    regex: "ready in .+ ms", //vite 3 doesn't show "running at" text anymore. "\d+ ms" doesn't work because of color formatting
    port: 8080,
    forceKill: true
    );

However, quite often on the first run, a few of the requests from vite for certain components are failing. The requests make it to the vite proxy, but are failing with:

System.Net.Http.HttpRequestException: Failed to proxy the request to http://127.0.0.1:8080/src/XXXXXX.vue?vue&type=style&index=0&scoped=477d7e3e&lang.css, because the request to the proxy target failed. Check that the proxy target server is running and accepting requests to http://127.0.0.1:8080/.

The underlying exception message was 'An error occurred while sending the request.'.Check the InnerException for more details.
 ---> System.Net.Http.HttpRequestException: An error occurred while sending the request.
 ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host..
 ---> System.Net.Sockets.SocketException (10054): An existing connection was forcibly closed by the remote host.
   --- End of inner exception stack trace ---

etc etc

A refresh of the page and all works fine. I can't work out what the issue is.

@kubayubay
Copy link

I have it working just fine and I'm using vite3 with vuejs3 in my .NET 6 project. What I have:

vite.config.ts - I had to set server.host to true because of some VueCliMiddelware was pushing for 127.0.0.1 while vite was expecting localhost and I needed to set server.hmr.protocol to 'ws' for websocket:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  server: {
    host: true,
    hmr: {
      protocol: 'ws',
      port: 52896
    }
  },
})

Program.cs (or Startup.cs) - like @yitzolsberg said, vite3 prints out ready in [x]ms so you gotta make VueCliMiddleware look for that:

spa.UseVueCli(npmScript: "dev", port: 3000, false, ScriptRunnerType.Npm, "ready in", true);

Hope this helps!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants