diff --git a/.changeset/modern-bears-deny.md b/.changeset/modern-bears-deny.md
new file mode 100644
index 000000000000..876535a5c033
--- /dev/null
+++ b/.changeset/modern-bears-deny.md
@@ -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();
+---
+
+
+```
diff --git a/packages/astro/src/assets/vite-plugin-assets.ts b/packages/astro/src/assets/vite-plugin-assets.ts
index 57bbf847a4ff..f7c541eb6265 100644
--- a/packages/astro/src/assets/vite-plugin-assets.ts
+++ b/packages/astro/src/assets/vite-plugin-assets.ts
@@ -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);
diff --git a/packages/astro/src/types/public/content.ts b/packages/astro/src/types/public/content.ts
index ac58c918f48f..77c0b2f17620 100644
--- a/packages/astro/src/types/public/content.ts
+++ b/packages/astro/src/types/public/content.ts
@@ -21,7 +21,7 @@ export interface MarkdownInstance> {
/** raw Markdown file content, excluding layout HTML and YAML frontmatter */
rawContent(): string;
/** Markdown file compiled to HTML, excluding layout HTML */
- compiledContent(): string;
+ compiledContent(): Promise;
/** List of headings (h1 -> h6) with associated metadata */
getHeadings(): MarkdownHeading[];
default: AstroComponentFactory;
diff --git a/packages/astro/src/vite-plugin-markdown/images.ts b/packages/astro/src/vite-plugin-markdown/images.ts
index b9ea98b82b50..d0ed625358ff 100644
--- a/packages/astro/src/vite-plugin-markdown/images.ts
+++ b/packages/astro/src/vite-plugin-markdown/images.ts
@@ -23,7 +23,6 @@ export function getMarkdownCodeForImages(imagePaths: MarkdownImagePath[], html:
const matchKey = ${rawUrl} + '_' + occurrenceCounter;
const imageProps = JSON.parse(match[1].replace(/"/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(/"/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(/"/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)});
`;
}
diff --git a/packages/astro/src/vite-plugin-markdown/index.ts b/packages/astro/src/vite-plugin-markdown/index.ts
index 694b96448fb5..a85eaff4659c 100644
--- a/packages/astro/src/vite-plugin-markdown/index.ts
+++ b/packages/astro/src/vite-plugin-markdown/index.ts
@@ -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;