Skip to content

[Bug]: (v7) @mdx-js/rollup: Unexpected FunctionDeclaration in code: only import/exports are supported. Error for a custom vite server. #12168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
zdunecki opened this issue Oct 21, 2024 · 4 comments

Comments

@zdunecki
Copy link

zdunecki commented Oct 21, 2024

What version of React Router are you using?

v7

Steps to Reproduce

  1. Install react-router (7.0.0-pre.1)
  2. Install @mdx-js/rollup (tested with ^3.1.0 and ^3.0.1)
  3. Create a custom vite server and add plugins for mdx + react-router
  4. Run custom vite server

Demo: https://stackblitz.com/edit/vitejs-vite-xmllxz?file=package.json

Expected Behavior

As a user, I expect the same behaviour for a custom vite server as a react-router one when using a mdx plugin.

Actual Behavior

When I run a react-router via a custom vite server with @mdx-js/rollup plugin I got error:

[plugin:@mdx-js/rollup] Unexpected `FunctionDeclaration` in code: only import/exports are supported
/home/projects/vitejs-vite-xmllxz/Post.mdx:2:1
1  |  import {jsxDEV as _jsxDEV} from "react/jsx-dev-runtime";
2  |  function _createMdxContent(props) {
   |   ^
3  |    const _components = {
4  |      h1: "h1",

Demo: https://stackblitz.com/edit/vitejs-vite-xmllxz?file=package.json

@zdunecki zdunecki added the bug label Oct 21, 2024
@zdunecki
Copy link
Author

I fixed that by removing mdx plugin from vite.config.ts. Since it's reasonable it would be great to have better developer experience here IMO.

Additionally react-router/remix requires configFile inside vite createServer and this leds to create vite config which is not really needed (below stackblitz demo). Because of that fact I did mistake to pass mdx plugin twice.

Here's a demo: https://stackblitz.com/edit/vitejs-vite-mhy6h5?file=vite.config.ts

@DovydasNavickas
Copy link

I've updated your demo and it worked.
I've removed all of the options from server.ts and then it takes them from vite.config.ts by default.

vite.config

import { reactRouter } from '@react-router/dev/vite';
import { defineConfig } from 'vite';
import mdx from '@mdx-js/rollup';

export default defineConfig({
  plugins: [mdx(), reactRouter()],
  optimizeDeps: {
    include: ['react/jsx-runtime'],
  },
});

server.ts

import { createServer } from 'vite';

async function startServer() {
  const server = await createServer({});

  await server.listen(5173);
  server.printUrls();
  server.bindCLIShortcuts({ print: true });
}

startServer();

StackBlitz doesn't let me save some why, so no link for the demo.

@brophdawg11 brophdawg11 added the v7 label Oct 23, 2024
@pcattori
Copy link
Contributor

Since it's reasonable it would be great to have better developer experience here IMO.

Agreed! I'm working on it 👍

@markdalgleish
Copy link
Member

markdalgleish commented Apr 29, 2025

Thanks for raising this issue.

The specific issue raised here is caused by the @mdx-js/rollup plugin being used twice. You're seeing this error message because the 2nd plugin instance is trying to parse the JS output from the 1st plugin instance as if it was MDX. This is happening in your example because it's merging the plugins arrays from both the inline config and vite.config.ts, resulting in duplicated plugins.

As you noted, the React Router plugin currently requires the presence of a Vite config file. This is so that we can load a fresh copy of all plugins to pass to our child compiler, which is needed to support non-JS routes (like MDX) and so we can ensure code is run through your plugins before analysing code for Split Route Modules support.

The correct usage to avoid this issue is what @DovydasNavickas posted above, avoiding inline config and using vite.config.ts instead. As of right now, this is expected behaviour. Ideally we'd like to drop the requirement for having a vite.config.ts file, but this will require some re-work and would likely be a breaking change. In the meantime, this behaviour is not considered a bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants