-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve MDX rendering performance (#8533)
- Loading branch information
Showing
10 changed files
with
175 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@astrojs/mdx': patch | ||
--- | ||
|
||
Improve MDX rendering performance by sharing processor instance |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
packages/integrations/mdx/src/recma-inject-import-meta-env.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import type { Literal, MemberExpression } from 'estree'; | ||
import { visit as estreeVisit } from 'estree-util-visit'; | ||
|
||
export function recmaInjectImportMetaEnv({ | ||
importMetaEnv, | ||
}: { | ||
importMetaEnv: Record<string, any>; | ||
}) { | ||
return (tree: any) => { | ||
estreeVisit(tree, (node) => { | ||
if (node.type === 'MemberExpression') { | ||
// attempt to get "import.meta.env" variable name | ||
const envVarName = getImportMetaEnvVariableName(node); | ||
if (typeof envVarName === 'string') { | ||
// clear object keys to replace with envVarLiteral | ||
for (const key in node) { | ||
delete (node as any)[key]; | ||
} | ||
const envVarLiteral: Literal = { | ||
type: 'Literal', | ||
value: importMetaEnv[envVarName], | ||
raw: JSON.stringify(importMetaEnv[envVarName]), | ||
}; | ||
Object.assign(node, envVarLiteral); | ||
} | ||
} | ||
}); | ||
}; | ||
} | ||
|
||
/** | ||
* Check if estree entry is "import.meta.env.VARIABLE" | ||
* If it is, return the variable name (i.e. "VARIABLE") | ||
*/ | ||
function getImportMetaEnvVariableName(node: MemberExpression): string | Error { | ||
try { | ||
// check for ".[ANYTHING]" | ||
if (node.object.type !== 'MemberExpression' || node.property.type !== 'Identifier') | ||
return new Error(); | ||
|
||
const nestedExpression = node.object; | ||
// check for ".env" | ||
if (nestedExpression.property.type !== 'Identifier' || nestedExpression.property.name !== 'env') | ||
return new Error(); | ||
|
||
const envExpression = nestedExpression.object; | ||
// check for ".meta" | ||
if ( | ||
envExpression.type !== 'MetaProperty' || | ||
envExpression.property.type !== 'Identifier' || | ||
envExpression.property.name !== 'meta' | ||
) | ||
return new Error(); | ||
|
||
// check for "import" | ||
if (envExpression.meta.name !== 'import') return new Error(); | ||
|
||
return node.property.name; | ||
} catch (e) { | ||
if (e instanceof Error) { | ||
return e; | ||
} | ||
return new Error('Unknown parsing error'); | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
packages/integrations/mdx/src/rehype-apply-frontmatter-export.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { InvalidAstroDataError } from '@astrojs/markdown-remark'; | ||
import { safelyGetAstroData } from '@astrojs/markdown-remark/dist/internal.js'; | ||
import type { VFile } from 'vfile'; | ||
import { jsToTreeNode } from './utils.js'; | ||
|
||
export function rehypeApplyFrontmatterExport() { | ||
return function (tree: any, vfile: VFile) { | ||
const astroData = safelyGetAstroData(vfile.data); | ||
if (astroData instanceof InvalidAstroDataError) | ||
throw new Error( | ||
// Copied from Astro core `errors-data` | ||
// TODO: find way to import error data from core | ||
'[MDX] A remark or rehype plugin attempted to inject invalid frontmatter. Ensure "astro.frontmatter" is set to a valid JSON object that is not `null` or `undefined`.' | ||
); | ||
const { frontmatter } = astroData; | ||
const exportNodes = [ | ||
jsToTreeNode(`export const frontmatter = ${JSON.stringify(frontmatter)};`), | ||
]; | ||
if (frontmatter.layout) { | ||
// NOTE(bholmesdev) 08-22-2022 | ||
// Using an async layout import (i.e. `const Layout = (await import...)`) | ||
// Preserves the dev server import cache when globbing a large set of MDX files | ||
// Full explanation: 'https://github.com/withastro/astro/pull/4428' | ||
exportNodes.unshift( | ||
jsToTreeNode( | ||
/** @see 'vite-plugin-markdown' for layout props reference */ | ||
`import { jsx as layoutJsx } from 'astro/jsx-runtime'; | ||
export default async function ({ children }) { | ||
const Layout = (await import(${JSON.stringify(frontmatter.layout)})).default; | ||
const { layout, ...content } = frontmatter; | ||
content.file = file; | ||
content.url = url; | ||
return layoutJsx(Layout, { | ||
file, | ||
url, | ||
content, | ||
frontmatter: content, | ||
headings: getHeadings(), | ||
'server:root': true, | ||
children, | ||
}); | ||
};` | ||
) | ||
); | ||
} | ||
tree.children = exportNodes.concat(tree.children); | ||
}; | ||
} |
Oops, something went wrong.