diff --git a/packages/docusaurus-mdx-loader/src/deps.d.ts b/packages/docusaurus-mdx-loader/src/deps.d.ts index 78beb9c74562..f4adca18b3c8 100644 --- a/packages/docusaurus-mdx-loader/src/deps.d.ts +++ b/packages/docusaurus-mdx-loader/src/deps.d.ts @@ -10,19 +10,17 @@ declare module '@mdx-js/mdx' { import type {Processor} from 'unified'; import type {RemarkOrRehypePlugin} from '@docusaurus/mdx-loader'; - namespace mdx { - interface Options { - filepath?: string; - skipExport?: boolean; - wrapExport?: string; - remarkPlugins?: RemarkOrRehypePlugin[]; - rehypePlugins?: RemarkOrRehypePlugin[]; - } - - function sync(content: string, options?: Options): string; - function createMdxAstCompiler(options?: Options): Processor; - function createCompiler(options?: Options): Processor; + export interface Options { + filepath?: string; + skipExport?: boolean; + wrapExport?: string; + remarkPlugins?: RemarkOrRehypePlugin[]; + rehypePlugins?: RemarkOrRehypePlugin[]; } + + export function sync(content: string, options?: Options): string; + export function createMdxAstCompiler(options?: Options): Processor; + export function createCompiler(options?: Options): Processor; export default function mdx( content: string, options?: mdx.Options, diff --git a/packages/docusaurus-mdx-loader/src/index.ts b/packages/docusaurus-mdx-loader/src/index.ts index 34cea4978d23..8d6e55c79c5e 100644 --- a/packages/docusaurus-mdx-loader/src/index.ts +++ b/packages/docusaurus-mdx-loader/src/index.ts @@ -6,7 +6,7 @@ */ import fs from 'fs-extra'; -import mdx from '@mdx-js/mdx'; +import {createCompiler} from '@mdx-js/mdx'; import logger from '@docusaurus/logger'; import emoji from 'remark-emoji'; import { @@ -23,11 +23,18 @@ import transformImage from './remark/transformImage'; import transformLinks from './remark/transformLinks'; import type {MDXOptions} from '@docusaurus/mdx-loader'; import type {LoaderContext} from 'webpack'; +import type {Processor} from 'unified'; const { loaders: {inlineMarkdownImageFileLoader}, } = getFileLoaderUtils(); +const pragma = ` +/* @jsxRuntime classic */ +/* @jsx mdx */ +/* @jsxFrag mdx.Fragment */ +`; + const DEFAULT_OPTIONS: MDXOptions = { rehypePlugins: [], remarkPlugins: [unwrapMdxCodeBlocks, emoji, headings, toc], @@ -35,6 +42,8 @@ const DEFAULT_OPTIONS: MDXOptions = { beforeDefaultRehypePlugins: [], }; +const compilerCache = new Map(); + type Options = MDXOptions & { staticDirs: string[]; siteDir: string; @@ -124,38 +133,47 @@ export default async function mdxLoader( const hasFrontMatter = Object.keys(frontMatter).length > 0; - const options: Options = { - ...reqOptions, - remarkPlugins: [ - ...(reqOptions.beforeDefaultRemarkPlugins ?? []), - ...DEFAULT_OPTIONS.remarkPlugins, - [ - transformImage, - { - staticDirs: reqOptions.staticDirs, - siteDir: reqOptions.siteDir, - }, + if (!compilerCache.has(this.query)) { + const options: Options = { + ...reqOptions, + remarkPlugins: [ + ...(reqOptions.beforeDefaultRemarkPlugins ?? []), + ...DEFAULT_OPTIONS.remarkPlugins, + [ + transformImage, + { + staticDirs: reqOptions.staticDirs, + siteDir: reqOptions.siteDir, + }, + ], + [ + transformLinks, + { + staticDirs: reqOptions.staticDirs, + siteDir: reqOptions.siteDir, + }, + ], + ...(reqOptions.remarkPlugins ?? []), ], - [ - transformLinks, - { - staticDirs: reqOptions.staticDirs, - siteDir: reqOptions.siteDir, - }, + rehypePlugins: [ + ...(reqOptions.beforeDefaultRehypePlugins ?? []), + ...DEFAULT_OPTIONS.rehypePlugins, + ...(reqOptions.rehypePlugins ?? []), ], - ...(reqOptions.remarkPlugins ?? []), - ], - rehypePlugins: [ - ...(reqOptions.beforeDefaultRehypePlugins ?? []), - ...DEFAULT_OPTIONS.rehypePlugins, - ...(reqOptions.rehypePlugins ?? []), - ], - filepath: filePath, - }; + }; + compilerCache.set(this.query, [createCompiler(options), options]); + } + + const [compiler, options] = compilerCache.get(this.query)!; let result: string; try { - result = await mdx(content, options); + result = await compiler + .process({ + contents: content, + path: this.resourcePath, + }) + .then((res) => res.toString()); } catch (err) { return callback(err as Error); } @@ -214,6 +232,7 @@ ${assets ? `export const assets = ${createAssetsExportCode(assets)};` : ''} `; const code = ` +${pragma} import React from 'react'; import { mdx } from '@mdx-js/react'; diff --git a/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts b/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts index b16949dd72e4..19c03c4b21c5 100644 --- a/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts +++ b/packages/docusaurus-remark-plugin-npm2yarn/src/index.ts @@ -6,7 +6,7 @@ */ import type {Code, Content, Literal} from 'mdast'; -import type {Plugin, Transformer} from 'unified'; +import type {Plugin} from 'unified'; import type {Node, Parent} from 'unist'; import visit from 'unist-util-visit'; import npmToYarn from 'npm-to-yarn'; @@ -61,9 +61,9 @@ const nodeForImport: Literal = { const plugin: Plugin<[PluginOptions?]> = (options = {}) => { const {sync = false} = options; - let transformed = false; - let alreadyImported = false; - const transformer: Transformer = (root) => { + return (root) => { + let transformed = false; + let alreadyImported = false; visit(root, (node: Node) => { if (isImport(node) && node.value.includes('@theme/Tabs')) { alreadyImported = true; @@ -87,7 +87,6 @@ const plugin: Plugin<[PluginOptions?]> = (options = {}) => { (root as Parent).children.unshift(nodeForImport); } }; - return transformer; }; // To continue supporting `require('npm2yarn')` without the `.default` ㄟ(▔,▔)ㄏ