summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Erika <3019731+Princesseuh@users.noreply.github.com> 2023-03-30 11:31:04 +0200
committerGravatar GitHub <noreply@github.com> 2023-03-30 11:31:04 +0200
commita0bdf4ce2f36a0ce7045dc9f96c15dc7d9204c47 (patch)
treefeb1f430b5c92b9255bdfeb77e33516fee67591f
parentb1b9b1390f95c6ae91389eba55f7563b911bccc7 (diff)
downloadastro-a0bdf4ce2f36a0ce7045dc9f96c15dc7d9204c47.tar.gz
astro-a0bdf4ce2f36a0ce7045dc9f96c15dc7d9204c47.tar.zst
astro-a0bdf4ce2f36a0ce7045dc9f96c15dc7d9204c47.zip
Fix multiple images being generated for the same image (#6710)
* fix(images): Fix multiple calls to same image generating multiple images * chore: changeset
-rw-r--r--.changeset/new-coats-check.md5
-rw-r--r--packages/astro/src/assets/internal.ts4
-rw-r--r--packages/astro/src/assets/types.ts2
-rw-r--r--packages/astro/src/assets/utils/transformToPath.ts10
-rw-r--r--packages/astro/src/assets/vite-plugin-assets.ts20
-rw-r--r--packages/astro/src/core/build/generate.ts2
6 files changed, 28 insertions, 15 deletions
diff --git a/.changeset/new-coats-check.md b/.changeset/new-coats-check.md
new file mode 100644
index 000000000..e749f551b
--- /dev/null
+++ b/.changeset/new-coats-check.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix multiple Image / getImage calls with the same image causing multiple duplicate images to be generated
diff --git a/packages/astro/src/assets/internal.ts b/packages/astro/src/assets/internal.ts
index e89b9d5da..5c5d82e77 100644
--- a/packages/astro/src/assets/internal.ts
+++ b/packages/astro/src/assets/internal.ts
@@ -79,7 +79,9 @@ export async function getImage(options: ImageTransform): Promise<GetImageResult>
};
}
-export function getStaticImageList(): Iterable<[ImageTransform, string]> {
+export function getStaticImageList(): Iterable<
+ [string, { path: string; options: ImageTransform }]
+> {
if (!globalThis?.astroAsset?.staticImages) {
return [];
}
diff --git a/packages/astro/src/assets/types.ts b/packages/astro/src/assets/types.ts
index 93f742e20..846e4e4cd 100644
--- a/packages/astro/src/assets/types.ts
+++ b/packages/astro/src/assets/types.ts
@@ -12,7 +12,7 @@ declare global {
var astroAsset: {
imageService?: ImageService;
addStaticImage?: ((options: ImageTransform) => string) | undefined;
- staticImages?: Map<ImageTransform, string>;
+ staticImages?: Map<string, { path: string; options: ImageTransform }>;
};
}
diff --git a/packages/astro/src/assets/utils/transformToPath.ts b/packages/astro/src/assets/utils/transformToPath.ts
index 1574af314..c2537b414 100644
--- a/packages/astro/src/assets/utils/transformToPath.ts
+++ b/packages/astro/src/assets/utils/transformToPath.ts
@@ -4,7 +4,7 @@ import { shorthash } from '../../runtime/server/shorthash.js';
import { isESMImportedImage } from '../internal.js';
import type { ImageTransform } from '../types.js';
-export function propsToFilename(transform: ImageTransform, imageService: string) {
+export function propsToFilename(transform: ImageTransform, hash: string) {
if (!isESMImportedImage(transform.src)) {
return transform.src;
}
@@ -12,9 +12,13 @@ export function propsToFilename(transform: ImageTransform, imageService: string)
let filename = removeQueryString(transform.src.src);
const ext = extname(filename);
filename = basename(filename, ext);
+ const outputExt = transform.format ? `.${transform.format}` : ext;
+ return `/${filename}_${hash}${outputExt}`;
+}
+
+export function hashTransform(transform: ImageTransform, imageService: string) {
// take everything from transform except alt, which is not used in the hash
const { alt, ...rest } = transform;
const hashFields = { ...rest, imageService };
- const outputExt = transform.format ? `.${transform.format}` : ext;
- return `/${filename}_${shorthash(JSON.stringify(hashFields))}${outputExt}`;
+ return shorthash(JSON.stringify(hashFields));
}
diff --git a/packages/astro/src/assets/vite-plugin-assets.ts b/packages/astro/src/assets/vite-plugin-assets.ts
index 3d96d08f1..52efe2487 100644
--- a/packages/astro/src/assets/vite-plugin-assets.ts
+++ b/packages/astro/src/assets/vite-plugin-assets.ts
@@ -16,7 +16,7 @@ import { copyWasmFiles } from './services/vendor/squoosh/copy-wasm.js';
import { emitESMImage } from './utils/emitAsset.js';
import { imageMetadata } from './utils/metadata.js';
import { getOrigQueryParams } from './utils/queryParams.js';
-import { propsToFilename } from './utils/transformToPath.js';
+import { hashTransform, propsToFilename } from './utils/transformToPath.js';
const resolvedVirtualModuleId = '\0' + VIRTUAL_MODULE_ID;
@@ -153,12 +153,17 @@ export default function assets({
globalThis.astroAsset.addStaticImage = (options) => {
if (!globalThis.astroAsset.staticImages) {
- globalThis.astroAsset.staticImages = new Map<ImageTransform, string>();
+ globalThis.astroAsset.staticImages = new Map<
+ string,
+ { path: string; options: ImageTransform }
+ >();
}
+ const hash = hashTransform(options, settings.config.image.service);
+
let filePath: string;
- if (globalThis.astroAsset.staticImages.has(options)) {
- filePath = globalThis.astroAsset.staticImages.get(options)!;
+ if (globalThis.astroAsset.staticImages.has(hash)) {
+ filePath = globalThis.astroAsset.staticImages.get(hash)!.path;
} else {
// If the image is not imported, we can return the path as-is, since static references
// should only point ot valid paths for builds or remote images
@@ -167,12 +172,9 @@ export default function assets({
}
filePath = prependForwardSlash(
- joinPaths(
- settings.config.build.assets,
- propsToFilename(options, settings.config.image.service)
- )
+ joinPaths(settings.config.build.assets, propsToFilename(options, hash))
);
- globalThis.astroAsset.staticImages.set(options, filePath);
+ globalThis.astroAsset.staticImages.set(hash, { path: filePath, options: options });
}
return prependForwardSlash(joinPaths(settings.config.base, filePath));
diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts
index 52e4204a9..e3b4ff2ed 100644
--- a/packages/astro/src/core/build/generate.ts
+++ b/packages/astro/src/core/build/generate.ts
@@ -108,7 +108,7 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn
if (opts.settings.config.experimental.assets) {
info(opts.logging, null, `\n${bgGreen(black(` generating optimized images `))}`);
for (const imageData of getStaticImageList()) {
- await generateImage(opts, imageData[0], imageData[1]);
+ await generateImage(opts, imageData[1].options, imageData[1].path);
}
delete globalThis.astroAsset.addStaticImage;
}