Skip to content

Conversation

@strfx
Copy link

@strfx strfx commented Nov 26, 2025

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 test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Edits

  • Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.

…veltejs#12615)

vite-imagetools caches processed images by default in
`node_modules/.cache/imagetools`. Storing the cache inside `node_modules`
can be undesirable in some scenarios - for example, during clean installs
(`npm ci`) in CI environments.

This commit adds the ability for configuring an alternative cache directory.
@changeset-bot
Copy link

changeset-bot bot commented Nov 26, 2025

🦋 Changeset detected

Latest commit: b96cdf4

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

@strfx strfx changed the title feat: Allow configuring cache directory for @sveltejs/enhanced-img (#12615) feat: Allow configuring cache directory for @sveltejs/enhanced-img Nov 26, 2025
@dominikg
Copy link
Member

dominikg commented Dec 4, 2025

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?

@elliott-with-the-longest-name-on-github
Copy link
Contributor

@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.

@strfx
Copy link
Author

strfx commented Dec 11, 2025

@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.

import { image_plugin } from './vite-plugin.js';

/**
* @typedef {{cache?: CacheOptions}} EnhancedImageOptions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should use the types exported by vite-imagetools so that we don't have to update here if they add new options

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right - I've originally opted for a custom interface following the discussion in the linked issue. But looking at it now, using vite-imagetools's types makes more sense. I'll update the PR accordingly.

namedExports: false
};

if (opts.cache) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason to not pass the opts to imagetools directly?

@dominikg
Copy link
Member

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.

@strfx
Copy link
Author

strfx commented Dec 11, 2025

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants