[MDX] Include url in glob result (#3981)

* deps: add es-module-lexer

* feat: inject url export on mdx files

* fix: apply url transform in prod

* test: page urls with overrides

* fix: revert test skips

* chore: changeset

* fix: add newline before export
This commit is contained in:
Ben Holmes 2022-07-20 10:56:32 -04:00 committed by GitHub
parent eaf187f2c4
commit 61fec63044
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 91 additions and 9 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/mdx': patch
---
Include page url in MDX glob result

View file

@ -30,7 +30,8 @@
"test": "mocha --exit --timeout 20000"
},
"dependencies": {
"@mdx-js/rollup": "^2.1.1"
"@mdx-js/rollup": "^2.1.1",
"es-module-lexer": "^0.10.5"
},
"devDependencies": {
"@types/chai": "^4.3.1",
@ -39,8 +40,8 @@
"astro": "workspace:*",
"astro-scripts": "workspace:*",
"chai": "^4.3.6",
"mocha": "^9.2.2",
"linkedom": "^0.14.12"
"linkedom": "^0.14.12",
"mocha": "^9.2.2"
},
"engines": {
"node": "^14.18.0 || >=16.12.0"

View file

@ -1,11 +1,13 @@
import mdxPlugin from '@mdx-js/rollup';
import type { AstroIntegration } from 'astro';
import mdxPlugin from '@mdx-js/rollup';
import { parse as parseESM } from 'es-module-lexer';
import { getFileInfo } from './utils.js';
export default function mdx(): AstroIntegration {
return {
name: '@astrojs/mdx',
hooks: {
'astro:config:setup': ({ updateConfig, addPageExtension, command }: any) => {
'astro:config:setup': ({ updateConfig, config, addPageExtension, command }: any) => {
addPageExtension('.mdx');
updateConfig({
vite: {
@ -20,14 +22,23 @@ export default function mdx(): AstroIntegration {
mdExtensions: [],
}),
},
command === 'dev' && {
{
name: '@astrojs/mdx',
transform(code: string, id: string) {
if (!id.endsWith('.mdx')) return;
// TODO: decline HMR updates until we have a stable approach
return `${code}\nif (import.meta.hot) {
const [, moduleExports] = parseESM(code);
if (!moduleExports.includes('url')) {
const { fileUrl } = getFileInfo(id, config);
code += `\nexport const url = ${JSON.stringify(fileUrl)};`;
}
if (command === 'dev') {
// TODO: decline HMR updates until we have a stable approach
code += `\nif (import.meta.hot) {
import.meta.hot.decline();
}`;
}`
}
return code;
},
},
],

View file

@ -0,0 +1,21 @@
import type { AstroConfig } from 'astro';
function appendForwardSlash(path: string) {
return path.endsWith('/') ? path : path + '/';
}
/** @see 'vite-plugin-utils' for source */
export function getFileInfo(id: string, config: AstroConfig) {
const sitePathname = appendForwardSlash(
config.site ? new URL(config.base, config.site).pathname : config.base
);
const fileId = id.split('?')[0];
let fileUrl = fileId.includes('/pages/')
? fileId.replace(/^.*?\/pages\//, sitePathname).replace(/(\/index)?\.mdx$/, '')
: undefined;
if (fileUrl && config.trailingSlash === 'always') {
fileUrl = appendForwardSlash(fileUrl);
}
return { fileId, fileUrl };
}

View file

@ -0,0 +1,9 @@
export async function get() {
const mdxPages = await import.meta.glob('./*.mdx', { eager: true });
return {
body: JSON.stringify({
urls: Object.values(mdxPages ?? {}).map(v => v?.url),
})
}
}

View file

@ -0,0 +1 @@
# I'm a page with a url of "/test-1!"

View file

@ -0,0 +1 @@
# I'm a page with a url of "/test-2!"

View file

@ -0,0 +1,3 @@
export const url = '/AH!'
# I'm a test with a url override!

View file

@ -0,0 +1,28 @@
import mdx from '@astrojs/mdx';
import { expect } from 'chai';
import { loadFixture } from '../../../astro/test/test-utils.js';
describe('MDX url export', () => {
let fixture;
before(async () => {
fixture = await loadFixture({
root: new URL('./fixtures/mdx-url-export/', import.meta.url),
integrations: [mdx()],
});
await fixture.build();
});
it('generates correct urls in glob result', async () => {
const { urls } = JSON.parse(await fixture.readFile('/pages.json'));
expect(urls).to.include('/test-1');
expect(urls).to.include('/test-2');
});
it('respects "export url" overrides in glob result', async () => {
const { urls } = JSON.parse(await fixture.readFile('/pages.json'));
expect(urls).to.include('/AH!');
});
});

View file

@ -2098,10 +2098,12 @@ importers:
astro: workspace:*
astro-scripts: workspace:*
chai: ^4.3.6
es-module-lexer: ^0.10.5
linkedom: ^0.14.12
mocha: ^9.2.2
dependencies:
'@mdx-js/rollup': 2.1.2
es-module-lexer: 0.10.5
devDependencies:
'@types/chai': 4.3.1
'@types/mocha': 9.1.1