diff --git a/examples/with-mdx/astro.config.mjs b/examples/with-mdx/astro.config.mjs index 57011d4ee..d797941ec 100644 --- a/examples/with-mdx/astro.config.mjs +++ b/examples/with-mdx/astro.config.mjs @@ -4,8 +4,5 @@ import preact from '@astrojs/preact'; // https://astro.build/config export default defineConfig({ - integrations: [ - mdx(), - preact() - ] + integrations: [mdx(), preact()], }); diff --git a/examples/with-mdx/src/pages/index.mdx b/examples/with-mdx/src/pages/index.mdx index e541df27c..cbd392371 100644 --- a/examples/with-mdx/src/pages/index.mdx +++ b/examples/with-mdx/src/pages/index.mdx @@ -1,19 +1,17 @@ -import Counter from '../components/Counter.jsx' -import Title from '../components/Title.astro' -export const components = { h1: Title } +import Counter from '../components/Counter.jsx'; +import Title from '../components/Title.astro'; +export const components = { h1: Title }; # Hello world! export const authors = [ - {name: 'Jane', email: 'hi@jane.com'}, - {name: 'John', twitter: '@john2002'} -] -export const published = new Date('2022-02-01') + { name: 'Jane', email: 'hi@jane.com' }, + { name: 'John', twitter: '@john2002' }, +]; +export const published = new Date('2022-02-01'); Written by: {new Intl.ListFormat('en').format(authors.map(d => d.name))}. Published on: {new Intl.DateTimeFormat('en', {dateStyle: 'long'}).format(published)}. - -## Counter - +## Counter diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 72382e60a..75d63cece 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -939,9 +939,10 @@ export interface SSRLoadedRenderer extends AstroRenderer { }; } -export type HookParameters = Fn extends (...args: any) => any - ? Parameters[0] - : never; +export type HookParameters< + Hook extends keyof AstroIntegration['hooks'], + Fn = AstroIntegration['hooks'][Hook] +> = Fn extends (...args: any) => any ? Parameters[0] : never; export interface AstroIntegration { /** The name of the integration. */ diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts index 05f1b1ae9..0fb41032b 100644 --- a/packages/astro/src/core/config.ts +++ b/packages/astro/src/core/config.ts @@ -346,9 +346,7 @@ export async function validateConfig( adapter: undefined, }, }; - if ( - result.integrations.find((integration) => integration.name === '@astrojs/mdx') - ) { + if (result.integrations.find((integration) => integration.name === '@astrojs/mdx')) { // Enable default JSX integration. It needs to come first, so unshift rather than push! const { default: jsxRenderer } = await import('../jsx/renderer.js'); (result._ctx.renderers as any[]).unshift(jsxRenderer); diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts index f55dbf0cb..37673f7c6 100644 --- a/packages/astro/src/core/create-vite.ts +++ b/packages/astro/src/core/create-vite.ts @@ -140,9 +140,11 @@ function getPluginName(plugin: vite.PluginOption) { function sortPlugins(result: ViteConfigWithSSR) { // HACK: move mdxPlugin to top because it needs to run before internal JSX plugin - const mdxPluginIndex = result.plugins?.findIndex(plugin => getPluginName(plugin) === '@mdx-js/rollup') ?? -1; + const mdxPluginIndex = + result.plugins?.findIndex((plugin) => getPluginName(plugin) === '@mdx-js/rollup') ?? -1; if (mdxPluginIndex === -1) return; - const jsxPluginIndex = result.plugins?.findIndex(plugin => getPluginName(plugin) === 'astro:jsx') ?? -1; + const jsxPluginIndex = + result.plugins?.findIndex((plugin) => getPluginName(plugin) === 'astro:jsx') ?? -1; const mdxPlugin = result.plugins?.[mdxPluginIndex]; result.plugins?.splice(mdxPluginIndex, 1); result.plugins?.splice(jsxPluginIndex, 0, mdxPlugin); diff --git a/packages/astro/src/core/render/core.ts b/packages/astro/src/core/render/core.ts index 6e492ec8c..c4d05ff46 100644 --- a/packages/astro/src/core/render/core.ts +++ b/packages/astro/src/core/render/core.ts @@ -9,7 +9,7 @@ import type { } from '../../@types/astro'; import type { LogOptions } from '../logger/core.js'; -import { renderComponent, renderPage } from '../../runtime/server/index.js'; +import { renderPage } from '../../runtime/server/index.js'; import { getParams } from '../routing/params.js'; import { createResult } from './result.js'; import { callGetStaticPaths, findPathItemByKey, RouteCache } from './route-cache.js'; diff --git a/packages/astro/src/integrations/index.ts b/packages/astro/src/integrations/index.ts index c3064eae9..d13d05d52 100644 --- a/packages/astro/src/integrations/index.ts +++ b/packages/astro/src/integrations/index.ts @@ -2,9 +2,9 @@ import type { AddressInfo } from 'net'; import type { ViteDevServer } from 'vite'; import { AstroConfig, - HookParameters, AstroRenderer, BuildConfig, + HookParameters, RouteData, } from '../@types/astro.js'; import ssgAdapter from '../adapter-ssg/index.js'; @@ -58,9 +58,7 @@ export async function runHookConfigSetup({ }; // Semi-private `addPageExtension` hook function addPageExtension(...input: (string | string[])[]) { - const exts = (input.flat(Infinity) as string[]).map( - (ext) => `.${ext.replace(/^\./, '')}` - ); + const exts = (input.flat(Infinity) as string[]).map((ext) => `.${ext.replace(/^\./, '')}`); updatedConfig._ctx.pageExtensions.push(...exts); } Object.defineProperty(hooks, 'addPageExtension', { diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts index 4a6daf71c..0d660fc94 100644 --- a/packages/astro/src/runtime/server/index.ts +++ b/packages/astro/src/runtime/server/index.ts @@ -166,9 +166,7 @@ function formatList(values: string[]): string { return `${values.slice(0, -1).join(', ')} or ${values[values.length - 1]}`; } -const rendererAliases = new Map([ - ['solid', 'solid-js'] -]) +const rendererAliases = new Map([['solid', 'solid-js']]); export async function renderComponent( result: SSRResult, @@ -283,7 +281,9 @@ Did you mean to add ${formatList(probableRendererNames.map((r) => '`' + r + '`') // Attempt: use explicitly passed renderer name if (metadata.hydrateArgs) { const passedName = metadata.hydrateArgs; - const rendererName = rendererAliases.has(passedName) ? rendererAliases.get(passedName) : passedName; + const rendererName = rendererAliases.has(passedName) + ? rendererAliases.get(passedName) + : passedName; renderer = renderers.filter( ({ name }) => name === `@astrojs/${rendererName}` || name === rendererName )[0]; @@ -709,16 +709,22 @@ export async function renderPage( let iterable: AsyncIterable; if (!componentFactory.isAstroComponentFactory) { const pageProps: Record = { ...(props ?? {}), 'server:root': true }; - const output = await renderComponent(result, componentFactory.name, componentFactory, pageProps, null); - let html = output.toString() + const output = await renderComponent( + result, + componentFactory.name, + componentFactory, + pageProps, + null + ); + let html = output.toString(); if (!/\n${await maybeRenderHead(result)}${html}`; } return new Response(html, { headers: new Headers([ ['Content-Type', 'text/html; charset=utf-8'], - ['Content-Length', `${Buffer.byteLength(html, 'utf-8')}`] - ]) + ['Content-Length', `${Buffer.byteLength(html, 'utf-8')}`], + ]), }); } const factoryReturnValue = await componentFactory(result, props, children); diff --git a/packages/astro/src/runtime/server/jsx.ts b/packages/astro/src/runtime/server/jsx.ts index a62587259..16b4c039b 100644 --- a/packages/astro/src/runtime/server/jsx.ts +++ b/packages/astro/src/runtime/server/jsx.ts @@ -28,13 +28,16 @@ export async function renderJSX(result: any, vnode: any): Promise { let props: Record = {}; let slots: Record = {}; for (const [key, value] of Object.entries(vnode.props ?? {})) { - if (key === 'children' || value && typeof value === 'object' && (value as any)['$$slot']) { + if ( + key === 'children' || + (value && typeof value === 'object' && (value as any)['$$slot']) + ) { slots[key === 'children' ? 'default' : key] = () => renderJSX(result, value); } else { props[key] = value; } } - return await renderToString(result, vnode.type, props, slots) + return await renderToString(result, vnode.type, props, slots); } } if (vnode[AstroJSX]) { diff --git a/packages/astro/src/vite-plugin-jsx/index.ts b/packages/astro/src/vite-plugin-jsx/index.ts index cc28a69b2..5d7883503 100644 --- a/packages/astro/src/vite-plugin-jsx/index.ts +++ b/packages/astro/src/vite-plugin-jsx/index.ts @@ -165,7 +165,6 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin } } - // if no imports were found, look for @jsxImportSource comment if (!importSource) { const multiline = code.match(/\/\*\*?[\S\s]*\*\//gm) || []; diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js index 90511d812..94abd6ef4 100644 --- a/packages/astro/test/test-utils.js +++ b/packages/astro/test/test-utils.js @@ -71,7 +71,7 @@ export async function loadFixture(inlineConfig) { cwd = new URL(cwd.replace(/\/?$/, '/'), import.meta.url); } } - + // Load the config. let config = await loadConfig({ cwd: fileURLToPath(cwd) }); config = merge(config, { ...inlineConfig, root: cwd }); @@ -83,7 +83,7 @@ export async function loadFixture(inlineConfig) { if (inlineConfig.base && !inlineConfig.base.endsWith('/')) { config.base = inlineConfig.base + '/'; } - if (config.integrations.find(integration => integration.name === '@astrojs/mdx')) { + if (config.integrations.find((integration) => integration.name === '@astrojs/mdx')) { // Enable default JSX integration. It needs to come first, so unshift rather than push! const { default: jsxRenderer } = await import('astro/jsx/renderer.js'); config._ctx.renderers.unshift(jsxRenderer); diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts index d07913ede..bd3d50c86 100644 --- a/packages/integrations/mdx/src/index.ts +++ b/packages/integrations/mdx/src/index.ts @@ -1,39 +1,39 @@ -import type { AstroIntegration } from 'astro'; import mdxPlugin from '@mdx-js/rollup'; +import type { AstroIntegration } from 'astro'; export default function mdx(): AstroIntegration { return { - name: '@astrojs/mdx', - hooks: { - 'astro:config:setup': ({ updateConfig, addPageExtension, command }: any) => { - addPageExtension('.mdx'); - updateConfig({ - vite: { - plugins: [ - { - enforce: 'pre', - ...mdxPlugin({ - jsx: true, - jsxImportSource: 'astro', - // Note: disable `.md` support - format: 'mdx', - 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) { + name: '@astrojs/mdx', + hooks: { + 'astro:config:setup': ({ updateConfig, addPageExtension, command }: any) => { + addPageExtension('.mdx'); + updateConfig({ + vite: { + plugins: [ + { + enforce: 'pre', + ...mdxPlugin({ + jsx: true, + jsxImportSource: 'astro', + // Note: disable `.md` support + format: 'mdx', + 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) { import.meta.hot.decline(); - }` - } - } - ] - } - }) - } - } - } + }`; + }, + }, + ], + }, + }); + }, + }, + }; } diff --git a/packages/integrations/mdx/test/mdx-component.test.js b/packages/integrations/mdx/test/mdx-component.test.js index 462e86e7b..1a610be05 100644 --- a/packages/integrations/mdx/test/mdx-component.test.js +++ b/packages/integrations/mdx/test/mdx-component.test.js @@ -1,18 +1,16 @@ import mdx from '@astrojs/mdx'; import { expect } from 'chai'; -import { parseHTML } from 'linkedom' +import { parseHTML } from 'linkedom'; import { loadFixture } from '../../../astro/test/test-utils.js'; describe('MDX Component', () => { let fixture; - + before(async () => { - fixture = await loadFixture({ + fixture = await loadFixture({ root: new URL('./fixtures/mdx-component/', import.meta.url), - integrations: [ - mdx() - ] + integrations: [mdx()], }); }); @@ -21,22 +19,21 @@ describe('MDX Component', () => { await fixture.build(); }); - it('works', async () => { const html = await fixture.readFile('/index.html'); const { document } = parseHTML(html); - + const h1 = document.querySelector('h1'); const foo = document.querySelector('#foo'); expect(h1.textContent).to.equal('Hello component!'); expect(foo.textContent).to.equal('bar'); }); - }) + }); describe('dev', () => { let devServer; - + before(async () => { devServer = await fixture.startDevServer(); }); @@ -52,12 +49,12 @@ describe('MDX Component', () => { const html = await res.text(); const { document } = parseHTML(html); - + const h1 = document.querySelector('h1'); const foo = document.querySelector('#foo'); expect(h1.textContent).to.equal('Hello component!'); expect(foo.textContent).to.equal('bar'); }); - }) -}) + }); +}); diff --git a/packages/integrations/mdx/test/mdx-page.test.js b/packages/integrations/mdx/test/mdx-page.test.js index 6e4ae79af..e375a9f17 100644 --- a/packages/integrations/mdx/test/mdx-page.test.js +++ b/packages/integrations/mdx/test/mdx-page.test.js @@ -1,18 +1,16 @@ import mdx from '@astrojs/mdx'; import { expect } from 'chai'; -import { parseHTML } from 'linkedom' +import { parseHTML } from 'linkedom'; import { loadFixture } from '../../../astro/test/test-utils.js'; describe('MDX Page', () => { let fixture; before(async () => { - fixture = await loadFixture({ + fixture = await loadFixture({ root: new URL('./fixtures/mdx-page/', import.meta.url), - integrations: [ - mdx() - ] + integrations: [mdx()], }); }); @@ -21,20 +19,19 @@ describe('MDX Page', () => { await fixture.build(); }); - it('works', async () => { const html = await fixture.readFile('/index.html'); const { document } = parseHTML(html); - + const h1 = document.querySelector('h1'); expect(h1.textContent).to.equal('Hello page!'); }); - }) + }); describe('dev', () => { let devServer; - + before(async () => { devServer = await fixture.startDevServer(); }); @@ -45,15 +42,15 @@ describe('MDX Page', () => { it('works', async () => { const res = await fixture.fetch('/'); - + expect(res.status).to.equal(200); const html = await res.text(); const { document } = parseHTML(html); - + const h1 = document.querySelector('h1'); expect(h1.textContent).to.equal('Hello page!'); }); - }) -}) + }); +});