vite-plugin-react-pages
Version:
<p> <a href="https://www.npmjs.com/package/vite-plugin-react-pages" target="_blank" rel="noopener"><img src="https://img.shields.io/npm/v/vite-plugin-react-pages.svg" alt="npm package" /></a> </p>
113 lines (104 loc) • 2.91 kB
text/typescript
/// <reference types="remark-mdx" />
import type { Root } from 'mdast'
import type { MdxjsEsm, MdxJsxFlowElement } from 'mdast-util-mdx'
import { createDefaultImportNode } from './mdastUtils'
export function FileTextMdxPlugin() {
return transformer
function transformer(tree: Root, file: any) {
const children = tree.children
const addImports: MdxjsEsm[] = []
children.forEach((child, index) => {
// find jsx node like: <FileText src="srcValue" syntax="syntaxValue" />
if (child.type === 'mdxJsxFlowElement' && child.name === 'FileText') {
const srcAttr = child.attributes.find(
(attr) =>
attr.type === 'mdxJsxAttribute' &&
attr.name === 'src' &&
typeof attr.value === 'string'
)
const srcValue = srcAttr?.value as string
const syntaxAttr = child.attributes.find(
(attr) =>
attr.type === 'mdxJsxAttribute' &&
attr.name === 'syntax' &&
typeof attr.value === 'string'
)
const syntaxValue = syntaxAttr?.value as string
if (srcValue && syntaxValue) {
const nextIndex = addImports.length
const varName = `_fileText${nextIndex}`
// add import:
// import varName from "${srcValue}?raw"
addImports.push(
createDefaultImportNode({
name: varName,
from: `${srcValue}?raw`,
})
)
// replace this node with:
// <FileText text={varName} syntax="syntaxValue" />
children.splice(
index,
1,
createFileTextJSXNode({
text: varName,
syntax: syntaxValue,
})
)
}
}
})
children.unshift(...addImports)
}
}
/**
* create mdast node for expression:
* <FileText text={text} syntax="syntax" />
* checkout the parsed node structure in https://mdxjs.com/playground/
*/
function createFileTextJSXNode({
text,
syntax,
}: {
text: string
syntax: string
}): MdxJsxFlowElement {
return {
type: 'mdxJsxFlowElement',
name: 'FileText',
data: {
_mdxExplicitJsx: true,
} as any,
children: [],
attributes: [
{
type: 'mdxJsxAttribute',
name: 'text',
value: {
type: 'mdxJsxAttributeValueExpression',
value: text,
data: {
estree: {
type: 'Program',
sourceType: 'module',
body: [
{
type: 'ExpressionStatement',
expression: {
type: 'Identifier',
name: text,
},
},
],
},
},
},
},
{
type: 'mdxJsxAttribute',
name: 'syntax',
value: syntax,
},
],
}
}