Next.js Discord

Discord Forum

turbopack + mdx custom plugins: module not found

Unanswered
Sloth bear posted this in #help-forum
Open in Discord
Sloth bearOP
I'm trying to transition to turbopack from a webpack config that works (but I'm hoping to see a performance increase).

Here is my next.config.mjs

const nextConfig = {
  experimental: {
    turbo: {
      rules: {
        "*.mdx": ["./build_scripts/remark/remarkTurbopackConfig.mjs"],
     // ... *snip*


./build_scripts/remark/remarkTurbopackConfig.mjs:
// @ts-check
import mdxLoader from "@mdx-js/loader";
import { remarkOptions } from "./remarkOptions.mjs";

/**
 * @typedef {import('@mdx-js/loader').Options} RemarkOptions
 * @typedef {import('webpack').LoaderContext<RemarkOptions>} LoaderContext
 * @typedef {Parameters<LoaderContext['getOptions']>} GetOptionsParams
 * @this {LoaderContext}
 * @param {string} code
 */
export default function remarkTurbopackConfig(code) {
  const prevGetOptions = this.getOptions.bind(this);
  this.getOptions = /** @type {LoaderContext['getOptions']} */ (
    function getOptions(/** @type {GetOptionsParams} */ ...args) {
      return {
        ...prevGetOptions(...args),
        ...remarkOptions,
      };
    }
  );

  mdxLoader.call(this, code);
}


When trying to load an .mdx file, I get:

Cannot find module './build_scripts/remark/remarkTurbopackConfig.mjs'

I tried:
- renaming the extensions to .js
- removing the extension from the config to fit the model shown in [the docs](https://turbo.build/pack/docs/features/customizing-turbopack)

2 Replies

Sloth bearOP
I don't think it matters, but just for completeness and in case it helps someone in the future, here are the options:
./build_scripts/remark/remarkOptions.mjs:
// @ts-check
import remarkGfm from "remark-gfm";
import rehypePrism from "rehype-prism-plus";
import rehypeSlug from "rehype-slug";
import remarkUnwrapImages from "remark-unwrap-images";
import remarkFrontmatter from "remark-frontmatter";
import remarkMdxGdSchool from "./remark-mdx-gdschool.mjs";

/** @type {NonNullable<import('@next/mdx').NextMDXOptions['options']>} */
export const remarkOptions = {
  remarkPlugins: [
    remarkGfm,
    remarkFrontmatter,
    remarkUnwrapImages,
    remarkMdxGdSchool,
  ],
  rehypePlugins: [rehypeSlug, [rehypePrism, { showLineNumbers: true }]],
};


(As for ./remark-mdx-gdschool.mjs it's our own plugin, developed for our specific needs)
And for comparison, here is the non-turbopack config that works:
// @ts-check
import createMDX from "@next/mdx";
import { remarkOptions } from "./build_scripts/remark/remarkOptions.mjs";

/** @type {import('next').NextConfig} */
const nextConfig = {
  pageExtensions: ["mdx", "ts", "tsx"],
 
};

const withMDX = createMDX({
  options: remarkOptions,
});

export default withMDX(nextConfig);