From 51312f29eb1364c0cbdc4e689a31cc9e810fc3c9 Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Tue, 23 Feb 2021 11:05:42 +0100 Subject: [PATCH] Cache MDX compiler in the Webpack loader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new MDX compiler was created for every file that’s processed. This means that any initialization logic in remark or rehype plugins was always run for every file. By reusing the MDX compiler, remark and rehype plugins can run heavy setup logic once, just like when they are called by unified directly. --- packages/loader/index.js | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/loader/index.js b/packages/loader/index.js index 383f3434f..6c1457d47 100644 --- a/packages/loader/index.js +++ b/packages/loader/index.js @@ -1,27 +1,39 @@ const {getOptions} = require('loader-utils') -const mdx = require('@mdx-js/mdx') +const {createCompiler} = require('@mdx-js/mdx') const DEFAULT_RENDERER = ` import React from 'react' import {mdx} from '@mdx-js/react' ` +const pragma = ` +/* @jsxRuntime classic */ +/* @jsx mdx */ +/* @jsxFrag mdx.Fragment */ +` + +const compilerCache = new Map() + module.exports = async function (content) { + if (!compilerCache.has(this.query)) { + const {renderer = DEFAULT_RENDERER, ...opts} = getOptions(this) + compilerCache.set(this.query, [renderer, createCompiler(opts)]) + } + const callback = this.async() - const options = Object.assign({}, getOptions(this), { - filepath: this.resourcePath - }) + const [renderer, compiler] = compilerCache.get(this.query) let result try { - result = await mdx(content, options) + result = await compiler.process({ + contents: content, + path: this.resourcePath + }) } catch (err) { return callback(err) } - const {renderer = DEFAULT_RENDERER} = options - - const code = `${renderer}\n${result}` + const code = `${renderer}${pragma}${result}` return callback(null, code) }