0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

fix(assets): Remove TLA by making compiledContent async (#11782)

* fix(assets): Remove TLA by making compiledContent async

* fix: actually use the functions I just added lol

* chore: changeset
This commit is contained in:
Erika 2024-08-20 15:52:08 +02:00 committed by GitHub
parent cfa6a47ac7
commit 9a2aaa01ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 44 additions and 47 deletions

View file

@ -0,0 +1,16 @@
---
'astro': major
---
Makes the `compiledContent` property of Markdown content an async function, this change should fix underlying issues where sometimes when using a custom image service and images inside Markdown, Node would exit suddenly without any error message.
```diff
---
import * as myPost from "../post.md";
- const content = myPost.compiledContent();
+ const content = await myPost.compiledContent();
---
<Fragment set:html={content} />
```

View file

@ -2,7 +2,6 @@ import { extname } from 'node:path';
import MagicString from 'magic-string';
import type * as vite from 'vite';
import { normalizePath } from 'vite';
import { extendManualChunks } from '../core/build/plugins/util.js';
import { AstroError, AstroErrorData } from '../core/errors/index.js';
import {
appendForwardSlash,
@ -106,19 +105,6 @@ export default function assets({
// Expose the components and different utilities from `astro:assets` and handle serving images from `/_image` in dev
{
name: 'astro:assets',
outputOptions(outputOptions) {
// Specifically split out chunk for asset files to prevent TLA deadlock
// caused by `getImage()` for markdown components.
// https://github.com/rollup/rollup/issues/4708
extendManualChunks(outputOptions, {
after(id) {
if (id.includes('astro/dist/assets/services/')) {
// By convention, library code is emitted to the `chunks/astro/*` directory
return `astro/assets-service`;
}
},
});
},
async resolveId(id) {
if (id === VIRTUAL_SERVICE_ID) {
return await this.resolve(settings.config.image.service.entrypoint);

View file

@ -21,7 +21,7 @@ export interface MarkdownInstance<T extends Record<string, any>> {
/** raw Markdown file content, excluding layout HTML and YAML frontmatter */
rawContent(): string;
/** Markdown file compiled to HTML, excluding layout HTML */
compiledContent(): string;
compiledContent(): Promise<string>;
/** List of headings (h1 -> h6) with associated metadata */
getHeadings(): MarkdownHeading[];
default: AstroComponentFactory;

View file

@ -23,7 +23,6 @@ export function getMarkdownCodeForImages(imagePaths: MarkdownImagePath[], html:
const matchKey = ${rawUrl} + '_' + occurrenceCounter;
const imageProps = JSON.parse(match[1].replace(/&#x22;/g, '"'));
const { src, ...props } = imageProps;
imageSources[matchKey] = await getImage({src: Astro__${entry.safeName}, ...props});
occurrenceCounter++;
}
@ -33,32 +32,28 @@ export function getMarkdownCodeForImages(imagePaths: MarkdownImagePath[], html:
return imageSources;
};
async function updateImageReferences(html) {
return images(html).then((imageSources) => {
return html.replaceAll(/__ASTRO_IMAGE_="([^"]+)"/gm, (full, imagePath) => {
const decodedImagePath = JSON.parse(imagePath.replace(/&#x22;/g, '"'));
// Use the 'index' property for each image occurrence
const srcKey = decodedImagePath.src + '_' + decodedImagePath.index;
if (imageSources[srcKey].srcSet && imageSources[srcKey].srcSet.values.length > 0) {
imageSources[srcKey].attributes.srcset = imageSources[srcKey].srcSet.attribute;
}
const { index, ...attributesWithoutIndex } = imageSources[srcKey].attributes;
return spreadAttributes({
src: imageSources[srcKey].src,
...attributesWithoutIndex,
});
});
});
}
async function updateImageReferences(html) {
const imageSources = await images(html);
// NOTE: This causes a top-level await to appear in the user's code, which can break very easily due to a Rollup
// bug and certain adapters not supporting it correctly. See: https://github.com/rollup/rollup/issues/4708
// Tread carefully!
const html = await updateImageReferences(${JSON.stringify(html)});
return html.replaceAll(/__ASTRO_IMAGE_="([^"]+)"/gm, (full, imagePath) => {
const decodedImagePath = JSON.parse(imagePath.replace(/&#x22;/g, '"'));
// Use the 'index' property for each image occurrence
const srcKey = decodedImagePath.src + '_' + decodedImagePath.index;
if (imageSources[srcKey].srcSet && imageSources[srcKey].srcSet.values.length > 0) {
imageSources[srcKey].attributes.srcset = imageSources[srcKey].srcSet.attribute;
}
const { index, ...attributesWithoutIndex } = imageSources[srcKey].attributes;
return spreadAttributes({
src: imageSources[srcKey].src,
...attributesWithoutIndex,
});
});
}
const html = async () => await updateImageReferences(${JSON.stringify(html)});
`;
}

View file

@ -115,7 +115,7 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
// Only include the code relevant to `astro:assets` if there's images in the file
imagePaths.length > 0
? getMarkdownCodeForImages(imagePaths, html)
: `const html = ${JSON.stringify(html)};`
: `const html = () => ${JSON.stringify(html)};`
}
export const frontmatter = ${JSON.stringify(frontmatter)};
@ -124,8 +124,8 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
export function rawContent() {
return ${JSON.stringify(raw.content)};
}
export function compiledContent() {
return html;
export async function compiledContent() {
return await html();
}
export function getHeadings() {
return ${JSON.stringify(headings)};
@ -148,9 +148,9 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
compiledContent,
'server:root': true,
}, {
'default': () => render\`\${unescapeHTML(html)}\`
'default': () => render\`\${unescapeHTML(html())}\`
})}\`;`
: `render\`\${maybeRenderHead(result)}\${unescapeHTML(html)}\`;`
: `render\`\${maybeRenderHead(result)}\${unescapeHTML(html())}\`;`
}
});
export default Content;