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

Support base option during dev #833

Closed
mashpie opened this issue Sep 18, 2020 · 19 comments
Closed

Support base option during dev #833

mashpie opened this issue Sep 18, 2020 · 19 comments
Labels
enhancement New feature or request

Comments

@mashpie
Copy link

mashpie commented Sep 18, 2020

Is your feature request related to a problem? Please describe.

Running multiple independent SPAs in subdirectories within the same domain like microservices for front-end is well supported for production builds by setting base. Example

https://domain.com/profile -> 'base':'/profile'
https://domain.com/admin -> 'base':'/admin'

Ok, but this seems impossible to set up for local dev because /vite/client, WebSocket, etc. will still load from the root path / instead of from base path, like /profile/vite/client.

Of course same applies to modules urls /src/App.vue instead of /profile/src/App.vue, etc.

Describe the solution you'd like

Assuming nginx (or similar) set up "in front" of some vite dev projects, like so:

location /profile {
  proxy_pass http://0.0.0.0:8081; 
}

location /admin {
  proxy_pass http://0.0.0.0:8082;
}

And running two local dev projects by a simple $ vite configured like:

// 1st vite.config.js
module.exports = {
  port: 8081,
  base: '/profile'
}

// 2nd vite.config.js
module.exports = {
  port: 8082,
  base: '/admin'
}

Describe alternatives you've considered

