Skip to content

Commit

Permalink
fix(assets): Remove TLA by making compiledContent async (#11782)
Browse files Browse the repository at this point in the history
* fix(assets): Remove TLA by making compiledContent async

* fix: actually use the functions I just added lol

* chore: changeset
  • Loading branch information
Princesseuh authored and ematipico committed Aug 21, 2024
1 parent 42fbdc4 commit 3f5f9bf
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 45 deletions.
16 changes: 16 additions & 0 deletions .changeset/modern-bears-deny.md
Original file line number Diff line number Diff line change
@@ -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} />
```
14 changes: 0 additions & 14 deletions packages/astro/src/assets/vite-plugin-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/types/public/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
45 changes: 20 additions & 25 deletions packages/astro/src/vite-plugin-markdown/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
}
Expand All @@ -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);
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,
});
});
}
// 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)});
const html = async () => await updateImageReferences(${JSON.stringify(html)});
`;
}
10 changes: 5 additions & 5 deletions packages/astro/src/vite-plugin-markdown/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)};
Expand All @@ -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)};
Expand All @@ -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;
Expand Down

0 comments on commit 3f5f9bf

Please sign in to comment.