kentcdodds / mdx-bundler

🦤 Give me MDX/TSX strings and I'll give you back a component you can render. Supports imports!
MIT License
1.78k stars 75 forks source link

mdx-bundler doesn't work in NextJS' getServerSideProps when deployed on Vercel: The package "esbuild-linux-64" could not be found, and is needed by esbuild. #126

Open dominik-sfl opened 3 years ago

dominik-sfl commented 3 years ago

Relevant code or config

Just copy pasted from the mdx-bundler github example:

import { bundleMDX } from "mdx-bundler";
import * as React from "react";
import { getMDXComponent } from "mdx-bundler/client";

export default function Home({ code, frontmatter }) {
  // it's generally a good idea to memoize this function call to
  // avoid re-creating the component every render.
  const Component = React.useMemo(() => getMDXComponent(code), [code]);
  return (
    <>
      <header>
        <h1>{frontmatter.title}</h1>
        <p>{frontmatter.description}</p>
      </header>
      <main>
        <Component />
      </main>
    </>
  );
}

export const getServerSideProps = async () => {
  const mdxSource = `
---
title: Example Post
published: "2021-02-13"
description: This is some description
---

# Wahoo

import Demo from './demo'

Here's a **neat** demo:

<Demo />
`.trim();

  const result = await bundleMDX(mdxSource, {
    files: {
      "./demo.tsx": `
import * as React from 'react'

function Demo() {
  return <div>Neat demo!</div>
}

export default Demo
    `,
    },
  });

  const { code, frontmatter } = result;

  return { props: { code, frontmatter } };
};

What you did:

I'm trying to use mdx-bundler server side in NextJS' getServerSideProps. Everything works fine when I keep things static (with getStaticProps), but I get a 500 error when I try to access the same page using getServerSideProps. All works on my machine (both in dev & when built), but not on Vercel.

What happened:

2021-11-12T10:39:25.261Z 57ade67b-7c54-4c70-bf8a-70c038937a29 ERROR Error: The package "esbuild-linux-64" could not be found, and is needed by esbuild. If you are installing esbuild with npm, make sure that you don't specify the "--no-optional" flag. The "optionalDependencies" package.json feature is used by esbuild to install the correct binary executable for your current platform. at generateBinPath (/var/task/node_modules/esbuild/lib/main.js:1643:15) at esbuildCommandAndArgs (/var/task/node_modules/esbuild/lib/main.js:1699:11) at ensureServiceIsRunning (/var/task/node_modules/esbuild/lib/main.js:1856:25) at Object.build (/var/task/node_modules/esbuild/lib/main.js:1749:26) at bundleMDX (/var/task/node_modules/mdx-bundler/dist/index.js:215:33) at async mdx2 (/var/task/packages/site/.next/server/pages/api/mdx2.js:93:18) at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils.js:102:9) at async Server.handleApiRequest (/var/task/node_modules/next/dist/server/next-server.js:1014:9) at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:901:37) at async Router.execute (/var/task/node_modules/next/dist/server/router.js:210:32)

Reproduction repository:

https://github.com/dominik-sfl/next-mdx-bundler Demo here: https://next-mdx-bundler.vercel.app/

Problem description:

mdx-bundler works in Next.JS on Vercel with getStaticProps, but not with getServerSideProps. Everything fine on my local machine.

Suggested solution:

Arcath commented 3 years ago

What OS is your machine running? Do you have a package-lock.json?

dominik-sfl commented 3 years ago

@Arcath macOS Big Sur 11.4

I do have a yarn.lock file right here.

dominik-sfl commented 3 years ago

I also added a 3rd page to the reproduction repository with this in getServerSideProps:

if(process.platform === "win32"){
  process.env.ESBUILD_BINARY_PATH = path.join(process.cwd(), 'node_modules', 'esbuild', 'esbuild.exe')
}else{
  process.env.ESBUILD_BINARY_PATH = path.join(process.cwd(), 'node_modules', 'esbuild', 'bin', 'esbuild')
}

I thought it might have to do with the ESBUILD_BINARY_PATH, but it gives me the same error about esbuild-linux-64.

Also did another reproduction using npm instead of yarn, but it's exactly the same problem:

with NPM : https://github.com/dominik-sfl/next-mdx-bundler-npm Demo with NPM : https://next-mdx-bundler-npm.vercel.app/

shimamooo commented 3 years ago

Issue seems to appear in 6.0.3 as well. Works exceptionally well in getStaticProps but chokes on getServerSideProps

dominik-sfl commented 3 years ago

@AnthonyKuang Yes, exactly. Downgrading esbuild seems to work for me though. Downgraded to 0.12.09 and it's working again.

jonhilt commented 2 years ago

I must confess to not really knowing what "NFT" is, but I'm guessing this may be relevant?

https://github.com/vercel/nft/pull/262

(I'm also running into the same issue, found that pull request and related issues whilst searching for a solution :))

mihaiandrei97 commented 12 months ago

The fix for me was adding "esbuild": "^0.19.5",