So far this was feasible with a little hacky setup in vue-cli (also see vuejs/vue-cli#4400):

// vue.config.js
module.exports = {
  publicPath: '/profile/',

  devServer: {
    public: '0.0.0.0',
    port: '8081',
    sockPath: '/profile/websocket',
    disableHostCheck: true
  },

  configureWebpack: {
    plugins: [
      {
        // needed workaround for sockPath issues
        apply: compiler => {
          compiler.hooks.entryOption.tap('entry', () => {
            const clients = compiler.options.entry.app
            for (const index in clients) {
              if (clients[index].match(/sockjs-node/)) {
                clients[index] = clients[index].replace(
                  '0.0.0.0/sockjs-node',
                  '0.0.0.0&sockPath=/profile/websocket'
                )
              }
            }
          })
        }
      }
    ]
  }
}

Additional context

I didn't find a solution yet within Github issues. Sorry if I missed one. There are some related PRs though to configure socket path for example. Still, there seems to be no workaround for /vite/... and /src/... URLs.

@marcio
Copy link

marcio commented Sep 19, 2020

A feature like @mashpie has described would be very good because nowadays we see a lot of stuff related to micro app, micro front ends, etc, but it's so hard (almost impossible) to reproduce in development time (with hmr, etc..) the production build behind a proxy like Nginx for example.

@mashpie
Copy link
Author

mashpie commented Oct 2, 2020

...would also love to contribute - but it looks like there are some more starting points involved. If anyone wants to briefly outline I'd be happy to dig in and provide a PR.

@mashpie
Copy link
Author

mashpie commented Jan 4, 2021

I'll check out a solution related to #677 (comment) these days (hope so :))

@yyx990803
Copy link
Member

With 2.0 this should be close enough: https://vitejs.dev/guide/build.html#multi-page-app

@mashpie
Copy link
Author

mashpie commented Jan 12, 2021

Thanks Evan! The multi-page setup is super helpful, although not exactly what I wanted to setup.

Think of a "multi-vite" setup with multiple independent repositories, even combined with other legacy ones or backend apps. Vite currently requires two extra components to be served from root, ex.:

  • /@vite/client
  • /node_modules/.vite/vue.71d55805.js

So the Nginx config above needs to add those a two extra location blocks:

server {
# [...]
  location /@vite/ {
    proxy_pass http://host.docker.internal:8081; 
  }
  location /node_modules/ {
    proxy_pass http://host.docker.internal:8081; 
  }
}

I've pushed a demo repository to illustrate the use case a bit better: https://github.com/uscreen/multi-vite

@bompus
Copy link
Contributor

bompus commented Jan 12, 2021

I think what is being asked in the original issue is a change in this behavior:

BASE_URL: "the base url the app is being served from. In development, this is always /. In production, this is determined by the build.base config option."

We would like a server.base config option to be able to specify "/vite1/" or "/vite2/" so that way we can have multiple vite projects being served up via nginx -> proxy_pass -> vite dev and instead of vite trying to request /src/assets/logo.png , the http request would go to /vite1/src/assets/logo.png instead.

This would also mean that you'd have to access your vite dev at http://127.0.0.1:3000/vite1/ instead of http://127.0.0.1:3000/, but of course that path should appear in the "running at:" list when running vite dev.

@yyx990803
Copy link
Member

yyx990803 commented Jan 12, 2021

I don't think Vite alone can be made to support this since there are a lot of assumptions made about one Vite dev server instance owning all paths under a single port. It would simply be too much change needed to support different sub paths under the same port.

The best bet is starting separate Vite instances on different ports, and then proxy everything using a 3rd custom proxy server.

@bompus
Copy link
Contributor

bompus commented Jan 12, 2021

@yyx990803 I agree with you.. I am running separate Vite instances on different ports, and proxying them through nginx.

Proxy example:
foo.localhost/app1/ -> 127.0.0.1:3001/ ( 127.0.0.1:3001/app1/ if server.base = '/app1/' )
foo.localhost/app2/ -> 127.0.0.1:3002/ ( 127.0.0.1:3002/app2/ if server.base = '/app2/' )

I believe the issue lies with Vite dev server forcing it's root path to be "/". When you reference "./assets/logo.png" in the default App.vue file for example, vite has the browser request "/src/assets/logo.png" instead of "/app1/src/assets/logo.png"

It's the same issue for the /@id/.../ , /node_modules/ files. There isn't a way to tell vite dev to prepend a path to those, so they always get requested from foo.localhost/@id/file.name instead of foo.localhost/app1/@id/file.name - Using rollupOptions.input doesn't change the behavior of these core files.

@yyx990803 yyx990803 changed the title Support to serve multiple vite projects in parallel from sub-paths in development Support base option during dev Jan 12, 2021
@yyx990803 yyx990803 added the enhancement New feature or request label Jan 12, 2021
@yyx990803 yyx990803 reopened this Jan 12, 2021
@mashpie
Copy link
Author

mashpie commented Jan 12, 2021

To clarify: different ports are perfectly feasible. See https://github.com/uscreen/multi-vite/blob/master/services/nginx/conf.d/default.conf - but, those locations marked with todo should be avoided to completely separate instances.

@bompus
Copy link
Contributor

bompus commented Jan 14, 2021

@yyx990803 if you aren't actively working on this, or plan to, I can attempt a PR.. just didn't want to dig into it if you've already started on it.

@yyx990803
Copy link
Member

@bompus I'm not working on this yet - feel free to give it a shot!

@bompus
Copy link
Contributor

bompus commented Jan 15, 2021

@yyx990803 can you take a look at my branch and see if I'm on the right track, or hopefully, completely successful and bug free.

I tested it manually and it seemed to work, even with Multi-Page App setup, and it prepends the provided base.

I wasn't sure what existing tests to modify, or if I should create a new playground test for this, so I didn't do anything with testing files yet. I also didn't check react, preact, or jsx as I am not familiar with them at all.

@yyx990803
Copy link
Member

Looks about right from a quick glance! We can do more in depth review in an actual PR (you can mark it as draft if you feel it's not done yet)

Some notes:

  • The playground/assets project uses the base option, we can use that as the test case. In scripts/jestPerTestSetup.ts we are currently only reading the base for build tests - we need to move this out so the test respects the base for both serve and build tests.

  • We should probably lift the base option to become a root level config option. Not sure if there are any cases where you'd want different base between serve and build?

@bompus
Copy link
Contributor

bompus commented Jan 16, 2021

PR submitted

@bompus
Copy link
Contributor

bompus commented Jan 27, 2021

@mashpie can you check out the newly available base config option, which should work for both dev and build.

Here is an example from my vite.config.js, note that it can be the same base in both dev/build, but wanted to provide an example if you wanted it different.

export default ({ command, mode }) => {
  return {
      base: command === 'build' ? '/app/' : '/app-dev/',
      plugins: [...],
      server: {...},
      build: {...}
    }
  }
}

@mashpie
Copy link
Author

mashpie commented Jan 27, 2021

@bompus sure! I guess it's already published... let's see

mashpie added a commit to uscreen/multi-vite that referenced this issue Jan 27, 2021
@mashpie
Copy link
Author

mashpie commented Jan 27, 2021

Perfect, just works! (And doesn't break with any exiting older setup)

Thank you so much guys. I've updated the demo repo https://github.com/uscreen/multi-vite accordingly.

Again, so glad to use that base feature from now on :)

@mashpie mashpie closed this as completed Jan 27, 2021
@lovetingyuan
Copy link

lovetingyuan commented Apr 19, 2021

Is full url base still not supported?

export default defineConfig({
  base: `http://localhost:4343/`,
  server: {
    port: 4343
  },
  plugins: [
    vue({
      template: {
        transformAssetUrls: {
          base: `http://localhost:4343/`
        }
      }
    }),
  ]
})

image

But I still get this:
image

image

@Shinigami92
Copy link
Member

@lovetingyuan Please feel free to open a new issue. On the first look your maybe requested feature is not related to this issue.

@github-actions github-actions bot locked and limited conversation to collaborators Jul 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants