feat: use mdx-bundler

This commit is contained in:
Timothy Lin
2021-06-26 18:46:45 +08:00
parent 0f844ff636
commit 553722750e
9 changed files with 1197 additions and 781 deletions

View File

@ -15,13 +15,14 @@ module.exports = (options) => (tree) => {
const dimensions = sizeOf(`${process.cwd()}/public${imageNode.url}`)
// Convert original node to next/image
imageNode.type = 'jsx'
imageNode.value = `<Image
alt={\`${imageNode.alt}\`}
src={\`${imageNode.url}\`}
width={${dimensions.width}}
height={${dimensions.height}}
/>`
;(imageNode.type = 'mdxJsxFlowElement'),
(imageNode.name = 'Image'),
(imageNode.attributes = [
{ type: 'mdxJsxAttribute', name: 'alt', value: imageNode.alt },
{ type: 'mdxJsxAttribute', name: 'src', value: imageNode.url },
{ type: 'mdxJsxAttribute', name: 'width', value: dimensions.width },
{ type: 'mdxJsxAttribute', name: 'height', value: dimensions.height },
])
// Change node type from p to div to avoid nesting error
node.type = 'div'

View File

@ -1,7 +1,6 @@
import { MDXComponents } from '@/components/MDXComponents'
import { bundleMDX } from 'mdx-bundler'
import fs from 'fs'
import matter from 'gray-matter'
import { serialize } from 'next-mdx-remote/serialize'
import path from 'path'
import readingTime from 'reading-time'
import visit from 'unist-util-visit'
@ -49,18 +48,42 @@ export async function getFileBySlug(type, slug) {
: fs.readFileSync(mdPath, 'utf8')
const { data, content } = matter(source)
const mdxSource = await serialize(content, {
components: MDXComponents,
mdxOptions: {
remarkPlugins: [
// https://github.com/kentcdodds/mdx-bundler#nextjs-esbuild-enoent
if (process.platform === 'win32') {
process.env.ESBUILD_BINARY_PATH = path.join(
process.cwd(),
'node_modules',
'esbuild',
'esbuild.exe'
)
} else {
process.env.ESBUILD_BINARY_PATH = path.join(
process.cwd(),
'node_modules',
'esbuild',
'bin',
'esbuild'
)
}
const { code } = await bundleMDX(source, {
xdmOptions(options) {
// this is the recommended way to add custom remark/rehype plugins:
// The syntax might look weird, but it protects you in case we add/remove
// plugins in the future.
options.remarkPlugins = [
...(options.remarkPlugins ?? []),
require('remark-slug'),
require('remark-autolink-headings'),
require('remark-gfm'),
require('remark-code-titles'),
[require('remark-footnotes'), { inlineNotes: true }],
require('remark-math'),
imgToJsx,
],
inlineNotes: true,
rehypePlugins: [
]
options.rehypePlugins = [
...(options.rehypePlugins ?? []),
require('rehype-katex'),
require('@mapbox/rehype-prism'),
() => {
@ -73,12 +96,13 @@ export async function getFileBySlug(type, slug) {
})
}
},
],
]
return options
},
})
return {
mdxSource,
mdxSource: code,
frontMatter: {
readingTime: readingTime(content),
slug: slug || null,

32
lib/remark-code-title.js Normal file
View File

@ -0,0 +1,32 @@
import visit from 'unist-util-visit'
module.exports = function (options) {
return (tree) =>
visit(tree, 'code', (node, index) => {
const nodeLang = node.lang || ''
let language = '',
title = ''
if (nodeLang.includes(':')) {
language = nodeLang.slice(0, nodeLang.search(':'))
title = nodeLang.slice(nodeLang.search(':') + 1, nodeLang.length)
}
if (!title) {
return
}
const className = 'remark-code-title'
const titleNode = {
type: 'mdxJsxFlowElement',
name: 'div',
attributes: [{ type: 'mdxJsxAttribute', name: 'className', value: className }],
children: [{ type: 'text', value: title }],
data: { _xdmExplicitJsx: true },
}
tree.children.splice(index, 0, titleNode)
node.lang = language
})
}