diff options
Diffstat (limited to 'packages/integrations/mdx/src/index.ts')
-rw-r--r-- | packages/integrations/mdx/src/index.ts | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts index 571fecb67..8909c8cae 100644 --- a/packages/integrations/mdx/src/index.ts +++ b/packages/integrations/mdx/src/index.ts @@ -1,19 +1,19 @@ +import type { AstroIntegration } from 'astro'; +import type { Plugin as VitePlugin } from 'vite'; import { compile as mdxCompile } from '@mdx-js/mdx'; import mdxPlugin, { Options as MdxRollupPluginOptions } from '@mdx-js/rollup'; -import type { AstroIntegration } from 'astro'; import { parse as parseESM } from 'es-module-lexer'; import { blue, bold } from 'kleur/colors'; import { VFile } from 'vfile'; -import type { Plugin as VitePlugin } from 'vite'; -import { rehypeApplyFrontmatterExport } from './astro-data-utils.js'; -import type { MdxOptions } from './utils.js'; +import fs from 'node:fs/promises'; +import { getFileInfo, handleExtendsNotSupported, parseFrontmatter } from './utils.js'; import { - getFileInfo, + recmaInjectImportMetaEnvPlugin, + rehypeApplyFrontmatterExport, getRehypePlugins, getRemarkPlugins, - handleExtendsNotSupported, - parseFrontmatter, -} from './utils.js'; +} from './plugins.js'; +import { PluggableList } from '@mdx-js/mdx/lib/core.js'; const RAW_CONTENT_ERROR = 'MDX does not support rawContent()! If you need to read the Markdown contents to calculate values (ex. reading time), we suggest injecting frontmatter via remark plugins. Learn more on our docs: https://docs.astro.build/en/guides/integrations-guide/mdx/#inject-frontmatter-via-remark-or-rehype-plugins'; @@ -21,6 +21,19 @@ const RAW_CONTENT_ERROR = const COMPILED_CONTENT_ERROR = 'MDX does not support compiledContent()! If you need to read the HTML contents to calculate values (ex. reading time), we suggest injecting frontmatter via rehype plugins. Learn more on our docs: https://docs.astro.build/en/guides/integrations-guide/mdx/#inject-frontmatter-via-remark-or-rehype-plugins'; +export type MdxOptions = { + remarkPlugins?: PluggableList; + rehypePlugins?: PluggableList; + /** + * Choose which remark and rehype plugins to inherit, if any. + * + * - "markdown" (default) - inherit your project’s markdown plugin config ([see Markdown docs](https://docs.astro.build/en/guides/markdown-content/#configuring-markdown)) + * - "astroDefaults" - inherit Astro’s default plugins only ([see defaults](https://docs.astro.build/en/reference/configuration-reference/#markdownextenddefaultplugins)) + * - false - do not inherit any plugins + */ + extendPlugins?: 'markdown' | 'astroDefaults' | false; +}; + export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration { return { name: '@astrojs/mdx', @@ -58,17 +71,28 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration { mdExtensions: [], }; + let importMetaEnv: Record<string, any> = { + SITE: config.site, + }; + updateConfig({ vite: { plugins: [ { enforce: 'pre', ...mdxPlugin(mdxPluginOpts), + configResolved(resolved) { + importMetaEnv = { ...importMetaEnv, ...resolved.env }; + }, // Override transform to alter code before MDX compilation // ex. inject layouts - async transform(code, id) { + async transform(_, id) { if (!id.endsWith('mdx')) return; + // Read code from file manually to prevent Vite from parsing `import.meta.env` expressions + const { fileId } = getFileInfo(id, config); + const code = await fs.readFile(fileId, 'utf-8'); + const { data: frontmatter, content: pageContent } = parseFrontmatter(code, id); const compiled = await mdxCompile(new VFile({ value: pageContent, path: id }), { ...mdxPluginOpts, @@ -76,10 +100,11 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration { ...(mdxPluginOpts.rehypePlugins ?? []), () => rehypeApplyFrontmatterExport(frontmatter), ], + recmaPlugins: [() => recmaInjectImportMetaEnvPlugin({ importMetaEnv })], }); return { - code: String(compiled.value), + code: escapeViteEnvReferences(String(compiled.value)), map: compiled.map, }; }, @@ -123,7 +148,7 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration { import.meta.hot.decline(); }`; } - return code; + return escapeViteEnvReferences(code); }, }, ] as VitePlugin[], @@ -133,3 +158,10 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration { }, }; } + +// Converts the first dot in `import.meta.env` to its Unicode escape sequence, +// which prevents Vite from replacing strings like `import.meta.env.SITE` +// in our JS representation of loaded Markdown files +function escapeViteEnvReferences(code: string) { + return code.replace(/import\.meta\.env/g, 'import\\u002Emeta.env'); +} |