MDX support (#3706)
* feat: first pass at MDX support * fix: move built-in JSX renderer to come first * chore: remove jsx example * chore: update lockfile * chore: cleanup example * fix: missing deps * refactor: move component render logic to `renderPage` * chore: update HMR script * chore: update MDX example * refactor: prefer unshit * refactor: remove TODO comment * fix: remove duplicate identifier * refactor: cleanup mdx entrypoint * fix: better html handling * fix: add tsconfig to mdx package * chore: update lockfile * fix: do not sort plugins unless mdx is enabled * chore: update compiler * fix(hmr): maybe render head for non-Astro pages * fix: set initial pageExtensions * refactor: cleanup addPageExtension * refactor: remove addPageExtensions from types * refactor: expose HookParameters type * fix: only default to astro for MDX * test: pick up jsx support in test fixtures * refactor: simplify mdx entrypoint * test: add basic MDX tests * test(e2e): add mdx + framework tests * chore: update lockfile * test(e2e): fix preact mdx e2e test * fix(mdx): disable .md support * test(e2e): fix vue-component test missing mdx * test(e2e): fix solid component needing import * fix: allow `client:only="solid"` as an alias to `solid-js` * chore: move to with-mdx example * chore: update MDX readme * chore: update example readme * chore: bump astro version * chore: update lockfile * Update mod.d.ts * feat: support `export const components` in MDX pages * chore: update mdx example * fix: update jsx-runtime with better slot support * refactor: remove object style support * chore: cleanup package exports * chore: add todo comment * refactor: improve isPage function, move to utils * refactor: dry up manual HMR updates * chore: add dev tests for MDX * chore: prefer set to array * chore: add changesets * fix(hmr): flip public/private route Co-authored-by: Nate Moore <nate@astro.build>
This commit is contained in:
parent
91635f05df
commit
032ad1c047
63 changed files with 1153 additions and 57 deletions
5
.changeset/selfish-beers-dance.md
Normal file
5
.changeset/selfish-beers-dance.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Internal changes needed to support `@astrojs/mdx`
|
5
.changeset/shaggy-gifts-admire.md
Normal file
5
.changeset/shaggy-gifts-admire.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/mdx': patch
|
||||
---
|
||||
|
||||
Initial release! 🎉
|
19
examples/with-mdx/.gitignore
vendored
Normal file
19
examples/with-mdx/.gitignore
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
# build output
|
||||
dist/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
2
examples/with-mdx/.npmrc
Normal file
2
examples/with-mdx/.npmrc
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Expose Astro dependencies for `pnpm` users
|
||||
shamefully-hoist=true
|
6
examples/with-mdx/.stackblitzrc
Normal file
6
examples/with-mdx/.stackblitzrc
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"startCommand": "npm start",
|
||||
"env": {
|
||||
"ENABLE_CJS_IMPORTS": true
|
||||
}
|
||||
}
|
4
examples/with-mdx/.vscode/extensions.json
vendored
Normal file
4
examples/with-mdx/.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"recommendations": ["astro-build.astro-vscode"],
|
||||
"unwantedRecommendations": []
|
||||
}
|
11
examples/with-mdx/.vscode/launch.json
vendored
Normal file
11
examples/with-mdx/.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"command": "./node_modules/.bin/astro dev",
|
||||
"name": "Development server",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
}
|
||||
]
|
||||
}
|
9
examples/with-mdx/README.md
Normal file
9
examples/with-mdx/README.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Astro Example: MDX
|
||||
|
||||
```
|
||||
npm init astro -- --template with-mdx
|
||||
```
|
||||
|
||||
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/with-mdx)
|
||||
|
||||
This example showcases using [`@astrojs/mdx`](https://www.npmjs.com/package/@astrojs/mdx) to author content using [MDX](https://mdxjs.com/).
|
11
examples/with-mdx/astro.config.mjs
Normal file
11
examples/with-mdx/astro.config.mjs
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import mdx from '@astrojs/mdx';
|
||||
import preact from '@astrojs/preact';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
mdx(),
|
||||
preact()
|
||||
]
|
||||
});
|
17
examples/with-mdx/package.json
Normal file
17
examples/with-mdx/package.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "@example/with-mdx",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/mdx": "^0.0.1",
|
||||
"@astrojs/preact": "^0.2.0",
|
||||
"astro": "^1.0.0-beta.58",
|
||||
"preact": "^10.6.5"
|
||||
}
|
||||
}
|
BIN
examples/with-mdx/public/favicon.ico
Normal file
BIN
examples/with-mdx/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
11
examples/with-mdx/sandbox.config.json
Normal file
11
examples/with-mdx/sandbox.config.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"infiniteLoopProtection": true,
|
||||
"hardReloadOnChange": false,
|
||||
"view": "browser",
|
||||
"template": "node",
|
||||
"container": {
|
||||
"port": 3000,
|
||||
"startScript": "start",
|
||||
"node": "14"
|
||||
}
|
||||
}
|
18
examples/with-mdx/src/components/Counter.jsx
Normal file
18
examples/with-mdx/src/components/Counter.jsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { useState } from 'preact/hooks';
|
||||
|
||||
export default function Counter({ children }) {
|
||||
const [count, setCount] = useState(0);
|
||||
const add = () => setCount((i) => i + 1);
|
||||
const subtract = () => setCount((i) => i - 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="counter">
|
||||
<button onClick={subtract}>-</button>
|
||||
<pre>{count}</pre>
|
||||
<button onClick={add}>+</button>
|
||||
</div>
|
||||
<div class="counter-message">{children}</div>
|
||||
</>
|
||||
);
|
||||
}
|
7
examples/with-mdx/src/components/Title.astro
Normal file
7
examples/with-mdx/src/components/Title.astro
Normal file
|
@ -0,0 +1,7 @@
|
|||
<h1><slot /></h1>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
19
examples/with-mdx/src/pages/index.mdx
Normal file
19
examples/with-mdx/src/pages/index.mdx
Normal file
|
@ -0,0 +1,19 @@
|
|||
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')
|
||||
|
||||
Written by: {new Intl.ListFormat('en').format(authors.map(d => d.name))}.
|
||||
|
||||
Published on: {new Intl.DateTimeFormat('en', {dateStyle: 'long'}).format(published)}.
|
||||
|
||||
<Counter client:idle>
|
||||
## Counter
|
||||
</Counter>
|
15
examples/with-mdx/tsconfig.json
Normal file
15
examples/with-mdx/tsconfig.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
// Enable top-level await, and other modern ESM features.
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
// Enable node-style module resolution, for things like npm package imports.
|
||||
"moduleResolution": "node",
|
||||
// Enable JSON imports.
|
||||
"resolveJsonModule": true,
|
||||
// Enable stricter transpilation for better output.
|
||||
"isolatedModules": true,
|
||||
// Add type definitions for our Vite runtime.
|
||||
"types": ["vite/client"]
|
||||
}
|
||||
}
|
|
@ -50,6 +50,7 @@
|
|||
"pnpm": {
|
||||
"peerDependencyRules": {
|
||||
"ignoreMissing": [
|
||||
"rollup",
|
||||
"@babel/core",
|
||||
"@babel/plugin-transform-react-jsx",
|
||||
"vite"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import preact from '@astrojs/preact';
|
||||
import mdx from '@astrojs/mdx';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [preact()],
|
||||
integrations: [preact(), mdx()],
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "workspace:*",
|
||||
"@astrojs/mdx": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"preact": "^10.7.3"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
import Counter from '../components/Counter.jsx';
|
||||
import PreactComponent from '../components/JSXComponent.jsx';
|
||||
|
||||
export const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
|
||||
<Counter id="server-only" {...someProps}>
|
||||
# Hello, server!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" {...someProps} client:idle>
|
||||
# Hello, client:idle!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" {...someProps} client:load>
|
||||
# Hello, client:load!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" {...someProps} client:visible>
|
||||
# Hello, client:visible!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
# Hello, client:media!
|
||||
</Counter>
|
||||
|
||||
<PreactComponent id="client-only" client:only="preact" />
|
|
@ -1,7 +1,8 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import react from '@astrojs/react';
|
||||
import mdx from '@astrojs/mdx';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [react()],
|
||||
integrations: [react(), mdx()],
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"dependencies": {
|
||||
"@astrojs/react": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/mdx": "workspace:*",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import Counter from '../components/Counter.jsx';
|
||||
import ReactComponent from '../components/JSXComponent.jsx';
|
||||
|
||||
export const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
|
||||
<Counter id="server-only" {...someProps}>
|
||||
# Hello, server!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" {...someProps} client:idle>
|
||||
# Hello, client:idle!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" {...someProps} client:load>
|
||||
# Hello, client:load!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" {...someProps} client:visible>
|
||||
# Hello, client:visible!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
# Hello, client:media!
|
||||
</Counter>
|
||||
|
||||
<ReactComponent id="client-only" client:only="react" />
|
|
@ -1,7 +1,8 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import mdx from '@astrojs/mdx';
|
||||
import solid from '@astrojs/solid-js';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [solid()],
|
||||
integrations: [solid(), mdx()],
|
||||
});
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/solid-js": "workspace:*",
|
||||
"astro": "workspace:*"
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/mdx": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"solid-js": "^1.4.3"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'solid-js';
|
||||
|
||||
export default function SolidComponent({ id }) {
|
||||
return (
|
||||
<div id={id}>Framework client:only component</div>
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import Counter from '../components/Counter.jsx';
|
||||
import SolidComponent from '../components/SolidComponent.jsx';
|
||||
|
||||
export const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
|
||||
<Counter id="server-only" {...someProps}>
|
||||
# Hello, server!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" {...someProps} client:idle>
|
||||
# Hello, client:idle!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" {...someProps} client:load>
|
||||
# Hello, client:load!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" {...someProps} client:visible>
|
||||
# Hello, client:visible!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
# Hello, client:media!
|
||||
</Counter>
|
||||
|
||||
<SolidComponent id="client-only" client:only="solid" />
|
|
@ -1,7 +1,8 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import svelte from '@astrojs/svelte';
|
||||
import mdx from '@astrojs/mdx';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [svelte()],
|
||||
integrations: [svelte(), mdx()],
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"dependencies": {
|
||||
"@astrojs/svelte": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/mdx": "workspace:*",
|
||||
"svelte": "^3.48.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import Counter from '../components/Counter.svelte';
|
||||
import SvelteComponent from '../components/SvelteComponent.svelte';
|
||||
|
||||
export const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
|
||||
<Counter id="server-only" {...someProps}>
|
||||
# Hello, server!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" {...someProps} client:idle>
|
||||
# Hello, client:idle!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" {...someProps} client:load>
|
||||
# Hello, client:load!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" {...someProps} client:visible>
|
||||
# Hello, client:visible!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
# Hello, client:media!
|
||||
</Counter>
|
||||
|
||||
<SvelteComponent id="client-only" client:only="svelte" />
|
|
@ -1,13 +1,17 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import vue from '@astrojs/vue';
|
||||
import mdx from '@astrojs/mdx';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [vue({
|
||||
integrations: [
|
||||
mdx(),
|
||||
vue({
|
||||
template: {
|
||||
compilerOptions: {
|
||||
isCustomElement: tag => tag.includes('my-button')
|
||||
}
|
||||
}
|
||||
})],
|
||||
}
|
||||
)],
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*"
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/mdx": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
|
28
packages/astro/e2e/fixtures/vue-component/src/pages/mdx.mdx
Normal file
28
packages/astro/e2e/fixtures/vue-component/src/pages/mdx.mdx
Normal file
|
@ -0,0 +1,28 @@
|
|||
import Counter from '../components/Counter.vue';
|
||||
import VueComponent from '../components/VueComponent.vue';
|
||||
|
||||
export const someProps = {
|
||||
count: 0,
|
||||
};
|
||||
|
||||
<Counter id="server-only" {...someProps}>
|
||||
# Hello, server!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-idle" {...someProps} client:idle>
|
||||
# Hello, client:idle!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-load" {...someProps} client:load>
|
||||
# Hello, client:load!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-visible" {...someProps} client:visible>
|
||||
# Hello, client:visible!
|
||||
</Counter>
|
||||
|
||||
<Counter id="client-media" {...someProps} client:media="(max-width: 50em)">
|
||||
# Hello, client:media!
|
||||
</Counter>
|
||||
|
||||
<VueComponent id="client-only" client:only="vue" />
|
|
@ -17,3 +17,11 @@ test.describe('Preact components in Markdown files', () => {
|
|||
componentFilePath: './src/components/JSXComponent.jsx',
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Preact components in MDX files', () => {
|
||||
createTests({
|
||||
pageUrl: '/mdx/',
|
||||
pageSourceFilePath: './src/pages/mdx.mdx',
|
||||
componentFilePath: './src/components/JSXComponent.jsx',
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,3 +17,11 @@ test.describe('React components in Markdown files', () => {
|
|||
componentFilePath: './src/components/JSXComponent.jsx',
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('React components in MDX files', () => {
|
||||
createTests({
|
||||
pageUrl: '/mdx/',
|
||||
pageSourceFilePath: './src/pages/mdx.mdx',
|
||||
componentFilePath: './src/components/JSXComponent.jsx',
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,3 +17,11 @@ test.describe('Solid components in Markdown files', () => {
|
|||
componentFilePath: './src/components/SolidComponent.jsx',
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Solid components in MDX files', () => {
|
||||
createTests({
|
||||
pageUrl: '/mdx/',
|
||||
pageSourceFilePath: './src/pages/mdx.mdx',
|
||||
componentFilePath: './src/components/SolidComponent.jsx',
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,3 +19,12 @@ test.describe('Svelte components in Markdown files', () => {
|
|||
counterCssFilePath: './src/components/Counter.svelte',
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Svelte components in MDX files', () => {
|
||||
createTests({
|
||||
pageUrl: '/mdx/',
|
||||
pageSourceFilePath: './src/pages/mdx.mdx',
|
||||
componentFilePath: './src/components/SvelteComponent.svelte',
|
||||
counterCssFilePath: './src/components/Counter.svelte',
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,3 +19,12 @@ test.describe('Vue components in Markdown files', () => {
|
|||
counterCssFilePath: './src/components/Counter.vue',
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Vue components in MDX files', () => {
|
||||
createTests({
|
||||
pageUrl: '/mdx/',
|
||||
pageSourceFilePath: './src/pages/mdx.mdx',
|
||||
componentFilePath: './src/components/VueComponent.vue',
|
||||
counterCssFilePath: './src/components/Counter.vue',
|
||||
});
|
||||
});
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
"test:e2e:match": "playwright test -g"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/compiler": "^0.17.0",
|
||||
"@astrojs/compiler": "^0.17.1",
|
||||
"@astrojs/language-server": "^0.13.4",
|
||||
"@astrojs/markdown-remark": "^0.11.3",
|
||||
"@astrojs/prism": "0.4.1",
|
||||
|
|
|
@ -939,6 +939,10 @@ export interface SSRLoadedRenderer extends AstroRenderer {
|
|||
};
|
||||
}
|
||||
|
||||
export type HookParameters<Hook extends keyof AstroIntegration['hooks'], Fn = AstroIntegration['hooks'][Hook]> = Fn extends (...args: any) => any
|
||||
? Parameters<Fn>[0]
|
||||
: never;
|
||||
|
||||
export interface AstroIntegration {
|
||||
/** The name of the integration. */
|
||||
name: string;
|
||||
|
@ -955,7 +959,7 @@ export interface AstroIntegration {
|
|||
// This may require some refactoring of `scripts`, `styles`, and `links` into something
|
||||
// more generalized. Consider the SSR use-case as well.
|
||||
// injectElement: (stage: vite.HtmlTagDescriptor, element: string) => void;
|
||||
}) => void;
|
||||
}) => void | Promise<void>;
|
||||
'astro:config:done'?: (options: {
|
||||
config: AstroConfig;
|
||||
setAdapter: (adapter: AstroAdapter) => void;
|
||||
|
|
|
@ -339,7 +339,7 @@ export async function validateConfig(
|
|||
const result = {
|
||||
...(await AstroConfigRelativeSchema.parseAsync(userConfig)),
|
||||
_ctx: {
|
||||
pageExtensions: [],
|
||||
pageExtensions: ['.astro', '.md'],
|
||||
scripts: [],
|
||||
renderers: [],
|
||||
injectedRoutes: [],
|
||||
|
@ -347,12 +347,11 @@ export async function validateConfig(
|
|||
},
|
||||
};
|
||||
if (
|
||||
// TODO: expose @astrojs/mdx package
|
||||
result.integrations.find((integration) => integration.name === '@astrojs/mdx')
|
||||
) {
|
||||
// Enable default JSX integration
|
||||
// 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[]).push(jsxRenderer);
|
||||
(result._ctx.renderers as any[]).unshift(jsxRenderer);
|
||||
}
|
||||
|
||||
// Final-Pass Validation (perform checks that require the full config object)
|
||||
|
|
|
@ -128,9 +128,26 @@ export async function createVite(
|
|||
let result = commonConfig;
|
||||
result = vite.mergeConfig(result, astroConfig.vite || {});
|
||||
result = vite.mergeConfig(result, commandConfig);
|
||||
sortPlugins(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function getPluginName(plugin: vite.PluginOption) {
|
||||
if (plugin && typeof plugin === 'object' && !Array.isArray(plugin)) {
|
||||
return plugin.name;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
if (mdxPluginIndex === -1) return;
|
||||
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);
|
||||
}
|
||||
|
||||
// Scans `projectRoot` for third-party Astro packages that could export an `.astro` file
|
||||
// `.astro` files need to be built by Vite, so these should use `noExternal`
|
||||
async function getAstroPackages({ root }: AstroConfig): Promise<string[]> {
|
||||
|
|
|
@ -140,11 +140,10 @@ export async function render(opts: RenderOptions): Promise<Response> {
|
|||
ssr,
|
||||
});
|
||||
|
||||
if (!Component.isAstroComponentFactory) {
|
||||
const props: Record<string, any> = { ...(pageProps ?? {}), 'server:root': true };
|
||||
const html = await renderComponent(result, Component.name, Component, props, null);
|
||||
return new Response(html.toString(), result.response);
|
||||
} else {
|
||||
// Support `export const components` for `MDX` pages
|
||||
if (typeof (mod as any).components === 'object') {
|
||||
Object.assign(pageProps, { components: (mod as any).components });
|
||||
}
|
||||
|
||||
return await renderPage(result, Component, pageProps, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import type {
|
|||
} from '../../../@types/astro';
|
||||
import { prependForwardSlash } from '../../../core/path.js';
|
||||
import { LogOptions } from '../../logger/core.js';
|
||||
import { isBuildingToSSR } from '../../util.js';
|
||||
import { isBuildingToSSR, isPage } from '../../util.js';
|
||||
import { render as coreRender } from '../core.js';
|
||||
import { RouteCache } from '../route-cache.js';
|
||||
import { createModuleScriptElementWithSrcSet } from '../ssr-element.js';
|
||||
|
@ -113,7 +113,7 @@ export async function render(
|
|||
);
|
||||
|
||||
// Inject HMR scripts
|
||||
if (mod.hasOwnProperty('$$metadata') && mode === 'development') {
|
||||
if (isPage(filePath, astroConfig) && mode === 'development') {
|
||||
scripts.add({
|
||||
props: { type: 'module', src: '/@vite/client' },
|
||||
children: '',
|
||||
|
|
|
@ -152,6 +152,33 @@ export function resolvePages(config: AstroConfig) {
|
|||
return new URL('./pages', config.srcDir);
|
||||
}
|
||||
|
||||
function isInPagesDir(file: URL, config: AstroConfig): boolean {
|
||||
const pagesDir = resolvePages(config);
|
||||
return file.toString().startsWith(pagesDir.toString());
|
||||
}
|
||||
|
||||
function isPublicRoute(file: URL, config: AstroConfig): boolean {
|
||||
const pagesDir = resolvePages(config);
|
||||
const parts = file.toString().replace(pagesDir.toString(), '').split('/').slice(1);
|
||||
for (const part of parts) {
|
||||
if (part.startsWith('_')) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function endsWithPageExt(file: URL, config: AstroConfig): boolean {
|
||||
for (const ext of config._ctx.pageExtensions) {
|
||||
if (file.toString().endsWith(ext)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isPage(file: URL, config: AstroConfig): boolean {
|
||||
if (!isInPagesDir(file, config)) return false;
|
||||
if (!isPublicRoute(file, config)) return false;
|
||||
return endsWithPageExt(file, config);
|
||||
}
|
||||
|
||||
export function isBuildingToSSR(config: AstroConfig): boolean {
|
||||
const adapter = config._ctx.adapter;
|
||||
if (!adapter) return false;
|
||||
|
|
|
@ -2,7 +2,7 @@ import type { AddressInfo } from 'net';
|
|||
import type { ViteDevServer } from 'vite';
|
||||
import {
|
||||
AstroConfig,
|
||||
AstroIntegration,
|
||||
HookParameters,
|
||||
AstroRenderer,
|
||||
BuildConfig,
|
||||
RouteData,
|
||||
|
@ -14,11 +14,6 @@ import { mergeConfig } from '../core/config.js';
|
|||
import type { ViteConfigWithSSR } from '../core/create-vite.js';
|
||||
import { isBuildingToSSR } from '../core/util.js';
|
||||
|
||||
type Hooks<
|
||||
Hook extends keyof AstroIntegration['hooks'],
|
||||
Fn = AstroIntegration['hooks'][Hook]
|
||||
> = Fn extends (...args: any) => any ? Parameters<Fn>[0] : never;
|
||||
|
||||
export async function runHookConfigSetup({
|
||||
config: _config,
|
||||
command,
|
||||
|
@ -45,7 +40,7 @@ export async function runHookConfigSetup({
|
|||
* ```
|
||||
*/
|
||||
if (integration?.hooks?.['astro:config:setup']) {
|
||||
const hooks: Hooks<'astro:config:setup'> = {
|
||||
const hooks: HookParameters<'astro:config:setup'> = {
|
||||
config: updatedConfig,
|
||||
command,
|
||||
addRenderer(renderer: AstroRenderer) {
|
||||
|
@ -62,13 +57,14 @@ export async function runHookConfigSetup({
|
|||
},
|
||||
};
|
||||
// Semi-private `addPageExtension` hook
|
||||
Object.defineProperty(hooks, 'addPageExtension', {
|
||||
value: (...input: (string | string[])[]) => {
|
||||
function addPageExtension(...input: (string | string[])[]) {
|
||||
const exts = (input.flat(Infinity) as string[]).map(
|
||||
(ext) => `.${ext.replace(/^\./, '')}`
|
||||
);
|
||||
updatedConfig._ctx.pageExtensions.push(...exts);
|
||||
},
|
||||
}
|
||||
Object.defineProperty(hooks, 'addPageExtension', {
|
||||
value: addPageExtension,
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
});
|
||||
|
|
|
@ -17,8 +17,20 @@ export function isVNode(vnode: any): vnode is AstroVNode {
|
|||
|
||||
export function transformSlots(vnode: AstroVNode) {
|
||||
if (typeof vnode.type === 'string') return vnode;
|
||||
if (!Array.isArray(vnode.props.children)) return;
|
||||
// Handle single child with slot attribute
|
||||
const slots: Record<string, any> = {};
|
||||
if (isVNode(vnode.props.children)) {
|
||||
const child = vnode.props.children;
|
||||
if (!isVNode(child)) return;
|
||||
if (!('slot' in child.props)) return;
|
||||
const name = toSlotName(child.props.slot);
|
||||
slots[name] = [child];
|
||||
slots[name]['$$slot'] = true;
|
||||
delete child.props.slot;
|
||||
delete vnode.props.children;
|
||||
}
|
||||
if (!Array.isArray(vnode.props.children)) return;
|
||||
// Handle many children with slot attributes
|
||||
vnode.props.children = vnode.props.children
|
||||
.map((child) => {
|
||||
if (!isVNode(child)) return child;
|
||||
|
@ -28,6 +40,7 @@ export function transformSlots(vnode: AstroVNode) {
|
|||
slots[name].push(child);
|
||||
} else {
|
||||
slots[name] = [child];
|
||||
slots[name]['$$slot'] = true;
|
||||
}
|
||||
delete child.props.slot;
|
||||
return Empty;
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
if (import.meta.hot) {
|
||||
import.meta.hot.accept((mod) => mod);
|
||||
|
||||
const parser = new DOMParser();
|
||||
|
||||
const KNOWN_MANUAL_HMR_EXTENSIONS = new Set(['.astro', '.md', '.mdx']);
|
||||
function needsManualHMR(path: string) {
|
||||
for (const ext of KNOWN_MANUAL_HMR_EXTENSIONS.values()) {
|
||||
if (path.endsWith(ext)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async function updatePage() {
|
||||
const { default: diff } = await import('micromorph');
|
||||
const html = await fetch(`${window.location}`).then((res) => res.text());
|
||||
|
@ -35,11 +45,11 @@ if (import.meta.hot) {
|
|||
});
|
||||
}
|
||||
async function updateAll(files: any[]) {
|
||||
let hasAstroUpdate = false;
|
||||
let hasManualUpdate = false;
|
||||
let styles = [];
|
||||
for (const file of files) {
|
||||
if (file.acceptedPath.endsWith('.astro')) {
|
||||
hasAstroUpdate = true;
|
||||
if (needsManualHMR(file.acceptedPath)) {
|
||||
hasManualUpdate = true;
|
||||
continue;
|
||||
}
|
||||
if (file.acceptedPath.includes('svelte&type=style')) {
|
||||
|
@ -72,7 +82,7 @@ if (import.meta.hot) {
|
|||
updateStyle(id, content);
|
||||
}
|
||||
}
|
||||
if (hasAstroUpdate) {
|
||||
if (hasManualUpdate) {
|
||||
return await updatePage();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,6 +166,10 @@ function formatList(values: string[]): string {
|
|||
return `${values.slice(0, -1).join(', ')} or ${values[values.length - 1]}`;
|
||||
}
|
||||
|
||||
const rendererAliases = new Map([
|
||||
['solid', 'solid-js']
|
||||
])
|
||||
|
||||
export async function renderComponent(
|
||||
result: SSRResult,
|
||||
displayName: string,
|
||||
|
@ -278,7 +282,8 @@ Did you mean to add ${formatList(probableRendererNames.map((r) => '`' + r + '`')
|
|||
} else {
|
||||
// Attempt: use explicitly passed renderer name
|
||||
if (metadata.hydrateArgs) {
|
||||
const rendererName = metadata.hydrateArgs;
|
||||
const passedName = metadata.hydrateArgs;
|
||||
const rendererName = rendererAliases.has(passedName) ? rendererAliases.get(passedName) : passedName;
|
||||
renderer = renderers.filter(
|
||||
({ name }) => name === `@astrojs/${rendererName}` || name === rendererName
|
||||
)[0];
|
||||
|
@ -701,10 +706,25 @@ export async function renderPage(
|
|||
props: any,
|
||||
children: any
|
||||
): Promise<Response> {
|
||||
let iterable: AsyncIterable<any>;
|
||||
if (!componentFactory.isAstroComponentFactory) {
|
||||
const pageProps: Record<string, any> = { ...(props ?? {}), 'server:root': true };
|
||||
const output = await renderComponent(result, componentFactory.name, componentFactory, pageProps, null);
|
||||
let html = output.toString()
|
||||
if (!/<!doctype html/i.test(html)) {
|
||||
html = `<!DOCTYPE html>\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')}`]
|
||||
])
|
||||
});
|
||||
}
|
||||
const factoryReturnValue = await componentFactory(result, props, children);
|
||||
|
||||
if (isAstroComponent(factoryReturnValue)) {
|
||||
let iterable = renderAstroComponent(factoryReturnValue);
|
||||
iterable = renderAstroComponent(factoryReturnValue);
|
||||
let stream = new ReadableStream({
|
||||
start(controller) {
|
||||
async function read() {
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
HTMLString,
|
||||
markHTMLString,
|
||||
renderComponent,
|
||||
renderToString,
|
||||
spreadAttributes,
|
||||
voidElementNames,
|
||||
} from './index.js';
|
||||
|
@ -23,6 +24,18 @@ export async function renderJSX(result: any, vnode: any): Promise<any> {
|
|||
return markHTMLString(
|
||||
(await Promise.all(vnode.map((v: any) => renderJSX(result, v)))).join('')
|
||||
);
|
||||
case vnode.type.isAstroComponentFactory: {
|
||||
let props: Record<string, any> = {};
|
||||
let slots: Record<string, any> = {};
|
||||
for (const [key, value] of Object.entries(vnode.props ?? {})) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
if (vnode[AstroJSX]) {
|
||||
if (!vnode.type && vnode.type !== 0) return '';
|
||||
|
|
|
@ -12,11 +12,11 @@ import { error } from '../core/logger/core.js';
|
|||
import { parseNpmName } from '../core/util.js';
|
||||
|
||||
const JSX_RENDERER_CACHE = new WeakMap<AstroConfig, Map<string, AstroRenderer>>();
|
||||
const JSX_EXTENSIONS = new Set(['.jsx', '.tsx']);
|
||||
const JSX_EXTENSIONS = new Set(['.jsx', '.tsx', '.mdx']);
|
||||
const IMPORT_STATEMENTS: Record<string, string> = {
|
||||
react: "import React from 'react'",
|
||||
preact: "import { h } from 'preact'",
|
||||
'solid-js': "import 'solid-js/web'",
|
||||
'solid-js': "import 'solid-js'",
|
||||
astro: "import 'astro/jsx-runtime'",
|
||||
};
|
||||
|
||||
|
@ -26,6 +26,7 @@ const IMPORT_STATEMENTS: Record<string, string> = {
|
|||
const PREVENT_UNUSED_IMPORTS = ';;(React,Fragment,h);';
|
||||
|
||||
function getEsbuildLoader(fileExt: string): string {
|
||||
if (fileExt === '.mdx') return 'jsx';
|
||||
return fileExt.slice(1);
|
||||
}
|
||||
|
||||
|
@ -164,9 +165,10 @@ 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) || [];
|
||||
const multiline = code.match(/\/\*\*?[\S\s]*\*\//gm) || [];
|
||||
for (const comment of multiline) {
|
||||
const [_, lib] = comment.slice(0, -2).match(/@jsxImportSource\s*(\S+)/) || [];
|
||||
if (lib) {
|
||||
|
@ -176,6 +178,10 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin
|
|||
}
|
||||
}
|
||||
|
||||
if (!importSource && jsxRenderers.has('astro') && id.includes('.mdx')) {
|
||||
importSource = 'astro';
|
||||
}
|
||||
|
||||
// if JSX renderer found, then use that
|
||||
if (importSource) {
|
||||
const jsxRenderer = jsxRenderers.get(importSource);
|
||||
|
|
|
@ -2,7 +2,7 @@ import { execa } from 'execa';
|
|||
import { polyfill } from '@astrojs/webapi';
|
||||
import fs from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { resolveConfig, loadConfig } from '../dist/core/config.js';
|
||||
import { loadConfig } from '../dist/core/config.js';
|
||||
import dev from '../dist/core/dev/index.js';
|
||||
import build from '../dist/core/build/index.js';
|
||||
import preview from '../dist/core/preview/index.js';
|
||||
|
@ -71,17 +71,23 @@ 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 });
|
||||
|
||||
// Note: the inline config doesn't run through config validation where these normalizations usually occur
|
||||
// HACK: the inline config doesn't run through config validation where these normalizations usually occur
|
||||
if (typeof inlineConfig.site === 'string') {
|
||||
config.site = new URL(inlineConfig.site);
|
||||
}
|
||||
if (inlineConfig.base && !inlineConfig.base.endsWith('/')) {
|
||||
config.base = inlineConfig.base + '/';
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/** @type {import('../src/core/logger/core').LogOptions} */
|
||||
const logging = {
|
||||
|
|
106
packages/integrations/mdx/README.md
Normal file
106
packages/integrations/mdx/README.md
Normal file
|
@ -0,0 +1,106 @@
|
|||
# @astrojs/mdx 📝
|
||||
|
||||
This **[Astro integration][astro-integration]** enables the usage of [MDX](https://mdxjs.com/) components and allows you to create pages as `.mdx` files.
|
||||
|
||||
- <strong>[Why MDX?](#why-mdx)</strong>
|
||||
- <strong>[Installation](#installation)</strong>
|
||||
- <strong>[Usage](#usage)</strong>
|
||||
- <strong>[Configuration](#configuration)</strong>
|
||||
- <strong>[Examples](#examples)</strong>
|
||||
- <strong>[Troubleshooting](#troubleshooting)</strong>
|
||||
- <strong>[Contributing](#contributing)</strong>
|
||||
- <strong>[Changelog](#changelog)</strong>
|
||||
|
||||
## Why MDX?
|
||||
|
||||
MDX is the defacto solution for embedding components, such as interactive charts or alerts, within Markdown content. If you have existing content authored in MDX, this integration makes migrating to Astro a breeze.
|
||||
|
||||
**Want to learn more about MDX before using this integration?**
|
||||
Check out [“What is MDX?”](https://mdxjs.com/docs/what-is-mdx/), a deep-dive on the MDX format.
|
||||
|
||||
## Installation
|
||||
|
||||
<details>
|
||||
<summary>Quick Install</summary>
|
||||
<br/>
|
||||
|
||||
The `astro add` command-line tool automates the installation for you. Run one of the following commands in a new terminal window. (If you aren't sure which package manager you're using, run the first command.) Then, follow the prompts, and type "y" in the terminal (meaning "yes") for each one.
|
||||
|
||||
```sh
|
||||
# Using NPM
|
||||
npx astro add mdx
|
||||
# Using Yarn
|
||||
yarn astro add mdx
|
||||
# Using PNPM
|
||||
pnpx astro add mdx
|
||||
```
|
||||
|
||||
Then, restart the dev server by typing `CTRL-C` and then `npm run astro dev` in the terminal window that was running Astro.
|
||||
|
||||
Because this command is new, it might not properly set things up. If that happens, [feel free to log an issue on our GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Manual Install</summary>
|
||||
<br/>
|
||||
|
||||
First, install the `@astrojs/mdx` package using your package manager. If you're using npm or aren't sure, run this in the terminal:
|
||||
|
||||
```
|
||||
npm install @astrojs/mdx
|
||||
```
|
||||
|
||||
Then, apply this integration to your `astro.config.*` file using the `integrations` property:
|
||||
|
||||
__astro.config.mjs__
|
||||
|
||||
```js
|
||||
import { defineConfig } from 'astro/config';
|
||||
import mdx from '@astrojs/mdx';
|
||||
|
||||
export default defineConfig({
|
||||
// ...
|
||||
integrations: [mdx()],
|
||||
});
|
||||
```
|
||||
|
||||
Finally, restart the dev server.
|
||||
</details>
|
||||
|
||||
## Usage
|
||||
|
||||
To write your first MDX page in Astro, head to our [UI framework documentation][astro-ui-frameworks]. You'll explore:
|
||||
- 📦 how framework components are loaded,
|
||||
- 💧 client-side hydration options, and
|
||||
- 🪆 opportunities to mix and nest frameworks together
|
||||
|
||||
[**Client Directives**](https://docs.astro.build/en/reference/directives-reference/#client-directives) are still required in `.mdx` files.
|
||||
|
||||
> **Note**: `.mdx` files adhere to strict JSX syntax rather than Astro's HTML-like syntax.
|
||||
|
||||
Also check our [Astro Integration Documentation][astro-integration] for more on integrations.
|
||||
|
||||
## Configuration
|
||||
|
||||
There are currently no configuration options for the `@astrojs/mdx` integration. Please [open an issue](https://github.com/withastro/astro/issues/new/choose) if you have a compelling use case to share.
|
||||
|
||||
## Examples
|
||||
|
||||
- The [Astro MDX example](https://github.com/withastro/astro/tree/latest/examples/with-mdx) shows how to use MDX files in your Astro project.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
For help, check out the `#support-threads` channel on [Discord](https://astro.build/chat). Our friendly Support Squad members are here to help!
|
||||
|
||||
You can also check our [Astro Integration Documentation][astro-integration] for more on integrations.
|
||||
|
||||
## Contributing
|
||||
|
||||
This package is maintained by Astro's Core team. You're welcome to submit an issue or PR!
|
||||
|
||||
## Changelog
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md) for a history of changes to this integration.
|
||||
|
||||
[astro-integration]: https://docs.astro.build/en/guides/integrations-guide/
|
||||
[astro-ui-frameworks]: https://docs.astro.build/en/core-concepts/framework-components/#using-framework-components
|
47
packages/integrations/mdx/package.json
Normal file
47
packages/integrations/mdx/package.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"name": "@astrojs/mdx",
|
||||
"description": "Use MDX within Astro",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"types": "./dist/index.d.ts",
|
||||
"author": "withastro",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/withastro/astro.git",
|
||||
"directory": "packages/integrations/mdx"
|
||||
},
|
||||
"keywords": [
|
||||
"astro-component",
|
||||
"renderer",
|
||||
"mdx"
|
||||
],
|
||||
"bugs": "https://github.com/withastro/astro/issues",
|
||||
"homepage": "https://astro.build",
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
|
||||
"build:ci": "astro-scripts build \"src/**/*.ts\"",
|
||||
"dev": "astro-scripts dev \"src/**/*.ts\"",
|
||||
"test": "mocha --exit --timeout 20000"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdx-js/rollup": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.3.1",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/yargs-parser": "^21.0.0",
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"chai": "^4.3.6",
|
||||
"mocha": "^9.2.2",
|
||||
"linkedom": "^0.14.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || >=16.0.0"
|
||||
}
|
||||
}
|
39
packages/integrations/mdx/src/index.ts
Normal file
39
packages/integrations/mdx/src/index.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import type { AstroIntegration } from 'astro';
|
||||
import mdxPlugin from '@mdx-js/rollup';
|
||||
|
||||
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) {
|
||||
import.meta.hot.decline();
|
||||
}`
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
packages/integrations/mdx/test/fixtures/mdx-component/src/components/Test.mdx
vendored
Normal file
3
packages/integrations/mdx/test/fixtures/mdx-component/src/components/Test.mdx
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Hello component!
|
||||
|
||||
<div id="foo">bar</div>
|
5
packages/integrations/mdx/test/fixtures/mdx-component/src/pages/index.astro
vendored
Normal file
5
packages/integrations/mdx/test/fixtures/mdx-component/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
import Test from '../components/Test.mdx';
|
||||
---
|
||||
|
||||
<Test />
|
1
packages/integrations/mdx/test/fixtures/mdx-page/src/pages/index.mdx
vendored
Normal file
1
packages/integrations/mdx/test/fixtures/mdx-page/src/pages/index.mdx
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
# Hello page!
|
63
packages/integrations/mdx/test/mdx-component.test.js
Normal file
63
packages/integrations/mdx/test/mdx-component.test.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
import mdx from '@astrojs/mdx';
|
||||
|
||||
import { expect } from 'chai';
|
||||
import { parseHTML } from 'linkedom'
|
||||
import { loadFixture } from '../../../astro/test/test-utils.js';
|
||||
|
||||
describe('MDX Component', () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: new URL('./fixtures/mdx-component/', import.meta.url),
|
||||
integrations: [
|
||||
mdx()
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
describe('build', () => {
|
||||
before(async () => {
|
||||
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();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
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');
|
||||
const foo = document.querySelector('#foo');
|
||||
|
||||
expect(h1.textContent).to.equal('Hello component!');
|
||||
expect(foo.textContent).to.equal('bar');
|
||||
});
|
||||
})
|
||||
})
|
59
packages/integrations/mdx/test/mdx-page.test.js
Normal file
59
packages/integrations/mdx/test/mdx-page.test.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
import mdx from '@astrojs/mdx';
|
||||
|
||||
import { expect } from 'chai';
|
||||
import { parseHTML } from 'linkedom'
|
||||
import { loadFixture } from '../../../astro/test/test-utils.js';
|
||||
|
||||
describe('MDX Page', () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: new URL('./fixtures/mdx-page/', import.meta.url),
|
||||
integrations: [
|
||||
mdx()
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
describe('build', () => {
|
||||
before(async () => {
|
||||
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();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
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!');
|
||||
});
|
||||
})
|
||||
})
|
10
packages/integrations/mdx/tsconfig.json
Normal file
10
packages/integrations/mdx/tsconfig.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"module": "ES2020",
|
||||
"outDir": "./dist",
|
||||
"target": "ES2020"
|
||||
}
|
||||
}
|
307
pnpm-lock.yaml
307
pnpm-lock.yaml
|
@ -400,6 +400,18 @@ importers:
|
|||
'@astrojs/markdown-remark': link:../../packages/markdown/remark
|
||||
astro: link:../../packages/astro
|
||||
|
||||
examples/with-mdx:
|
||||
specifiers:
|
||||
'@astrojs/mdx': ^0.0.1
|
||||
'@astrojs/preact': ^0.2.0
|
||||
astro: ^1.0.0-beta.58
|
||||
preact: ^10.6.5
|
||||
devDependencies:
|
||||
'@astrojs/mdx': link:../../packages/integrations/mdx
|
||||
'@astrojs/preact': 0.2.0_preact@10.8.2
|
||||
astro: link:../../packages/astro
|
||||
preact: 10.8.2
|
||||
|
||||
examples/with-nanostores:
|
||||
specifiers:
|
||||
'@astrojs/preact': ^0.3.1
|
||||
|
@ -463,7 +475,7 @@ importers:
|
|||
|
||||
packages/astro:
|
||||
specifiers:
|
||||
'@astrojs/compiler': ^0.17.0
|
||||
'@astrojs/compiler': ^0.17.1
|
||||
'@astrojs/language-server': ^0.13.4
|
||||
'@astrojs/markdown-remark': ^0.11.3
|
||||
'@astrojs/prism': 0.4.1
|
||||
|
@ -948,21 +960,25 @@ importers:
|
|||
|
||||
packages/astro/e2e/fixtures/preact-component:
|
||||
specifiers:
|
||||
'@astrojs/mdx': workspace:*
|
||||
'@astrojs/preact': workspace:*
|
||||
astro: workspace:*
|
||||
preact: ^10.7.3
|
||||
dependencies:
|
||||
'@astrojs/mdx': link:../../../../integrations/mdx
|
||||
'@astrojs/preact': link:../../../../integrations/preact
|
||||
astro: link:../../..
|
||||
preact: 10.8.2
|
||||
|
||||
packages/astro/e2e/fixtures/react-component:
|
||||
specifiers:
|
||||
'@astrojs/mdx': workspace:*
|
||||
'@astrojs/react': workspace:*
|
||||
astro: workspace:*
|
||||
react: ^18.1.0
|
||||
react-dom: ^18.1.0
|
||||
dependencies:
|
||||
'@astrojs/mdx': link:../../../../integrations/mdx
|
||||
'@astrojs/react': link:../../../../integrations/react
|
||||
astro: link:../../..
|
||||
react: 18.2.0
|
||||
|
@ -970,10 +986,12 @@ importers:
|
|||
|
||||
packages/astro/e2e/fixtures/solid-component:
|
||||
specifiers:
|
||||
'@astrojs/mdx': workspace:*
|
||||
'@astrojs/solid-js': workspace:*
|
||||
astro: workspace:*
|
||||
solid-js: ^1.4.3
|
||||
dependencies:
|
||||
'@astrojs/mdx': link:../../../../integrations/mdx
|
||||
'@astrojs/solid-js': link:../../../../integrations/solid
|
||||
astro: link:../../..
|
||||
devDependencies:
|
||||
|
@ -981,10 +999,12 @@ importers:
|
|||
|
||||
packages/astro/e2e/fixtures/svelte-component:
|
||||
specifiers:
|
||||
'@astrojs/mdx': workspace:*
|
||||
'@astrojs/svelte': workspace:*
|
||||
astro: workspace:*
|
||||
svelte: ^3.48.0
|
||||
dependencies:
|
||||
'@astrojs/mdx': link:../../../../integrations/mdx
|
||||
'@astrojs/svelte': link:../../../../integrations/svelte
|
||||
astro: link:../../..
|
||||
svelte: 3.48.0
|
||||
|
@ -1011,9 +1031,11 @@ importers:
|
|||
|
||||
packages/astro/e2e/fixtures/vue-component:
|
||||
specifiers:
|
||||
'@astrojs/mdx': workspace:*
|
||||
'@astrojs/vue': workspace:*
|
||||
astro: workspace:*
|
||||
dependencies:
|
||||
'@astrojs/mdx': link:../../../../integrations/mdx
|
||||
'@astrojs/vue': link:../../../../integrations/vue
|
||||
astro: link:../../..
|
||||
|
||||
|
@ -1904,6 +1926,29 @@ importers:
|
|||
cheerio: 1.0.0-rc.12
|
||||
sass: 1.53.0
|
||||
|
||||
packages/integrations/mdx:
|
||||
specifiers:
|
||||
'@mdx-js/rollup': ^2.1.1
|
||||
'@types/chai': ^4.3.1
|
||||
'@types/mocha': ^9.1.1
|
||||
'@types/yargs-parser': ^21.0.0
|
||||
astro: workspace:*
|
||||
astro-scripts: workspace:*
|
||||
chai: ^4.3.6
|
||||
linkedom: ^0.14.12
|
||||
mocha: ^9.2.2
|
||||
dependencies:
|
||||
'@mdx-js/rollup': 2.1.2
|
||||
devDependencies:
|
||||
'@types/chai': 4.3.1
|
||||
'@types/mocha': 9.1.1
|
||||
'@types/yargs-parser': 21.0.0
|
||||
astro: link:../../astro
|
||||
astro-scripts: link:../../../scripts
|
||||
chai: 4.3.6
|
||||
linkedom: 0.14.12
|
||||
mocha: 9.2.2
|
||||
|
||||
packages/integrations/netlify:
|
||||
specifiers:
|
||||
'@astrojs/webapi': ^0.12.0
|
||||
|
@ -2565,6 +2610,19 @@ packages:
|
|||
vfile-message: 3.1.2
|
||||
dev: false
|
||||
|
||||
/@astrojs/preact/0.2.0_preact@10.8.2:
|
||||
resolution: {integrity: sha512-AedeRz65mmW8qvS2TR20lS1TdRSXzKY9g3X8k1OlL585XE8ZI5WfucpzNMYMQxNuRvRDoh7imO8JoKt19O/mgg==}
|
||||
engines: {node: ^14.15.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
preact: ^10.6.5
|
||||
dependencies:
|
||||
'@babel/plugin-transform-react-jsx': 7.18.6
|
||||
preact: 10.8.2
|
||||
preact-render-to-string: 5.2.0_preact@10.8.2
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
dev: true
|
||||
|
||||
/@astrojs/svelte-language-integration/0.1.6_typescript@4.6.4:
|
||||
resolution: {integrity: sha512-nqczE674kz7GheKSWQwTOL6+NGHghc4INQox048UyHJRaIKHEbCPyFLDBDVY7QJH0jug1komCJ8OZXUn6Z3eLA==}
|
||||
dependencies:
|
||||
|
@ -2861,6 +2919,8 @@ packages:
|
|||
resolution: {integrity: sha512-uQVSa9jJUe/G/304lXspfWVpKpK4euFLgGiMQFOCpM/bgcAdeoHwi/OQz23O9GK2osz26ZiXRRV9aV+Yl1O8tw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@babel/types': 7.18.7
|
||||
|
||||
/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.18.6:
|
||||
resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==}
|
||||
|
@ -3215,7 +3275,6 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
'@babel/helper-plugin-utils': 7.18.6
|
||||
dev: false
|
||||
|
||||
/@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.18.6:
|
||||
resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==}
|
||||
|
@ -3680,7 +3739,6 @@ packages:
|
|||
'@babel/helper-plugin-utils': 7.18.6
|
||||
'@babel/plugin-syntax-jsx': 7.18.6
|
||||
'@babel/types': 7.18.7
|
||||
dev: false
|
||||
|
||||
/@babel/plugin-transform-react-jsx/7.18.6_@babel+core@7.18.6:
|
||||
resolution: {integrity: sha512-Mz7xMPxoy9kPS/JScj6fJs03TZ/fZ1dJPlMjRAgTaxaS0fUBk8FV/A2rRgfPsVCZqALNwMexD+0Uaf5zlcKPpw==}
|
||||
|
@ -4563,6 +4621,46 @@ packages:
|
|||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@mdx-js/mdx/2.1.2:
|
||||
resolution: {integrity: sha512-ASN1GUH0gXsgJ2UD/Td7FzJo1SwFkkQ5V1i9at5o/ROra7brkyMcBsotsOWJWRzmXZaLw2uXWn4aN8B3PMNFMA==}
|
||||
dependencies:
|
||||
'@types/estree-jsx': 0.0.1
|
||||
'@types/mdx': 2.0.2
|
||||
astring: 1.8.3
|
||||
estree-util-build-jsx: 2.1.0
|
||||
estree-util-is-identifier-name: 2.0.1
|
||||
estree-walker: 3.0.1
|
||||
hast-util-to-estree: 2.0.2
|
||||
markdown-extensions: 1.1.1
|
||||
periscopic: 3.0.4
|
||||
remark-mdx: 2.1.1
|
||||
remark-parse: 10.0.1
|
||||
remark-rehype: 10.1.0
|
||||
unified: 10.1.2
|
||||
unist-util-position-from-estree: 1.1.1
|
||||
unist-util-stringify-position: 3.0.2
|
||||
unist-util-visit: 4.1.0
|
||||
vfile: 5.3.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@mdx-js/rollup/2.1.2:
|
||||
resolution: {integrity: sha512-3ahqp3DCpIlGlCRuLX4z7dFEgN5kWBljrk8BpipiWkVrvB4FQpTQu1T7lmDffm8tOunjHAsZEHtb076HiW51NQ==}
|
||||
peerDependencies:
|
||||
rollup: '>=2'
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@mdx-js/mdx': 2.1.2
|
||||
'@rollup/pluginutils': 4.2.1
|
||||
source-map: 0.7.4
|
||||
vfile: 5.3.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@nanostores/preact/0.1.3_gzamsul3sgwlq3zzcqv3ims3km:
|
||||
resolution: {integrity: sha512-uiX1ned0LrzASot+sPUjyJzr8Js3pX075omazgsSdLf0zPp4ss8xwTiuNh5FSKigTSQEVqZFiS+W8CnHIrX62A==}
|
||||
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
|
||||
|
@ -6964,6 +7062,9 @@ packages:
|
|||
engines: {node: '>=8.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
rollup: 2.75.7
|
||||
slash: 3.0.0
|
||||
|
@ -6981,6 +7082,8 @@ packages:
|
|||
optional: true
|
||||
'@types/babel__core':
|
||||
optional: true
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/core': 7.18.6
|
||||
'@babel/helper-module-imports': 7.18.6
|
||||
|
@ -6992,6 +7095,9 @@ packages:
|
|||
resolution: {integrity: sha512-4pbcU4J/nS+zuHk+c+OL3WtmEQhqxlZ9uqfjQMQDOHOPld7PsCd8k5LWs8h5wjwJN7MgnAn768F2sDxEP4eNFQ==}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0 || ^2.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.75.7
|
||||
estree-walker: 2.0.2
|
||||
|
@ -7004,6 +7110,9 @@ packages:
|
|||
engines: {node: '>= 10.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.75.7
|
||||
'@types/resolve': 1.17.1
|
||||
|
@ -7019,6 +7128,9 @@ packages:
|
|||
engines: {node: '>= 10.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^2.42.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.75.7
|
||||
'@types/resolve': 1.17.1
|
||||
|
@ -7033,6 +7145,9 @@ packages:
|
|||
resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0 || ^2.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0_rollup@2.75.7
|
||||
magic-string: 0.25.9
|
||||
|
@ -7047,6 +7162,8 @@ packages:
|
|||
tslib: '*'
|
||||
typescript: '>=3.7.0'
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
tslib:
|
||||
optional: true
|
||||
dependencies:
|
||||
|
@ -7062,6 +7179,9 @@ packages:
|
|||
engines: {node: '>= 8.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/estree': 0.0.39
|
||||
estree-walker: 1.0.1
|
||||
|
@ -7286,6 +7406,10 @@ packages:
|
|||
resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==}
|
||||
dev: false
|
||||
|
||||
/@types/mdx/2.0.2:
|
||||
resolution: {integrity: sha512-mJGfgj4aWpiKb8C0nnJJchs1sHBHn0HugkVfqqyQi7Wn6mBRksLeQsPOFvih/Pu8L1vlDzfe/LidhVHBeUk3aQ==}
|
||||
dev: false
|
||||
|
||||
/@types/mime/1.3.2:
|
||||
resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==}
|
||||
dev: true
|
||||
|
@ -8064,6 +8188,11 @@ packages:
|
|||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/astring/1.8.3:
|
||||
resolution: {integrity: sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/async/3.2.4:
|
||||
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
|
||||
dev: true
|
||||
|
@ -8734,6 +8863,10 @@ packages:
|
|||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
|
||||
/cssom/0.5.0:
|
||||
resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==}
|
||||
dev: true
|
||||
|
||||
/csstype/2.6.20:
|
||||
resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==}
|
||||
|
||||
|
@ -8783,6 +8916,11 @@ packages:
|
|||
|
||||
/debug/3.2.7:
|
||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
dev: false
|
||||
|
@ -9527,6 +9665,20 @@ packages:
|
|||
engines: {node: '>=4.0'}
|
||||
dev: true
|
||||
|
||||
/estree-util-attach-comments/2.0.1:
|
||||
resolution: {integrity: sha512-1wTBNndwMIsnvnuxjFIaYQz0M7PsCvcgP0YD7/dU8xWh1FuHk+O6pYpT4sLa5THY/CywJvdIdgw4uhozujga/g==}
|
||||
dependencies:
|
||||
'@types/estree': 0.0.51
|
||||
dev: false
|
||||
|
||||
/estree-util-build-jsx/2.1.0:
|
||||
resolution: {integrity: sha512-gsBGfsY6LOJUIDwmMkTOcgCX+3r/LUjRBccgHMSW55PHjhZsV13RmPl/iwpAvW8KcQqoN9P0FEFWTSS2Zc5bGA==}
|
||||
dependencies:
|
||||
'@types/estree-jsx': 0.0.1
|
||||
estree-util-is-identifier-name: 2.0.1
|
||||
estree-walker: 3.0.1
|
||||
dev: false
|
||||
|
||||
/estree-util-is-identifier-name/2.0.1:
|
||||
resolution: {integrity: sha512-rxZj1GkQhY4x1j/CSnybK9cGuMFQYFPLq0iNyopqf14aOVLFtMv7Esika+ObJWPWiOHuMOAHz3YkWoLYYRnzWQ==}
|
||||
dev: false
|
||||
|
@ -10204,6 +10356,27 @@ packages:
|
|||
zwitch: 2.0.2
|
||||
dev: false
|
||||
|
||||
/hast-util-to-estree/2.0.2:
|
||||
resolution: {integrity: sha512-UQrZVeBj6A9od0lpFvqHKNSH9zvDrNoyWKbveu1a2oSCXEDUI+3bnd6BoiQLPnLrcXXn/jzJ6y9hmJTTlvf8lQ==}
|
||||
dependencies:
|
||||
'@types/estree-jsx': 0.0.1
|
||||
'@types/hast': 2.3.4
|
||||
'@types/unist': 2.0.6
|
||||
comma-separated-tokens: 2.0.2
|
||||
estree-util-attach-comments: 2.0.1
|
||||
estree-util-is-identifier-name: 2.0.1
|
||||
hast-util-whitespace: 2.0.0
|
||||
mdast-util-mdx-expression: 1.2.1
|
||||
mdast-util-mdxjs-esm: 1.2.0
|
||||
property-information: 6.1.1
|
||||
space-separated-tokens: 2.0.1
|
||||
style-to-object: 0.3.0
|
||||
unist-util-position: 4.0.3
|
||||
zwitch: 2.0.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/hast-util-to-html/8.0.3:
|
||||
resolution: {integrity: sha512-/D/E5ymdPYhHpPkuTHOUkSatxr4w1ZKrZsG0Zv/3C2SRVT0JFJG53VS45AMrBtYk0wp5A7ksEhiC8QaOZM95+A==}
|
||||
dependencies:
|
||||
|
@ -10267,7 +10440,6 @@ packages:
|
|||
|
||||
/html-escaper/3.0.3:
|
||||
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
|
||||
dev: false
|
||||
|
||||
/html-void-elements/2.0.1:
|
||||
resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==}
|
||||
|
@ -10620,6 +10792,12 @@ packages:
|
|||
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
|
||||
dev: true
|
||||
|
||||
/is-reference/3.0.0:
|
||||
resolution: {integrity: sha512-Eo1W3wUoHWoCoVM4GVl/a+K0IgiqE5aIo4kJABFyMum1ZORlPkC+UC357sSQUL5w5QCE5kCC9upl75b7+7CY/Q==}
|
||||
dependencies:
|
||||
'@types/estree': 0.0.52
|
||||
dev: false
|
||||
|
||||
/is-regex/1.1.4:
|
||||
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
@ -10884,6 +11062,16 @@ packages:
|
|||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||
dev: true
|
||||
|
||||
/linkedom/0.14.12:
|
||||
resolution: {integrity: sha512-8uw8LZifCwyWeVWr80T79sQTMmNXt4Da7oN5yH5gTXRqQM+TuZWJyBqRMcIp32zx/f8anHNHyil9Avw9y76ziQ==}
|
||||
dependencies:
|
||||
css-select: 5.1.0
|
||||
cssom: 0.5.0
|
||||
html-escaper: 3.0.3
|
||||
htmlparser2: 8.0.1
|
||||
uhyphen: 0.1.0
|
||||
dev: true
|
||||
|
||||
/lit-element/3.2.1:
|
||||
resolution: {integrity: sha512-2PxyE9Yq9Jyo/YBK2anycaHcqo93YvB5D+24JxloPVqryW/BOXekne+jGsm0Ke3E5E2v7CDgkmpEmCAzYfrHCQ==}
|
||||
dependencies:
|
||||
|
@ -11043,6 +11231,11 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/markdown-extensions/1.1.1:
|
||||
resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/markdown-table/3.0.2:
|
||||
resolution: {integrity: sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA==}
|
||||
dev: false
|
||||
|
@ -11162,6 +11355,43 @@ packages:
|
|||
vfile-message: 3.1.2
|
||||
dev: false
|
||||
|
||||
/mdast-util-mdx-jsx/2.0.1:
|
||||
resolution: {integrity: sha512-oPC7/smPBf7vxnvIYH5y3fPo2lw1rdrswFfSb4i0GTAXRUQv7JUU/t/hbp07dgGdUFTSDOHm5DNamhNg/s2Hrg==}
|
||||
dependencies:
|
||||
'@types/estree-jsx': 0.0.1
|
||||
'@types/hast': 2.3.4
|
||||
'@types/mdast': 3.0.10
|
||||
ccount: 2.0.1
|
||||
mdast-util-to-markdown: 1.3.0
|
||||
parse-entities: 4.0.0
|
||||
stringify-entities: 4.0.3
|
||||
unist-util-remove-position: 4.0.1
|
||||
unist-util-stringify-position: 3.0.2
|
||||
vfile-message: 3.1.2
|
||||
dev: false
|
||||
|
||||
/mdast-util-mdx/2.0.0:
|
||||
resolution: {integrity: sha512-M09lW0CcBT1VrJUaF/PYxemxxHa7SLDHdSn94Q9FhxjCQfuW7nMAWKWimTmA3OyDMSTH981NN1csW1X+HPSluw==}
|
||||
dependencies:
|
||||
mdast-util-mdx-expression: 1.2.1
|
||||
mdast-util-mdx-jsx: 2.0.1
|
||||
mdast-util-mdxjs-esm: 1.2.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/mdast-util-mdxjs-esm/1.2.0:
|
||||
resolution: {integrity: sha512-IPpX9GBzAIbIRCjbyeLDpMhACFb0wxTIujuR3YElB8LWbducUdMgRJuqs/Vg8xQ1bIAMm7lw8L+YNtua0xKXRw==}
|
||||
dependencies:
|
||||
'@types/estree-jsx': 0.0.1
|
||||
'@types/hast': 2.3.4
|
||||
'@types/mdast': 3.0.10
|
||||
mdast-util-from-markdown: 1.2.0
|
||||
mdast-util-to-markdown: 1.3.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/mdast-util-to-hast/12.1.1:
|
||||
resolution: {integrity: sha512-qE09zD6ylVP14jV4mjLIhDBOrpFdShHZcEsYvvKGABlr9mGbV7mTlRWdoFxL/EYSTNDiC9GZXy7y8Shgb9Dtzw==}
|
||||
dependencies:
|
||||
|
@ -11327,12 +11557,52 @@ packages:
|
|||
uvu: 0.5.4
|
||||
dev: false
|
||||
|
||||
/micromark-extension-mdx-jsx/1.0.3:
|
||||
resolution: {integrity: sha512-VfA369RdqUISF0qGgv2FfV7gGjHDfn9+Qfiv5hEwpyr1xscRj/CiVRkU7rywGFCO7JwJ5L0e7CJz60lY52+qOA==}
|
||||
dependencies:
|
||||
'@types/acorn': 4.0.6
|
||||
estree-util-is-identifier-name: 2.0.1
|
||||
micromark-factory-mdx-expression: 1.0.6
|
||||
micromark-factory-space: 1.0.0
|
||||
micromark-util-character: 1.1.0
|
||||
micromark-util-symbol: 1.0.1
|
||||
micromark-util-types: 1.0.2
|
||||
uvu: 0.5.4
|
||||
vfile-message: 3.1.2
|
||||
dev: false
|
||||
|
||||
/micromark-extension-mdx-md/1.0.0:
|
||||
resolution: {integrity: sha512-xaRAMoSkKdqZXDAoSgp20Azm0aRQKGOl0RrS81yGu8Hr/JhMsBmfs4wR7m9kgVUIO36cMUQjNyiyDKPrsv8gOw==}
|
||||
dependencies:
|
||||
micromark-util-types: 1.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-extension-mdxjs-esm/1.0.3:
|
||||
resolution: {integrity: sha512-2N13ol4KMoxb85rdDwTAC6uzs8lMX0zeqpcyx7FhS7PxXomOnLactu8WI8iBNXW8AVyea3KIJd/1CKnUmwrK9A==}
|
||||
dependencies:
|
||||
micromark-core-commonmark: 1.0.6
|
||||
micromark-util-character: 1.1.0
|
||||
micromark-util-events-to-acorn: 1.1.0
|
||||
micromark-util-symbol: 1.0.1
|
||||
micromark-util-types: 1.0.2
|
||||
unist-util-position-from-estree: 1.1.1
|
||||
uvu: 0.5.4
|
||||
vfile-message: 3.1.2
|
||||
dev: false
|
||||
|
||||
/micromark-extension-mdxjs/1.0.0:
|
||||
resolution: {integrity: sha512-TZZRZgeHvtgm+IhtgC2+uDMR7h8eTKF0QUX9YsgoL9+bADBpBY6SiLvWqnBlLbCEevITmTqmEuY3FoxMKVs1rQ==}
|
||||
dependencies:
|
||||
acorn: 8.7.1
|
||||
acorn-jsx: 5.3.2_acorn@8.7.1
|
||||
micromark-extension-mdx-expression: 1.0.3
|
||||
micromark-extension-mdx-jsx: 1.0.3
|
||||
micromark-extension-mdx-md: 1.0.0
|
||||
micromark-extension-mdxjs-esm: 1.0.3
|
||||
micromark-util-combine-extensions: 1.0.0
|
||||
micromark-util-types: 1.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-factory-destination/1.0.0:
|
||||
resolution: {integrity: sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==}
|
||||
dependencies:
|
||||
|
@ -11703,6 +11973,8 @@ packages:
|
|||
debug: 3.2.7
|
||||
iconv-lite: 0.4.24
|
||||
sax: 1.2.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/netmask/2.0.2:
|
||||
|
@ -11786,6 +12058,8 @@ packages:
|
|||
rimraf: 2.7.1
|
||||
semver: 5.7.1
|
||||
tar: 4.4.19
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/node-releases/2.0.5:
|
||||
|
@ -12246,6 +12520,13 @@ packages:
|
|||
resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
|
||||
dev: true
|
||||
|
||||
/periscopic/3.0.4:
|
||||
resolution: {integrity: sha512-SFx68DxCv0Iyo6APZuw/AKewkkThGwssmU0QWtTlvov3VAtPX+QJ4CadwSaz8nrT5jPIuxdvJWB4PnD2KNDxQg==}
|
||||
dependencies:
|
||||
estree-walker: 3.0.1
|
||||
is-reference: 3.0.0
|
||||
dev: false
|
||||
|
||||
/picocolors/1.0.0:
|
||||
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
|
||||
|
||||
|
@ -12697,7 +12978,6 @@ packages:
|
|||
dependencies:
|
||||
preact: 10.8.2
|
||||
pretty-format: 3.8.0
|
||||
dev: false
|
||||
|
||||
/preact/10.6.6:
|
||||
resolution: {integrity: sha512-dgxpTFV2vs4vizwKohYKkk7g7rmp1wOOcfd4Tz3IB3Wi+ivZzsn/SpeKJhRENSE+n8sUfsAl4S3HiCVT923ABw==}
|
||||
|
@ -12775,7 +13055,6 @@ packages:
|
|||
|
||||
/pretty-format/3.8.0:
|
||||
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
|
||||
dev: false
|
||||
|
||||
/prismjs/1.28.0:
|
||||
resolution: {integrity: sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw==}
|
||||
|
@ -13159,6 +13438,15 @@ packages:
|
|||
- supports-color
|
||||
dev: false
|
||||
|
||||
/remark-mdx/2.1.1:
|
||||
resolution: {integrity: sha512-0wXdEITnFyjLquN3VvACNLzbGzWM5ujzTvfgOkONBZgSFJ7ezLLDaTWqf6H9eUgVITEP8asp6LJ0W/X090dXBg==}
|
||||
dependencies:
|
||||
mdast-util-mdx: 2.0.0
|
||||
micromark-extension-mdxjs: 1.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/remark-parse/10.0.1:
|
||||
resolution: {integrity: sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==}
|
||||
dependencies:
|
||||
|
@ -13285,6 +13573,9 @@ packages:
|
|||
resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
|
||||
peerDependencies:
|
||||
rollup: ^2.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.18.6
|
||||
jest-worker: 26.6.2
|
||||
|
@ -14377,6 +14668,10 @@ packages:
|
|||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/uhyphen/0.1.0:
|
||||
resolution: {integrity: sha512-o0QVGuFg24FK765Qdd5kk0zU/U4dEsCtN/GSiwNI9i8xsSVtjIAOdTaVhLwZ1nrbWxFVMxNDDl+9fednsOMsBw==}
|
||||
dev: true
|
||||
|
||||
/unbox-primitive/1.0.2:
|
||||
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
|
||||
dependencies:
|
||||
|
|
Loading…
Reference in a new issue