Skip to content

Commit

Permalink
Fix: correctly transform import.meta.env.* in MDX (#4858)
Browse files Browse the repository at this point in the history
* fix: serialize route pattern for Netlify edge

Co-authored-by: Jackie Macharia <jackiewmacharia>

* fix: escape import.meta.env in MDX compiler output

* test: env vars in mdx

* chore: changeset

* deps: estree-util-visit, @types/estree

* feat: inject import.meta.env w/ recma

* feat: pull importMetaEnv from vite + astro configs

* test: `import.meta.env` in JSX

* fix: lockfile

* chore: update changeset

* fix: remove stray stashed commit
  • Loading branch information
bholmesdev committed Sep 26, 2022
1 parent b73ec14 commit 58a2dca
Show file tree
Hide file tree
Showing 12 changed files with 454 additions and 233 deletions.
5 changes: 5 additions & 0 deletions .changeset/metal-hats-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/mdx': patch
---

Correctly parse import.meta.env in MDX files
2 changes: 2 additions & 0 deletions packages/integrations/mdx/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@mdx-js/rollup": "^2.1.1",
"acorn": "^8.8.0",
"es-module-lexer": "^0.10.5",
"estree-util-visit": "^1.2.0",
"github-slugger": "^1.4.0",
"gray-matter": "^4.0.3",
"kleur": "^4.1.4",
Expand All @@ -47,6 +48,7 @@
},
"devDependencies": {
"@types/chai": "^4.3.1",
"@types/estree": "^1.0.0",
"@types/mocha": "^9.1.1",
"@types/yargs-parser": "^21.0.0",
"astro": "workspace:*",
Expand Down
103 changes: 0 additions & 103 deletions packages/integrations/mdx/src/astro-data-utils.ts

This file was deleted.

54 changes: 43 additions & 11 deletions packages/integrations/mdx/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
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';

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',
Expand Down Expand Up @@ -58,28 +71,40 @@ 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,
rehypePlugins: [
...(mdxPluginOpts.rehypePlugins ?? []),
() => rehypeApplyFrontmatterExport(frontmatter),
],
recmaPlugins: [() => recmaInjectImportMetaEnvPlugin({ importMetaEnv })],
});

return {
code: String(compiled.value),
code: escapeViteEnvReferences(String(compiled.value)),
map: compiled.map,
};
},
Expand Down Expand Up @@ -123,7 +148,7 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
import.meta.hot.decline();
}`;
}
return code;
return escapeViteEnvReferences(code);
},
},
] as VitePlugin[],
Expand All @@ -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');
}
Loading

0 comments on commit 58a2dca

Please sign in to comment.