feat: Allow configuring cache directory for @sveltejs/enhanced-img
This PR allows configuring the cache directory for @sveltejs/enhanced-img.
By default, processed images are cached in node_modules/.cache/imagetools. When running npm ci (e.g., in CI or on deployment), it completely wipes node_modules and thus the cache. Placing the cache outside of node_modules also allows caching processed images between CI runs.
Changes:
Add optional config object parameter to enhancedImages(). The object intentionally mirrors the cache options of imagetools to avoid coupling the two plugins. The parameter can be omitted to be backwards-compatible with any existing config.
Behavior:
imagetools's default cache options apply unless explicitly overwritten.
Example:
To place the caching directory to ./my-cache-dir, provide:
// vite.config.js
import { enhancedImages } from '@sveltejs/enhanced-img';
export default {
plugins: [
enhancedImages({
cache: { directory: './my-cache-dir' }
})
]
};
For a more detailed discussion, see #12615
Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
- [ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
- [ ] This message body should clearly illustrate what problems it solves.
- [ ] Ideally, include a test that fails without this PR but passes with it.
Tests
- [ ] Run the tests with
pnpm testand lint the project withpnpm lintandpnpm check
Changesets
- [ ] If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running
pnpm changesetand following the prompts. Changesets that add features should beminorand those that fix bugs should bepatch. Please prefix changeset messages withfeat:,fix:, orchore:.
Edits
- [ ] Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.
🦋 Changeset detected
Latest commit: b96cdf400093fb120bbf254411a6c48ca476d0c6
The changes in this PR will be included in the next version bump.
This PR includes changesets to release 1 package
| Name | Type |
|---|---|
| @sveltejs/enhanced-img | Minor |
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
note i am not familiar with the cache impl of vite-imagetools
keeping a persistent cache across builds requires meticulous tracking of anything that could have an effect on the cache content. From dependency versions to configuration, code or asset changes. Otherwise stale cached output is going to lead to hard to track errors.
So is that cache really safe to store across builds or is it even flushed on buildStart and just there to avoid doing the same work twice during a single build?
@dominikg it is a cache of processed images during build. It's stored in node_modules by default specifically because a lot of platforms cache that across builds.
@dominikg I assume with #14988 SvelteKit completely delegates caching of optimized images to vite-imagetools. As @elliott-with-the-longest-name-on-github pointed out, vite-imagetools stores its cache by default under node_modules and there is currently no way to change that through the enhanced-img plugin.
This PR opens enhanced-img up for configuration of underlying vite-imagetools.
Is there any kind of effort to prevent stale cached images from being reused in a future build although some configuration has changed (eg "remove exif metadata")?
Regarding CI and caching of node_modules, it really depends on the provider and package manager. For github+pnpm i believe the setup-node action caches pnpms store dir, not node_modules.
So ideally this PR comes with documentation on how to use the custom cache directory and set it up in github with the cache action. How do you solve cache restore there ? You'd need a key to pick the right one in case something has changed or again you end up with an entirely stale cache.
Thanks @dominikg for your feedback!
Is there any kind of effort to prevent stale cached images from being reused in a future build although some configuration has changed (eg "remove exif metadata")?
Not from what I've gathered - imagetools uses a hash of the directives and image content as cache key, but does not incorporate the plugin's options, i.e., toggling removeMetadata will not clear the cache.
(Relevant places in imagetools: generateImageID creates a hash of the directives and hashed image contents coming from here, uses the generated id to read / write from / to cache)
Regarding CI and caching of node_modules, it really depends on the provider and package manager. For github+pnpm i believe the setup-node action caches pnpms store dir, not node_modules.
So ideally this PR comes with documentation on how to use the custom cache directory and set it up in github with the cache action. How do you solve cache restore there ? You'd need a key to pick the right one in case something has changed or again you end up with an entirely stale cache.
Good point. I do not see a straightforward way of coming up with a reliable key without replicating some of imagetools caching logic, which I don't think makes sense.
However, putting the problem of caching in CI aside, opening up enhancedImages() to allow passing options to imagetools would address another issue besides #121615 - #13085. At the moment, there is no way of passing removeMetadata to imagetools.
Do you think it makes sense going forward? If so, I'll update the PR to directly pass through the options to imagetools, using their types.