mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-10 23:02:56 +02:00
perf(mdx-loader): cache mdx/remark compiler instances (#4997)
* (mdx-loader) only create mdx compiler once per webpack config * type fixes * fix path * remove assertion * docs: add missing Tab/TabItem imports * fixup Co-authored-by: slorber <lorber.sebastien@gmail.com> Co-authored-by: Josh-Cena <sidachen2003@gmail.com>
This commit is contained in:
parent
bb55586c20
commit
949a72e6a5
3 changed files with 61 additions and 45 deletions
10
packages/docusaurus-mdx-loader/src/deps.d.ts
vendored
10
packages/docusaurus-mdx-loader/src/deps.d.ts
vendored
|
@ -10,8 +10,7 @@ declare module '@mdx-js/mdx' {
|
|||
import type {Processor} from 'unified';
|
||||
import type {RemarkOrRehypePlugin} from '@docusaurus/mdx-loader';
|
||||
|
||||
namespace mdx {
|
||||
interface Options {
|
||||
export interface Options {
|
||||
filepath?: string;
|
||||
skipExport?: boolean;
|
||||
wrapExport?: string;
|
||||
|
@ -19,10 +18,9 @@ declare module '@mdx-js/mdx' {
|
|||
rehypePlugins?: RemarkOrRehypePlugin[];
|
||||
}
|
||||
|
||||
function sync(content: string, options?: Options): string;
|
||||
function createMdxAstCompiler(options?: Options): Processor;
|
||||
function createCompiler(options?: Options): Processor;
|
||||
}
|
||||
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,
|
||||
|
|
|
@ -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<string | Options, [Processor, Options]>();
|
||||
|
||||
type Options = MDXOptions & {
|
||||
staticDirs: string[];
|
||||
siteDir: string;
|
||||
|
@ -124,6 +133,7 @@ export default async function mdxLoader(
|
|||
|
||||
const hasFrontMatter = Object.keys(frontMatter).length > 0;
|
||||
|
||||
if (!compilerCache.has(this.query)) {
|
||||
const options: Options = {
|
||||
...reqOptions,
|
||||
remarkPlugins: [
|
||||
|
@ -150,12 +160,20 @@ export default async function mdxLoader(
|
|||
...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';
|
||||
|
||||
|
|
|
@ -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;
|
||||
return (root) => {
|
||||
let transformed = false;
|
||||
let alreadyImported = false;
|
||||
const transformer: Transformer = (root) => {
|
||||
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` ㄟ(▔,▔)ㄏ
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue