Skip to content

Commit 57e65d2

Browse files
authored
revert: markdoc asset bleed (#7178)
* revert: markdoc asset bleed * chore: changeset
1 parent cbdb0fd commit 57e65d2

File tree

16 files changed

+120
-294
lines changed

16 files changed

+120
-294
lines changed

.changeset/tiny-phones-reply.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@astrojs/markdoc': patch
3+
'@astrojs/mdx': patch
4+
'astro': patch
5+
---
6+
7+
Fix: revert Markdoc asset bleed changes. Production build issues were discovered that deserve a different fix.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { defineCollection, z } from 'astro:content';
2+
3+
const docs = defineCollection({
4+
schema: z.object({
5+
title: z.string(),
6+
}),
7+
});
8+
9+
export const collections = { docs };

packages/astro/src/@types/astro.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,12 +1275,6 @@ export interface ContentEntryType {
12751275
}
12761276
): rollup.LoadResult | Promise<rollup.LoadResult>;
12771277
contentModuleTypes?: string;
1278-
/**
1279-
* Handle asset propagation for rendered content to avoid bleed.
1280-
* Ex. MDX content can import styles and scripts, so `handlePropagation` should be true.
1281-
* @default true
1282-
*/
1283-
handlePropagation?: boolean;
12841278
}
12851279

12861280
type GetContentEntryInfoReturnType = {

packages/astro/src/content/consts.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
11
export const PROPAGATED_ASSET_FLAG = 'astroPropagatedAssets';
2-
export const CONTENT_RENDER_FLAG = 'astroRenderContent';
32
export const CONTENT_FLAG = 'astroContentCollectionEntry';
43
export const DATA_FLAG = 'astroDataCollectionEntry';
4+
export const CONTENT_FLAGS = [CONTENT_FLAG, DATA_FLAG, PROPAGATED_ASSET_FLAG] as const;
55

66
export const VIRTUAL_MODULE_ID = 'astro:content';
77
export const LINKS_PLACEHOLDER = '@@ASTRO-LINKS@@';
88
export const STYLES_PLACEHOLDER = '@@ASTRO-STYLES@@';
99
export const SCRIPTS_PLACEHOLDER = '@@ASTRO-SCRIPTS@@';
1010

11-
export const CONTENT_FLAGS = [
12-
CONTENT_FLAG,
13-
CONTENT_RENDER_FLAG,
14-
DATA_FLAG,
15-
PROPAGATED_ASSET_FLAG,
16-
] as const;
17-
1811
export const CONTENT_TYPES_FILE = 'types.d.ts';

packages/astro/src/content/runtime.ts

Lines changed: 52 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -270,82 +270,62 @@ async function render({
270270
const baseMod = await renderEntryImport();
271271
if (baseMod == null || typeof baseMod !== 'object') throw UnexpectedRenderError;
272272

273-
if (
274-
baseMod.default != null &&
275-
typeof baseMod.default === 'object' &&
276-
baseMod.default.__astroPropagation === true
277-
) {
278-
const { collectedStyles, collectedLinks, collectedScripts, getMod } = baseMod.default;
279-
if (typeof getMod !== 'function') throw UnexpectedRenderError;
280-
const propagationMod = await getMod();
281-
if (propagationMod == null || typeof propagationMod !== 'object') throw UnexpectedRenderError;
273+
const { collectedStyles, collectedLinks, collectedScripts, getMod } = baseMod;
274+
if (typeof getMod !== 'function') throw UnexpectedRenderError;
275+
const mod = await getMod();
276+
if (mod == null || typeof mod !== 'object') throw UnexpectedRenderError;
282277

283-
const Content = createComponent({
284-
factory(result, baseProps, slots) {
285-
let styles = '',
286-
links = '',
287-
scripts = '';
288-
if (Array.isArray(collectedStyles)) {
289-
styles = collectedStyles
290-
.map((style: any) => {
291-
return renderUniqueStylesheet(result, {
292-
type: 'inline',
293-
content: style,
294-
});
295-
})
296-
.join('');
297-
}
298-
if (Array.isArray(collectedLinks)) {
299-
links = collectedLinks
300-
.map((link: any) => {
301-
return renderUniqueStylesheet(result, {
302-
type: 'external',
303-
src: prependForwardSlash(link),
304-
});
305-
})
306-
.join('');
307-
}
308-
if (Array.isArray(collectedScripts)) {
309-
scripts = collectedScripts.map((script: any) => renderScriptElement(script)).join('');
310-
}
278+
const Content = createComponent({
279+
factory(result, baseProps, slots) {
280+
let styles = '',
281+
links = '',
282+
scripts = '';
283+
if (Array.isArray(collectedStyles)) {
284+
styles = collectedStyles
285+
.map((style: any) => {
286+
return renderUniqueStylesheet(result, {
287+
type: 'inline',
288+
content: style,
289+
});
290+
})
291+
.join('');
292+
}
293+
if (Array.isArray(collectedLinks)) {
294+
links = collectedLinks
295+
.map((link: any) => {
296+
return renderUniqueStylesheet(result, {
297+
type: 'external',
298+
src: prependForwardSlash(link),
299+
});
300+
})
301+
.join('');
302+
}
303+
if (Array.isArray(collectedScripts)) {
304+
scripts = collectedScripts.map((script: any) => renderScriptElement(script)).join('');
305+
}
311306

312-
let props = baseProps;
313-
// Auto-apply MDX components export
314-
if (id.endsWith('mdx')) {
315-
props = {
316-
components: propagationMod.components ?? {},
317-
...baseProps,
318-
};
319-
}
307+
let props = baseProps;
308+
// Auto-apply MDX components export
309+
if (id.endsWith('mdx')) {
310+
props = {
311+
components: mod.components ?? {},
312+
...baseProps,
313+
};
314+
}
320315

321-
return createHeadAndContent(
322-
unescapeHTML(styles + links + scripts) as any,
323-
renderTemplate`${renderComponent(
324-
result,
325-
'Content',
326-
propagationMod.Content,
327-
props,
328-
slots
329-
)}`
330-
);
331-
},
332-
propagation: 'self',
333-
});
316+
return createHeadAndContent(
317+
unescapeHTML(styles + links + scripts) as any,
318+
renderTemplate`${renderComponent(result, 'Content', mod.Content, props, slots)}`
319+
);
320+
},
321+
propagation: 'self',
322+
});
334323

335-
return {
336-
Content,
337-
headings: propagationMod.getHeadings?.() ?? [],
338-
remarkPluginFrontmatter: propagationMod.frontmatter ?? {},
339-
};
340-
} else if (baseMod.Content && typeof baseMod.Content === 'function') {
341-
return {
342-
Content: baseMod.Content,
343-
headings: baseMod.getHeadings?.() ?? [],
344-
remarkPluginFrontmatter: baseMod.frontmatter ?? {},
345-
};
346-
} else {
347-
throw UnexpectedRenderError;
348-
}
324+
return {
325+
Content,
326+
headings: mod.getHeadings?.() ?? [],
327+
remarkPluginFrontmatter: mod.frontmatter ?? {},
328+
};
349329
}
350330

351331
export function createReference({ lookupMap }: { lookupMap: ContentLookupMap }) {

packages/astro/src/content/template/virtual-mod.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function createGlobLookup(glob) {
4646
}
4747

4848
const renderEntryGlob = import.meta.glob('@@RENDER_ENTRY_GLOB_PATH@@', {
49-
query: { astroRenderContent: true },
49+
query: { astroPropagatedAssets: true },
5050
});
5151
const collectionToRenderEntryMap = createCollectionToGlobResultMap({
5252
globResult: renderEntryGlob,

packages/astro/src/content/utils.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import type {
1414
} from '../@types/astro.js';
1515
import { VALID_INPUT_FORMATS } from '../assets/consts.js';
1616
import { AstroError, AstroErrorData } from '../core/errors/index.js';
17-
1817
import { formatYAMLException, isYAMLException } from '../core/errors/utils.js';
1918
import { CONTENT_FLAGS, CONTENT_TYPES_FILE } from './consts.js';
2019
import { errorMap } from './error-map.js';
@@ -329,7 +328,7 @@ export function parseFrontmatter(fileContents: string, filePath: string) {
329328
*/
330329
export const globalContentConfigObserver = contentObservable({ status: 'init' });
331330

332-
export function hasContentFlag(viteId: string, flag: (typeof CONTENT_FLAGS)[number]): boolean {
331+
export function hasContentFlag(viteId: string, flag: (typeof CONTENT_FLAGS)[number]) {
333332
const flags = new URLSearchParams(viteId.split('?')[1] ?? '');
334333
return flags.has(flag);
335334
}

packages/astro/src/content/vite-plugin-content-assets.ts

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { extname } from 'node:path';
2-
import { pathToFileURL } from 'node:url';
1+
import { pathToFileURL } from 'url';
32
import type { Plugin } from 'vite';
43
import type { AstroSettings } from '../@types/astro.js';
54
import { moduleIsTopLevelPage, walkParentInfos } from '../core/build/graph.js';
@@ -12,13 +11,16 @@ import { joinPaths, prependForwardSlash } from '../core/path.js';
1211
import { getStylesForURL } from '../core/render/dev/css.js';
1312
import { getScriptsForURL } from '../core/render/dev/scripts.js';
1413
import {
15-
CONTENT_RENDER_FLAG,
1614
LINKS_PLACEHOLDER,
1715
PROPAGATED_ASSET_FLAG,
1816
SCRIPTS_PLACEHOLDER,
1917
STYLES_PLACEHOLDER,
2018
} from './consts.js';
21-
import { hasContentFlag } from './utils.js';
19+
20+
function isPropagatedAsset(viteId: string) {
21+
const flags = new URLSearchParams(viteId.split('?')[1]);
22+
return flags.has(PROPAGATED_ASSET_FLAG);
23+
}
2224

2325
export function astroContentAssetPropagationPlugin({
2426
mode,
@@ -30,31 +32,13 @@ export function astroContentAssetPropagationPlugin({
3032
let devModuleLoader: ModuleLoader;
3133
return {
3234
name: 'astro:content-asset-propagation',
33-
enforce: 'pre',
34-
async resolveId(id, importer, opts) {
35-
if (hasContentFlag(id, CONTENT_RENDER_FLAG)) {
36-
const base = id.split('?')[0];
37-
38-
for (const { extensions, handlePropagation = true } of settings.contentEntryTypes) {
39-
if (handlePropagation && extensions.includes(extname(base))) {
40-
return this.resolve(`${base}?${PROPAGATED_ASSET_FLAG}`, importer, {
41-
skipSelf: true,
42-
...opts,
43-
});
44-
}
45-
}
46-
// Resolve to the base id (no content flags)
47-
// if Astro doesn't need to handle propagation.
48-
return this.resolve(base, importer, { skipSelf: true, ...opts });
49-
}
50-
},
5135
configureServer(server) {
5236
if (mode === 'dev') {
5337
devModuleLoader = createViteLoader(server);
5438
}
5539
},
5640
async transform(_, id, options) {
57-
if (hasContentFlag(id, PROPAGATED_ASSET_FLAG)) {
41+
if (isPropagatedAsset(id)) {
5842
const basePath = id.split('?')[0];
5943
let stringifiedLinks: string, stringifiedStyles: string, stringifiedScripts: string;
6044

@@ -89,17 +73,14 @@ export function astroContentAssetPropagationPlugin({
8973
}
9074

9175
const code = `
92-
async function getMod() {
76+
export async function getMod() {
9377
return import(${JSON.stringify(basePath)});
9478
}
95-
const collectedLinks = ${stringifiedLinks};
96-
const collectedStyles = ${stringifiedStyles};
97-
const collectedScripts = ${stringifiedScripts};
98-
const defaultMod = { __astroPropagation: true, getMod, collectedLinks, collectedStyles, collectedScripts };
99-
export default defaultMod;
79+
export const collectedLinks = ${stringifiedLinks};
80+
export const collectedStyles = ${stringifiedStyles};
81+
export const collectedScripts = ${stringifiedScripts};
10082
`;
101-
// ^ Use a default export for tools like Markdoc
102-
// to catch the `__astroPropagation` identifier
83+
10384
return { code, map: { mappings: '' } };
10485
}
10586
},

packages/astro/src/core/render/dev/vite.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { ModuleLoader, ModuleNode } from '../../module-loader/index';
22

33
import npath from 'path';
4+
import { PROPAGATED_ASSET_FLAG } from '../../../content/consts.js';
45
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from '../../constants.js';
56
import { unwrapId } from '../../util.js';
67
import { isCSSRequest } from './util.js';
@@ -9,10 +10,9 @@ import { isCSSRequest } from './util.js';
910
* List of file extensions signalling we can (and should) SSR ahead-of-time
1011
* See usage below
1112
*/
12-
const fileExtensionsToSSR = new Set(['.astro', '.mdoc', ...SUPPORTED_MARKDOWN_FILE_EXTENSIONS]);
13+
const fileExtensionsToSSR = new Set(['.astro', ...SUPPORTED_MARKDOWN_FILE_EXTENSIONS]);
1314

1415
const STRIP_QUERY_PARAMS_REGEX = /\?.*$/;
15-
const ASTRO_PROPAGATED_ASSET_REGEX = /\?astroPropagatedAssets/;
1616

1717
/** recursively crawl the module graph to get all style files imported by parent id */
1818
export async function* crawlGraph(
@@ -23,6 +23,7 @@ export async function* crawlGraph(
2323
): AsyncGenerator<ModuleNode, void, unknown> {
2424
const id = unwrapId(_id);
2525
const importedModules = new Set<ModuleNode>();
26+
if (new URL(id, 'file://').searchParams.has(PROPAGATED_ASSET_FLAG)) return;
2627

2728
const moduleEntriesForId = isRootFile
2829
? // "getModulesByFile" pulls from a delayed module cache (fun implementation detail),
@@ -43,7 +44,6 @@ export async function* crawlGraph(
4344
if (id === entry.id) {
4445
scanned.add(id);
4546
const entryIsStyle = isCSSRequest(id);
46-
4747
for (const importedModule of entry.importedModules) {
4848
// some dynamically imported modules are *not* server rendered in time
4949
// to only SSR modules that we can safely transform, we check against
@@ -60,13 +60,15 @@ export async function* crawlGraph(
6060
if (entryIsStyle && !isCSSRequest(importedModulePathname)) {
6161
continue;
6262
}
63-
const isFileTypeNeedingSSR = fileExtensionsToSSR.has(
64-
npath.extname(importedModulePathname)
65-
);
6663
if (
67-
isFileTypeNeedingSSR &&
68-
// Should not SSR a module with ?astroPropagatedAssets
69-
!ASTRO_PROPAGATED_ASSET_REGEX.test(importedModule.id)
64+
fileExtensionsToSSR.has(
65+
npath.extname(
66+
// Use `id` instead of `pathname` to preserve query params.
67+
// Should not SSR a module with an unexpected query param,
68+
// like "?astroPropagatedAssets"
69+
importedModule.id
70+
)
71+
)
7072
) {
7173
const mod = loader.getModuleById(importedModule.id);
7274
if (!mod?.ssrModule) {

packages/astro/src/vite-plugin-head/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import { getTopLevelPages, walkParentInfos } from '../core/build/graph.js';
99
import type { BuildInternals } from '../core/build/internal.js';
1010
import { getAstroMetadata } from '../vite-plugin-astro/index.js';
1111

12-
// Detect this in comments, both in .astro components and in js/ts files.
13-
const injectExp = /(^\/\/|\/\/!)\s*astro-head-inject/;
12+
const injectExp = /^\/\/\s*astro-head-inject/;
1413

1514
export default function configHeadVitePlugin({
1615
settings,
@@ -33,7 +32,6 @@ export default function configHeadVitePlugin({
3332
seen.add(id);
3433
const mod = server.moduleGraph.getModuleById(id);
3534
const info = this.getModuleInfo(id);
36-
3735
if (info?.meta.astro) {
3836
const astroMetadata = getAstroMetadata(info);
3937
if (astroMetadata) {

0 commit comments

Comments
 (0)