Skip to content

Commit

Permalink
perf(mdx-loader): cache mdx/remark compiler instances (#4997)
Browse files Browse the repository at this point in the history
* (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>
  • Loading branch information
3 people authored Mar 31, 2022
1 parent bb55586 commit 949a72e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 45 deletions.
22 changes: 10 additions & 12 deletions packages/docusaurus-mdx-loader/src/deps.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
75 changes: 47 additions & 28 deletions packages/docusaurus-mdx-loader/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -23,18 +23,27 @@ 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],
beforeDefaultRemarkPlugins: [],
beforeDefaultRehypePlugins: [],
};

const compilerCache = new Map<string | Options, [Processor, Options]>();

type Options = MDXOptions & {
staticDirs: string[];
siteDir: string;
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -214,6 +232,7 @@ ${assets ? `export const assets = ${createAssetsExportCode(assets)};` : ''}
`;

const code = `
${pragma}
import React from 'react';
import { mdx } from '@mdx-js/react';
Expand Down
9 changes: 4 additions & 5 deletions packages/docusaurus-remark-plugin-npm2yarn/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand All @@ -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` ㄟ(▔,▔)ㄏ
Expand Down

0 comments on commit 949a72e

Please sign in to comment.