fix: capistrano deployment docs correction for vite v5
Description 📖
When using Vite v5 and above, Capistrano is not aware that the location of the asset manifest files has moved, and fails on deployment with Rails assets manifest file not found.
Background 📜
When using Vite v5 and above, asset manifest files are output to a vite/.vite/ subdirectory, by default. Meaning that the manifest.json and manifest-assets.json files that used to reside under public/vite/ now reside under public/vite/.vite/.
The Fix 🔨
Update documentation to reflect that there is a difference between the Capistrano configuration when using Vite v4 and Vite v5. The fix when using Vite v5 and above is to set the Capistrano :assets_manifests option. The path(s) need to be relative or absolute.
@tenkiller
Thanks for the update! It started working as you mentioned. Now, the issue I'm facing is that when the Skipping asset precompile, no asset diff found, the deploy fails with the following error: Rails Assets manifest file not found.
Could there be a path conflict with Sprockets searching for the manifest?
set :assets_prefix, 'vite'
set :assets_manifests, ["public/#{fetch(:assets_prefix)}/.vite/manifest*.*"]
ls /releases/xxxx/public/vite/manifest*
ls ls: cannot access /releases/xxxx/public/vite/manifest*
ls 10 : No such file or directory
ls /releases/xxxx/public/vite/.sprockets-manifest*
ls ls: cannot access /releases/xxxx/public/vite/.sprockets-manifest*'
ls No such file or directory
@rgioia Good point. I had considered including the path for the Rails Asset Pipeline (i.e. sprockets), but we weren't getting any errors on deployment for our setup, so I overlooked it.
By setting :assets_manifests, it overrides the default, which is
[
"/path/to/release_path/public/#{fetch(:assets_prefix)}/.sprockets-manifest*",
"/path/to/release_path/public/#{fetch(:assets_prefix)}/manifest*.*"
]
But, we don't want to add this back in as given because assets_prefix is set to vite. The default prefix for the Rails Asset Pipeline is assets. So, I think, this should remedy it?
set :assets_manifests, [
"public/assets/.sprockets-manifest*",
"public/assets/manifest*.*",
"public/#{fetch(:assets_prefix)}/.vite/manifest*.*"
]
@tenkiller Thank you! I managed to do what I needed; I successfully switched from Webpacker to Vite.
I don't use Capistrano myself, but if I understand correctly, the instructions are not complete if the app needs to support sprockets, as public/assets would not be automatically added to linked_dirs.
Given that some users still mix sprockets and vite_rails, and some with propshaft it might be better to avoid relying on the internals of capistrano-rails and its usage of assets_prefix, and instead instruct the user to configure:
- adding
"public/vite"tolinked_dirs - adding
release_path.join("public/vite/.vite/manifest*.*")toassets_manifests
Happy to accept a PR that removes the example setting assets_prefix and explains how to append these two values.
@ElMassimo There's some odd behavior I'm experiencing with capistrano-rails and the assets_manifests list. They return an ls command capture on each string in the list. This seems like a very unintuitive way to do it, in my opinion.
Here is what I have provided in my deploy config.
set :assets_manifests, [
"public/vite/.vite/manifest*.json",
"public/assets/.sprockets-manifest*"
]
There are files that match these paths on the server after vite:build and assets:precompile complete. Note that there are three.
$ ls public/vite/.vite/manifest*.json public/assets/.sprockets-manifest*
public/assets/.sprockets-manifest-415461b893c1f289238ea242950f61cb.json
public/vite/.vite/manifest.json
public/vite/.vite/manifest-assets.json
But these are the only files capistrano-rails backs up to assets_manifest_backup directory. Not that there are two.
$ ls assets_manifest_backup/
manifest-assets.json manifest.json
I have no idea why this is the case.
I realize this isn't your problem, but an issue with capistrano-rails. I'm unsure if you should even mention capistrano in your own docs. Let me know what you think, and I can either close this PR or amend it, based on your recommendation.
Hi, I'm a maintainer of capistrano-rails. I agree with @ElMassimo's comment above about setting linked_dirs and assets_manifests explicitly, like this:
- adding
"public/vite"tolinked_dirs- adding
release_path.join("public/vite/.vite/manifest*.*")toassets_manifests
I believe the best way forward is to add those recommendations to the Vite Ruby docs.
@tenkiller, regarding the problem of capistrano-rails failing to find and backup the sprockets manifest, that might be because the sprockets manifest starts with a . character, making it hidden by default. If you use ls -a (-a shows hidden files), does it show up as you expect?
$ ls -a assets_manifest_backup/
If a bug still seems to be lurking there, please feel free to report it at https://github.com/capistrano/rails, since I don't think that particular issue is Vite-related.
@mattbrictson Thanks for responding, Matt. The sprockets manifest is definitely not on the server.
$ ls -a assets_manifest_backup/
. .. manifest-assets.json manifest.json
The funny thing is, if I list the sprockets manifest path first in the assets_manifest config setting, it appears on the server, but the vite manifests do not. Which makes me think that it's only honoring the first string. I'll open an issue on the capistrano-rails repo.
Thanks everyone for the discussion!
Updated the docs to avoid overriding assets_prefix, which would conflict with sprockets or propshaft, instead preferring to extend the config to cover the additional dirs and manifest files created by Vite Ruby.