export default async function mdxLoader()

in packages/docusaurus-mdx-loader/src/index.ts [120:244]


export default async function mdxLoader(
  this: LoaderContext<Options>,
  fileString: string,
): Promise<void> {
  const callback = this.async();
  const filePath = this.resourcePath;
  const reqOptions = this.getOptions() ?? {};

  const {frontMatter, content: contentWithTitle} = parseFrontMatter(fileString);

  const {content, contentTitle} = parseMarkdownContentTitle(contentWithTitle, {
    removeContentTitle: reqOptions.removeContentTitle,
  });

  const hasFrontMatter = Object.keys(frontMatter).length > 0;

  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 ?? []),
      ],
      rehypePlugins: [
        ...(reqOptions.beforeDefaultRehypePlugins ?? []),
        ...DEFAULT_OPTIONS.rehypePlugins,
        ...(reqOptions.rehypePlugins ?? []),
      ],
    };
    compilerCache.set(this.query, [createCompiler(options), options]);
  }

  const [compiler, options] = compilerCache.get(this.query)!;

  let result: string;
  try {
    result = await compiler
      .process({
        contents: content,
        path: this.resourcePath,
      })
      .then((res) => res.toString());
  } catch (err) {
    return callback(err as Error);
  }

  // MDX partials are MDX files starting with _ or in a folder starting with _
  // Partial are not expected to have associated metadata files or front matter
  const isMDXPartial = options.isMDXPartial?.(filePath);
  if (isMDXPartial && hasFrontMatter) {
    const errorMessage = `Docusaurus MDX partial files should not contain front matter.
Those partial files use the _ prefix as a convention by default, but this is configurable.
File at ${filePath} contains front matter that will be ignored:
${JSON.stringify(frontMatter, null, 2)}`;

    if (!options.isMDXPartialFrontMatterWarningDisabled) {
      const shouldError = process.env.NODE_ENV === 'test' || process.env.CI;
      if (shouldError) {
        return callback(new Error(errorMessage));
      }
      logger.warn(errorMessage);
    }
  }

  function getMetadataPath(): string | undefined {
    if (!isMDXPartial) {
      // Read metadata for this MDX and export it.
      if (options.metadataPath && typeof options.metadataPath === 'function') {
        return options.metadataPath(filePath);
      }
    }
    return undefined;
  }

  const metadataPath = getMetadataPath();
  if (metadataPath) {
    this.addDependency(metadataPath);
  }

  const metadataJsonString = metadataPath
    ? await readMetadataPath(metadataPath)
    : undefined;

  const metadata = metadataJsonString
    ? JSON.parse(metadataJsonString)
    : undefined;

  const assets =
    reqOptions.createAssets && metadata
      ? reqOptions.createAssets({frontMatter, metadata})
      : undefined;

  const exportsCode = `
export const frontMatter = ${stringifyObject(frontMatter)};
export const contentTitle = ${stringifyObject(contentTitle)};
${metadataJsonString ? `export const metadata = ${metadataJsonString};` : ''}
${assets ? `export const assets = ${createAssetsExportCode(assets)};` : ''}
`;

  const code = `
${pragma}
import React from 'react';
import { mdx } from '@mdx-js/react';

${exportsCode}
${result}
`;

  return callback(null, code);
}