Vercel: ОШИБКА Ошибка: не удалось найти пакет «esbuild-linux-64», который необходим esbuild

#reactjs #next.js #vercel #mdxjs

Вопрос:

Надеюсь, вы все хорошо проводите время. Я работаю над простым приложением NextJS, в котором я хочу иметь несколько поддоменов. Я развертываю приложение на vercel.

Что делает мое приложение, так это то, что у него есть простая текстовая область, в которой вы пишете многомерные выражения, нажимаете кнопку публикации, и это сохранит это многомерное выражение в firebase firestore. Под текстовой областью отображается список всех страниц, которые были опубликованы ранее.

Приложение отображает список всех страниц, например, с именем страницы, которая генерируется случайным образом в качестве поддомена, в то время как фактический домен появляется позже, как показано ниже.

 a-mdx-page.mydomain.app
 

Когда я открываю этот URL-адрес, он извлекает многомерные выражения страницы из firestore и использует пакет next-mdx-remote для сериализации и отображения многомерных выражений. Причина использования пакета next-mdx-remote заключается в том, что мы можем добавлять компоненты react в MDX, и он может отображаться как обычные компоненты react. У меня уже есть пользовательский домен, потому что вы не можете иметь поддомен поверх свободного поддомена в vercel free deployment.

На локальном хосте все работает нормально, и все так, как должно быть, но проблема в том, что когда я развертываю код на Vercel и перехожу к поддомену, он показывает ОШИБКУ 500 на веб-сайте и показывает следующую ошибку в журналах.

 [GET] /   21:21:03:30

2021-10-24T16:21:04.018Z    8e52d5da-ff1f-4840-a09b-199233834a5d    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.transform (/var/task/node_modules/esbuild/lib/main.js:1751:37)
    at serialize (/var/task/node_modules/next-mdx-remote/dist/serialize.js:287:43)
    at async getServerSideProps (/var/task/.next/server/pages/index.js:261:25)
    at async Object.renderToHTML (/var/task/node_modules/next/dist/server/render.js:428:24)
    at async doRender (/var/task/node_modules/next/dist/server/next-server.js:1144:38)
    at async /var/task/node_modules/next/dist/server/next-server.js:1236:28
    at async /var/task/node_modules/next/dist/server/response-cache.js:64:36 {
  page: '/'
}
RequestId: 8e52d5da-ff1f-4840-a09b-199233834a5d Error: Runtime exited with error: exit status 1
Runtime.ExitError
 

Насколько я понимаю, функция next-mdx-remote serialize использует в нем esbuild, и когда я развертываю приложение на vercel npm, оно просто не загружает пакет, специфичный для платформы, но, возможно, я ошибаюсь.

Я пытался найти решение для этого, но нет никаких ответов, которые мне помогли.

Ниже приведен весь код, который использует приложение.

 import { useState } from "react"
import { collection, doc, getDoc, getDocs, setDoc } from "firebase/firestore"
import matter from "gray-matter"
import { MDXRemote } from "next-mdx-remote"
import { serialize } from "next-mdx-remote/serialize"
import {
  uniqueNamesGenerator,
  adjectives,
  colors,
  animals,
} from "unique-names-generator"

import { db } from "../utils/fire-client"
import Layout from "../components/Layout"
import { HOSTNAME } from "../config"
import MDXComponents from "../components/mdx"

export default function Index({ posts, isPage = false, mdxSource }) {
  const [mdxCode, setMdxCode] = useState("# THIS IS MDX")
  const [message, setMessage] = useState("")

  const addPageToCollection = async (name, content) => {
    const pagesCollection = collection(db, "pages")
    await setDoc(doc(pagesCollection, name), {
      name,
      content,
    })
  }

  function publishPage() {
    const randomName = uniqueNamesGenerator({
      dictionaries: [adjectives, colors, animals],
    })

    addPageToCollection(randomName, mdxCode)
    setMessage(
      "New Page Added: "   randomName   "nReload page To see it in the list"
    )

    setTimeout(() => {
      setMessage("")
    }, 5000)
  }

  return (
    <Layout>
      {isPage ? (
        <>
          <header>
            <nav>
              <a href={"http://"   HOSTNAME}>
                <a>👈 Go back home</a>
              </a>
            </nav>
          </header>
          <main>
            <MDXRemote {...mdxSource} components={MDXComponents} />
          </main>
        </>
      ) : (
        <>
          <h1>Home Page</h1>

          <textarea
            name="mdxCode"
            id="mdxCode"
            value={mdxCode}
            onChange={(e) => setMdxCode(e.target.value)}
            className="w-full h-1/2 border-2 border-gray-400 p-2"
          />

          <button className="btn btn-primary" onClick={publishPage}>
            Publish
          </button>

          <div>{message}</div>

          <ul>
            <div className="mt-4 font-bold">Pages List</div>
            {posts.map((post) => (
              <li key={post.name}>
                <a href={`http://${post.name}.${HOSTNAME}`}>{post.name}</a>
              </li>
            ))}
          </ul>
        </>
      )}
    </Layout>
  )
}

export async function getServerSideProps({ req, res }) {
  const host = req.headers.host.split(".")

  if (host[0] !== HOSTNAME.split(".")[0] amp;amp; host[0] !== "www") {
    const docRef = doc(db, "pages", host[0])
    const docSnap = await getDoc(docRef)

    if (docSnap.exists()) {
      const { content, data } = matter(docSnap.data().content)
      const mdxSource = await serialize(content, {
        // Optionally pass remark/rehype plugins
        mdxOptions: {
          remarkPlugins: [],
          rehypePlugins: [],
        },
        scope: data,
      })

      if (mdxSource) {
        return {
          props: {
            isPage: true,
            mdxSource,
          },
        }
      }
    } else {
      return {
        props: {
          redirect: {
            destination: "/",
          },
        },
      }
    }
  }

  const pagesCollection = collection(db, "pages")
  const pagesSnapshot = await getDocs(pagesCollection)
  const pagesList = pagesSnapshot.docs.map((doc) => doc.data())

  if (pagesList.length > 0) {
    return {
      props: {
        posts: pagesList,
      },
    }
  }

  return { props: { posts } }
}
 

Ответ №1:

Обновите esbuild до версии 0.13.4 или выше

 npm i -D esbuild@0.13.4
 

Смотрите: https://github.com/evanw/esbuild/releases/tag/v0.13.4