Skip to content

Commit

Permalink
Fix using optimized images with base (#6643)
Browse files Browse the repository at this point in the history
* fix(images): Fix images having the wrong path when using `base`

* test(images): Add test for using images with base

* test: add more tests

* chore: changeset

* fix: paths

* refactor: feedback
  • Loading branch information
Princesseuh authored Mar 27, 2023
1 parent 25cd3e5 commit fc0ed9c
Show file tree
Hide file tree
Showing 19 changed files with 232 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/thick-penguins-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fix images not having the proper path when using `base`
17 changes: 15 additions & 2 deletions packages/astro/src/assets/internal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import fs from 'node:fs';
import { basename, join } from 'node:path/posix';
import type { StaticBuildOptions } from '../core/build/types.js';
import { AstroError, AstroErrorData } from '../core/errors/index.js';
import { prependForwardSlash } from '../core/path.js';
import { isLocalService, type ImageService, type LocalImageService } from './services/service.js';
import type { ImageMetadata, ImageTransform } from './types.js';

Expand Down Expand Up @@ -104,8 +106,19 @@ export async function generateImage(
clientRoot = buildOpts.settings.config.outDir;
}

const fileData = await fs.promises.readFile(new URL('.' + options.src.src, serverRoot));
const resultData = await imageService.transform(fileData, { ...options, src: options.src.src });
// The original file's path (the `src` attribute of the ESM imported image passed by the user)
const originalImagePath = options.src.src;

const fileData = await fs.promises.readFile(
new URL(
'.' +
prependForwardSlash(
join(buildOpts.settings.config.build.assets, basename(originalImagePath))
),
serverRoot
)
);
const resultData = await imageService.transform(fileData, { ...options, src: originalImagePath });

const finalFileURL = new URL('.' + filepath, clientRoot);
const finalFolderURL = new URL('./', finalFileURL);
Expand Down
8 changes: 2 additions & 6 deletions packages/astro/src/assets/vite-plugin-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,16 +167,12 @@ export default function assets({
}

filePath = prependForwardSlash(
joinPaths(
settings.config.base,
settings.config.build.assets,
propsToFilename(options)
)
joinPaths(settings.config.build.assets, propsToFilename(options))
);
globalThis.astroAsset.staticImages.set(options, filePath);
}

return filePath;
return prependForwardSlash(joinPaths(settings.config.base, filePath));
};
},
async buildEnd() {
Expand Down
53 changes: 53 additions & 0 deletions packages/astro/test/core-image.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,59 @@ describe('astro:image', () => {
});
});

describe('support base option correctly', () => {
before(async () => {
fixture = await loadFixture({
root: './fixtures/core-image-base/',
experimental: {
assets: true,
},
base: '/blog',
});
await fixture.build();
});

it('has base path prefix when using the Image component', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);
const src = $('#local img').attr('src');
expect(src.length).to.be.greaterThan(0);
expect(src.startsWith('/blog')).to.be.true;
});

it('has base path prefix when using getImage', async () => {
const html = await fixture.readFile('/get-image/index.html');
const $ = cheerio.load(html);
const src = $('img').attr('src');
expect(src.length).to.be.greaterThan(0);
expect(src.startsWith('/blog')).to.be.true;
});

it('has base path prefix when using image directly', async () => {
const html = await fixture.readFile('/direct/index.html');
const $ = cheerio.load(html);
const src = $('img').attr('src');
expect(src.length).to.be.greaterThan(0);
expect(src.startsWith('/blog')).to.be.true;
});

it('has base path prefix in Markdown', async () => {
const html = await fixture.readFile('/post/index.html');
const $ = cheerio.load(html);
const src = $('img').attr('src');
expect(src.length).to.be.greaterThan(0);
expect(src.startsWith('/blog')).to.be.true;
});

it('has base path prefix in Content Collection frontmatter', async () => {
const html = await fixture.readFile('/blog/one/index.html');
const $ = cheerio.load(html);
const src = $('img').attr('src');
expect(src.length).to.be.greaterThan(0);
expect(src.startsWith('/blog')).to.be.true;
});
});

describe('build ssg', () => {
before(async () => {
fixture = await loadFixture({
Expand Down
11 changes: 11 additions & 0 deletions packages/astro/test/fixtures/core-image-base/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "@test/core-image-ssg",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
},
"exports": {
"./service": "./src/service.ts"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: One
image: ~/assets/penguin2.jpg
cover:
image: ../../assets/penguin1.jpg
---

# A post

text here
15 changes: 15 additions & 0 deletions packages/astro/test/fixtures/core-image-base/src/content/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { defineCollection, image, z } from "astro:content";

const blogCollection = defineCollection({
schema: z.object({
title: z.string(),
image: image(),
cover: z.object({
image: image()
})
}),
});

export const collections = {
blog: blogCollection
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
import image from "~/assets/penguin1.jpg";
---

<img src={image.src} width={image.width} height={image.height} alt="A penguin!" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
![A penguin](~/assets/penguin1.jpg)

A penguin
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
import { getImage } from 'astro:assets';
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
const blogEntries = await getCollection('blog');
return blogEntries.map(entry => ({
params: { slug: entry.slug }, props: { entry },
}));
}
const { entry } = Astro.props;
const { Content } = await entry.render();
const myImage = await getImage(entry.data.image);
---
<html>
<head>
<title>Testing</title>
</head>
<body>
<h1>Testing</h1>

<div id="direct-image">
<img src={entry.data.image.src} width={entry.data.image.width} height={entry.data.image.height} />
</div>

<div id="nested-image">
<img src={entry.data.cover.image.src} width={entry.data.cover.image.width} height={entry.data.cover.image.height} />
</div>

<Content />
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
import image from "~/assets/penguin1.jpg";
---

<img src={image.src} width={image.width} height={image.height} alt="A penguin!" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
import { Image } from 'astro:assets';
import myImage from "../assets/penguin1.jpg";
---
<html>
<head>

</head>
<body>
<div id="no-format">
<Image src={myImage} alt="a penguin" />
</div>

<div id="format-avif">
<Image src={myImage} alt="a penguin" format="avif" />
</div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
import { getImage } from "astro:assets";
import image from "../assets/penguin2.jpg";
const myImage = await getImage({ src: image, width: 207, height: 243, alt: 'a penguin' });
---

<img src={myImage.src} {...myImage.attributes} />
18 changes: 18 additions & 0 deletions packages/astro/test/fixtures/core-image-base/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
import { Image } from 'astro:assets';
import myImage from "../assets/penguin1.jpg";
---
<html>
<head>

</head>
<body>
<div id="local">
<Image src={myImage} alt="a penguin" />
</div>

<div id="remote">
<Image src="https://avatars.githubusercontent.com/u/622227?s=64" alt="fred" width="48" height="48" />
</div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
![My article cover](../assets/penguin1.jpg)

Image worked
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
import { Image } from 'astro:assets';
import myImage from "../assets/penguin1.jpg";
---
<html>
<head>

</head>
<body>
<div id="no-quality">
<Image src={myImage} alt="a penguin" />
</div>

<div id="quality-low">
<Image src={myImage} alt="a penguin" quality="low" />
</div>

<div id="quality-num">
<Image src={myImage} alt="a penguin" quality="70" />
</div>
</body>
</html>
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fc0ed9c

Please sign in to comment.