Manage multiple Vite SPAs with separate config files #496
Replies: 1 comment 6 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.
-
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