Manage multiple Vite SPAs with separate config files #496
Replies: 2 comments 7 replies
-
Hi Franz! It's possible, but it's not supported out of the box, it requires a bespoke setup. I'd recommend that you try restricting the vue plugins via If you need a separate bundle for each app...An approach I'm using in a Rails app that requires 6 different builds involves manually specifying the entrypoints per "bundle": const bundles = {
admin: {
entrypoints: [
'entrypoints/admin.ts',
],
},
main: {
entrypoints: [
'entrypoints/main.ts',
'entrypoints/main_styles.scss',
],
},
// 4 additional apps.
}
const separateBundlesPlugin: Plugin = {
name: 'build:separate-bundles',
apply: 'build',
enforce: 'post',
configResolved ({ build: { rollupOptions } }) {
const bundleName = process.env.VITE_RUBY_BUNDLE_NAME
const bundleConfig = bundles[bundleName]
if (!bundleConfig)
throw new Error(`Unknown frontend bundle ${bundleName}.`)
console.info('Building', { bundleName, ...bundleConfig })
rollupOptions.input = Object.fromEntries(Object.entries(rollupOptions.input)
.filter(([name, value]) => bundleConfig.entrypoints.includes(name)))
console.info(rollupOptions.input)
},
} That way I can start a single dev server and use all "apps" in development, while at build time each one gets its own manifest: # app/helpers/vite_build_helper.rb
# Override: We want to use separate builds for each frontend app, since the
# users of these apps don't have a lot of overlap, and we want to optimize each
# bundle separately.
module ViteBuildHelper
# Override: Returns a different ViteRuby instance for each app.
#
# In development, we want the convenience of a single dev server.
# In production, use a separate build output dir and manifest for each app.
def vite_ruby_instance
@vite_ruby_instance ||= if Rails.env.local? && ViteRuby.instance.dev_server_running?
ViteRuby.instance
else
ViteBuildHelper.instances[vite_bundle_name]
end
end
# Internal: Infer the corresponding Vite bundle based on the controller's config, shared through inheritance.
def vite_bundle_name
controller.vite_bundle_name
end
class << self
def instances
@instances ||= Hash.new { |instances, bundle_name|
instances[bundle_name] = new_instance(name)
}
end
def new_instance(name)
config = ViteRuby::Config.resolve_config
ViteRuby.new(
auto_build: Rails.env.development? || (Rails.env.test? && !ENV["CI"]),
public_output_dir: "#{config.public_output_dir}/#{name}",
build_cache_dir: "tmp/cache/vite/#{name}",
).tap do |instance|
instance.define_singleton_method(:bundle_name) { name }
instance.env["VITE_RUBY_BUNDLE_NAME"] = name.to_s
instance.logger = ViteRuby.instance.logger
end
end
end
end In this case, I also take advantage of the fact that I can configure certain plugins to only process a portion of the app (via If possible, I'd suggest trying to find a different approach, as this gets quite complex. |
Beta Was this translation helpful? Give feedback.
-
@ElMassimo we're having trouble debugging an issue in our Vite Ruby installation that has two Vite servers running at the same time. Oddly enough, we don't see any logs or log points being triggered when we have both servers running (unsure why this is). What we do see is that sometimes one server will run as expected, but the other will not. However, if we start them in reverse order (i.e. the second server before the first), we see one server succeed and the other fail. We referenced the engines example as our configuration is a bit unique in that we have a monorepo setup. To explain a bit further, we have a single app with multiple engines located in an Here's an example of our project structure (names obfuscated)
For our procfile which we use to run our server in development environments, it looks a bit like this: web: bundle exec puma -C config/puma.rb
vite-base: bundle exec vite dev
vite-engine-c: VITE_RUBY_PORT=$VITE_RUBY_ENG_C_PORT VITE_RUBY_CONFIG_PATH=engines/engine_c/config/vite.json bundle exec vite dev When we run just a single server (i.e. the server for engines a, b, and d), those engines work as expected. When we try to access the routes for engine c, we see a few interesting things:
To me, this seems like we're potentially missing something in our Vite configuration at the root of our project, but we've been unable to figure out exactly what might be happening here. Do you have any ideas of what might be happening based on the context I've provided? |
Beta Was this translation helpful? Give feedback.
-
Hello and thanks for this gem,
our app consists of multiple Vue single-page apps, some of which we are currently finally migrating from Vue 2 to Vue 3.
As a first step, we are migrating the bundling from Webpack to Vite for the Vue 2 apps. (Another Vue 3 app is already on Vite.) Because we need different Vite plugins (e.g. the Vue 2 one) for each app, I think I need a different Vite config file for each, essentially two Vite build processes. Native Vite supports this with e.g.
vite build --config other.file.config.js
.Can this somehow be achieved with
vite_ruby
? Or is there another attempt I can try out?Beta Was this translation helpful? Give feedback.
All reactions