TIL: How to use 3rd party Rubygem assets with Vite Ruby/Rails
With the rise of the no-build era in Rails, there are more and more gems where assets are included. If you’re using Vite, you’re probably also not using an asset pipeline, making it hard to reference these assets.
Fortunately, someone smart found a solution (thanks Matt Yorkley: https://github.com/ElMassimo/vite_ruby/discussions/159#discussioncomment-1992049).
Simply create a config/vite.rb
file and put the following content into it:
# frozen_string_literal: true
ViteRuby.env['GEM_PATHS'] = Gem.loaded_specs.to_h do |name, gem|
["gems/#{name}", gem.full_gem_path]
end.to_json
This will get the paths for every gem in your project and then encode them as json
so they can be saved in an environment variable.
Then in vite.config.js
, we just have to get the environment and pass the paths to Vite as aliases, and add them to the development server's allowed list of assets to serve:
import { defineConfig } from 'vite'
import RailsPlugin from 'vite-plugin-rails'
const gemPaths = JSON.parse(process.env.GEM_PATHS || '[]')
export default defineConfig({
plugins: [
RailsPlugin(),
],
resolve: {
alias: gemPaths,
},
server: {
fs: {
allow: Object.values(gemPaths),
}
}
})
Now you can reference the assets from a bundle with import "gems/my_gem_with_assets/app/javascript/my_script.js"
.
Have fun!!