Ensure file and url are always present in MDX for Astro.glob (#4076)

This commit is contained in:
Matthew Phillips 2022-07-28 10:58:44 -04:00 committed by GitHub
parent 6fb95dbdd6
commit 6120a71e54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 100 additions and 5 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/mdx': patch
---
Ensure file and url are always present in MDX for Astro.glob

View file

@ -96,10 +96,14 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
// or otherwise refactored to not require copy-paste handling logic.
code += `\nimport "${'astro:scripts/page-ssr.js'}";`;
const { fileUrl, fileId } = getFileInfo(id, config);
if (!moduleExports.includes('url')) {
const { fileUrl } = getFileInfo(id, config);
code += `\nexport const url = ${JSON.stringify(fileUrl)};`;
}
if (!moduleExports.includes('file')) {
code += `\nexport const file = ${JSON.stringify(fileId)};`;
}
if (command === 'dev') {
// TODO: decline HMR updates until we have a stable approach
code += `\nif (import.meta.hot) {

View file

@ -4,16 +4,34 @@ function appendForwardSlash(path: string) {
return path.endsWith('/') ? path : path + '/';
}
interface FileInfo {
fileId: string;
fileUrl: string;
}
/** @see 'vite-plugin-utils' for source */
export function getFileInfo(id: string, config: AstroConfig) {
export function getFileInfo(id: string, config: AstroConfig): FileInfo {
const sitePathname = appendForwardSlash(
config.site ? new URL(config.base, config.site).pathname : config.base
);
// Try to grab the file's actual URL
let url: URL | undefined = undefined;
try {
url = new URL(`file://${id}`);
} catch {}
const fileId = id.split('?')[0];
let fileUrl = fileId.includes('/pages/')
? fileId.replace(/^.*?\/pages\//, sitePathname).replace(/(\/index)?\.mdx$/, '')
: undefined;
let fileUrl: string;
const isPage = fileId.includes('/pages/');
if(isPage) {
fileUrl = fileId.replace(/^.*?\/pages\//, sitePathname).replace(/(\/index)?\.mdx$/, '');
} else if(url && url.pathname.startsWith(config.root.pathname)) {
fileUrl = url.pathname.slice(config.root.pathname.length);
} else {
fileUrl = fileId;
}
if (fileUrl && config.trailingSlash === 'always') {
fileUrl = appendForwardSlash(fileUrl);
}

View file

@ -0,0 +1,5 @@
---
one: hello
slug: one
---
First mdx file

View file

@ -0,0 +1,34 @@
---
export const getStaticPaths = async () => {
const content = await Astro.glob('../content/*.mdx');
return content
.filter((page) => !page.frontmatter.draft) // skip drafts
.map(({ default: MdxContent, frontmatter, url, file }) => {
return {
params: { slug: frontmatter.slug || "index" },
props: {
MdxContent,
file,
frontmatter,
url
}
}
})
}
const { MdxContent, frontmatter, url, file } = Astro.props;
---
<html>
<head>
<title>Page</title>
</head>
<body>
<MdxContent />
<div id="one">{frontmatter.one}</div>
<div id="url">{url}</div>
<div id="file">{file}</div>
</body>
</html>

View file

@ -0,0 +1,29 @@
import mdx from '@astrojs/mdx';
import { expect } from 'chai';
import { loadFixture } from '../../../astro/test/test-utils.js';
import * as cheerio from 'cheerio';
const FIXTURE_ROOT = new URL('./fixtures/mdx-get-static-paths', import.meta.url);
describe('getStaticPaths', () => {
/** @type {import('astro/test/test-utils').Fixture} */
let fixture;
before(async () => {
fixture = await loadFixture({
root: FIXTURE_ROOT,
integrations: [mdx()],
});
await fixture.build();
});
it('Provides file and url', async () => {
const html = await fixture.readFile('/one/index.html');
const $ = cheerio.load(html);
expect($('p').text()).to.equal('First mdx file');
expect($('#one').text()).to.equal('hello', 'Frontmatter included');
expect($('#url').text()).to.equal('/src/content/1.mdx', 'url is included');
expect($('#file').text()).to.contain('fixtures/mdx-get-static-paths/src/content/1.mdx', 'file is included');
});
});