Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix using optimized images with base #6643

Merged
merged 8 commits into from
Mar 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.