Add next-mdx-remote

This commit is contained in:
DefectingCat
2022-08-18 15:19:25 +08:00
parent 1b2af6dc43
commit 562ba00912
49 changed files with 193 additions and 55 deletions

View File

@ -0,0 +1,5 @@
const main = `export default function App() {
return <h1>Hello world</h1>
}`;
export default main;

View File

@ -0,0 +1,9 @@
import RUASandpack from 'components/RUA/RUASandpack';
import Anchor from 'components/mdx/Anchor';
const components = {
RUASandpack,
a: Anchor,
};
export default components;

9
data/mdxData.ts Normal file
View File

@ -0,0 +1,9 @@
import main from 'assets/sandpack/hello-world/main';
const data = {
sandpack: {
'hello-world': main,
},
};
export default data;

View File

@ -0,0 +1,22 @@
---
title: Hello world
date: '2022-04-06'
tags: ['Hello world']
---
## Hello
This is my first post!
```ts
console.log('Hello world');
```
## Say hello to world
<RUASandpack
template="react"
files={{
'/App.js': sandpack['hello-world'],
}}
/>

View File

@ -1,17 +1,19 @@
import fs from 'fs';
import fs from 'fs/promises';
import path from 'path';
import matter from 'gray-matter';
import { MyMatters, Post } from 'types';
import { sortByDate } from 'lib/utils';
const dataPath = 'data/posts';
/**
* Read post meta info with gray-matter.
* @param filename
* @returns
*/
const readFileMeta = (filename: string) => {
const markdownWithMeta = fs.readFileSync(
path.join('pages/p', filename),
const readFileMeta = async (filename: string) => {
const markdownWithMeta = await fs.readFile(
path.join(dataPath, filename),
'utf-8'
);
const slug = filename.replace(/\.mdx$/, '');
@ -27,8 +29,25 @@ const readFileMeta = (filename: string) => {
* @returns
*/
export const postLists = async (): Promise<Post[]> => {
const files = fs.readdirSync(path.join('pages/p'));
const posts = files.map(readFileMeta).sort(sortByDate);
return posts;
const files = await fs.readdir(path.join(dataPath));
return (await Promise.all(files.map(readFileMeta))).sort(sortByDate);
};
const readFilePath = async (filename: string) => {
const slug = filename.replace(/\.mdx$/, '');
return {
params: {
slug,
},
};
};
export const allPostsPath = async () => {
const files = await fs.readdir(path.join(dataPath));
return await Promise.all(files.map(readFilePath));
};
export const readSinglePost = async (slug: string) => {
const filename = path.join(`${dataPath}/${slug}.mdx`);
return await fs.readFile(filename, { encoding: 'utf-8' });
};

View File

@ -24,6 +24,7 @@
"dayjs": "^1.11.4",
"next": "12.2.4",
"next-compose-plugins": "^2.2.1",
"next-mdx-remote": "^4.1.0",
"next-themes": "^0.2.0",
"octokit": "^2.0.4",
"react": "^18.2.0",

View File

@ -40,9 +40,9 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
enableSystem
defaultTheme="system"
>
<MDXProvider components={components}>
{getLayout(<Component {...pageProps} />)}
</MDXProvider>
{/* <MDXProvider components={components}> */}
{getLayout(<Component {...pageProps} />)}
{/* </MDXProvider> */}
</ThemeProvider>
{loading && <VercelLoading />}

74
pages/p/[slug].tsx Normal file
View File

@ -0,0 +1,74 @@
import { allPostsPath, readSinglePost } from 'lib/posts';
import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next';
import { serialize } from 'next-mdx-remote/serialize';
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote';
import components from 'components/mdx/components';
import data from 'data/mdxData';
import rehypePrism from '@mapbox/rehype-prism';
import remarkGfm from 'remark-gfm';
import rehypeSlug from 'rehype-slug';
import dynamic from 'next/dynamic';
import { MyMatters } from 'types';
const Footer = dynamic(() => import('components/Footer'));
const HeadBar = dynamic(() => import('components/NavBar'));
const PostComment = dynamic(() => import('components/post/PostComment'));
const Slug = ({
mdxSource,
}: InferGetStaticPropsType<typeof getStaticProps>) => {
return (
<>
<HeadBar />
<main id="article" className="relative max-w-4xl px-4 mx-auto my-10">
<h1>{mdxSource.frontmatter?.title}</h1>
<time>{mdxSource.frontmatter?.date}</time>
<article id="post-content">
<MDXRemote {...mdxSource} components={components} />
<PostComment />
</article>
</main>
<Footer />
</>
);
};
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: await allPostsPath(),
fallback: false,
};
};
export const getStaticProps: GetStaticProps<{
mdxSource: MDXRemoteSerializeResult;
}> = async ({ params }) => {
const slug = params?.slug?.toString();
if (!slug)
return {
notFound: true,
};
const post = await readSinglePost(slug);
const mdxSource = await serialize(post, {
mdxOptions: {
remarkPlugins: [remarkGfm],
rehypePlugins: [
[rehypePrism, { alias: { vue: 'xml' }, ignoreMissing: true }],
rehypeSlug,
],
},
parseFrontmatter: true,
scope: data,
});
return {
props: {
mdxSource,
},
};
};
export default Slug;

View File

@ -1,43 +0,0 @@
---
title: Hello world
date: '2022-04-06'
tags: ['Hello world']
---
import Layout from 'layouts/MDXLayout';
import dynamic from 'next/dynamic';
export const RUASandpack = dynamic(() => import('components/RUA/RUASandpack'));
export const meta = {
title: 'Hello world',
date: '2022-04-06',
tags: ['Hello world'],
};
export default ({ children }) => (
<Layout {...meta} showTOC={false}>
{children}
</Layout>
);
## Hello
This is my first post!
```ts
console.log('Hello world');
```
## Say hello to world
export const main = `export default function App() {
return <h1>Hello world</h1>
}`;
<RUASandpack
template="react"
files={{
'/App.js': main,
}}
/>

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 144 KiB

View File

Before

Width:  |  Height:  |  Size: 343 KiB

After

Width:  |  Height:  |  Size: 343 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 348 B

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1281,6 +1281,14 @@
unist-util-visit "^4.0.0"
vfile "^5.0.0"
"@mdx-js/react@^2.0.0":
version "2.1.3"
resolved "https://registry.npmmirror.com/@mdx-js/react/-/react-2.1.3.tgz#4b28a774295ed1398cf6be1b8ddef69d6a30e78d"
integrity sha512-11n4lTvvRyxq3OYbWJwEYM+7q6PE0GxKbk0AwYIIQmrRkxDeljIsjDQkKOgdr/orgRRbYy5zi+iERdnwe01CHQ==
dependencies:
"@types/mdx" "^2.0.0"
"@types/react" ">=16"
"@mdx-js/react@^2.1.2":
version "2.1.2"
resolved "https://registry.npmmirror.com/@mdx-js/react/-/react-2.1.2.tgz#02972f170cd3ad9113ce448245c5f636bb3e750d"
@ -1903,6 +1911,11 @@
jest-matcher-utils "^28.0.0"
pretty-format "^28.0.0"
"@types/js-yaml@^4.0.0":
version "4.0.5"
resolved "https://registry.npmmirror.com/@types/js-yaml/-/js-yaml-4.0.5.tgz#738dd390a6ecc5442f35e7f03fa1431353f7e138"
integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==
"@types/jsdom@^16.2.4":
version "16.2.14"
resolved "https://registry.npmmirror.com/@types/jsdom/-/jsdom-16.2.14.tgz#26fe9da6a8870715b154bb84cd3b2e53433d8720"
@ -5372,7 +5385,7 @@ js-yaml@^3.13.1, js-yaml@^3.14.1:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^4.1.0:
js-yaml@^4.0.0, js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
@ -6514,6 +6527,16 @@ next-compose-plugins@^2.2.1:
resolved "https://registry.npmmirror.com/next-compose-plugins/-/next-compose-plugins-2.2.1.tgz#020fc53f275a7e719d62521bef4300fbb6fde5ab"
integrity sha512-OjJ+fV15FXO2uQXQagLD4C0abYErBjyjE0I0FHpOEIB8upw0hg1ldFP6cqHTJBH1cZqy96OeR3u1dJ+Ez2D4Bg==
next-mdx-remote@^4.1.0:
version "4.1.0"
resolved "https://registry.npmmirror.com/next-mdx-remote/-/next-mdx-remote-4.1.0.tgz#5e063542437a8cfa3faa9623870b076c01429c2a"
integrity sha512-ZdL5AFJcEqvInGkYYRKda930D6AJt1GOLX/OXFE/vTwaqV/Mw+l3/njZ4kWqvYSAkl89Z6W7WZrTtN0fd0XwPg==
dependencies:
"@mdx-js/mdx" "^2.0.0"
"@mdx-js/react" "^2.0.0"
vfile "^5.3.0"
vfile-matter "^3.0.1"
next-themes@^0.2.0:
version "0.2.0"
resolved "https://registry.npmmirror.com/next-themes/-/next-themes-0.2.0.tgz#fdc507f61e95b3ae513dee8d4783bcec8c02e3a3"
@ -8596,6 +8619,15 @@ validate-npm-package-name@^3.0.0:
dependencies:
builtins "^1.0.3"
vfile-matter@^3.0.1:
version "3.0.1"
resolved "https://registry.npmmirror.com/vfile-matter/-/vfile-matter-3.0.1.tgz#85e26088e43aa85c04d42ffa3693635fa2bc5624"
integrity sha512-CAAIDwnh6ZdtrqAuxdElUqQRQDQgbbIrYtDYI8gCjXS1qQ+1XdLoK8FIZWxJwn0/I+BkSSZpar3SOgjemQz4fg==
dependencies:
"@types/js-yaml" "^4.0.0"
is-buffer "^2.0.0"
js-yaml "^4.0.0"
vfile-message@^3.0.0:
version "3.1.2"
resolved "https://registry.npmmirror.com/vfile-message/-/vfile-message-3.1.2.tgz#a2908f64d9e557315ec9d7ea3a910f658ac05f7d"
@ -8614,6 +8646,16 @@ vfile@^5.0.0:
unist-util-stringify-position "^3.0.0"
vfile-message "^3.0.0"
vfile@^5.3.0:
version "5.3.4"
resolved "https://registry.npmmirror.com/vfile/-/vfile-5.3.4.tgz#bbb8c96b956693bbf70b2c67fdb5781dff769b93"
integrity sha512-KI+7cnst03KbEyN1+JE504zF5bJBZa+J+CrevLeyIMq0aPU681I2rQ5p4PlnQ6exFtWiUrg26QUdFMnAKR6PIw==
dependencies:
"@types/unist" "^2.0.0"
is-buffer "^2.0.0"
unist-util-stringify-position "^3.0.0"
vfile-message "^3.0.0"
w3c-hr-time@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"