如何分部分导出大型 Next.js 静态站点?

Tri*_*123 10 javascript node.js reactjs next.js

我在我的网站上使用 Next.js Static HTML Export,该网站有 1000 万个静态页面,但在构建应用程序时遇到了内存问题。

是否有可能将其分部分导出,例如第一个版本中的 100k 页,然后是第二个版本中的 100k 页,依此类推?

我不想使用Incremental Static RegenerationgetServerSideProps削减成本。

该网站使用 MongoDB 只有两个页面主页和帖子页面:

index.js
[postPage].js
Run Code Online (Sandbox Code Playgroud)

在主页中我使用了这段代码:

export async function getStaticProps() {
  const { db } = await connectToDatabase();

  const postsFeed = await db
    .collection("myCollection")
    .aggregate([{ $sample: { size: 100 } }])
    .toArray();

  return {
    props: {
      postsFeed: JSON.parse(JSON.stringify(postsFeed)),
    },
  };
}
Run Code Online (Sandbox Code Playgroud)

在帖子页面中我使用了以下代码:

export async function getStaticPaths() {

  const { db } = await connectToDatabase();
  const posts = await db
    .collection("myCollection")
    .find({})
    .toArray();

  const paths = posts.map((data) => {
    return {
      params: {
        postPage: data.slug.toString(),
      }
    }
  })

  return {
    paths,
    fallback: 'blocking'
  }
}

export async function getStaticProps(context) {

  const postSlug = context.params.postPage;

  const { db } = await connectToDatabase();

  const posts = await db
    .collection("myCollection")
    .find({ slug: { $eq: postsSlug } })
    .toArray();

  const postsFeed = await db
    .collection("myCollection")
    .aggregate([{ $sample: { size: 100 } }])
    .toArray();

  return {
    props: {
      posts: JSON.parse(JSON.stringify(posts)),
      postsFeed: JSON.parse(JSON.stringify(postsFeed)),
    },
  };
}
Run Code Online (Sandbox Code Playgroud)

die*_*edu 5

似乎不是处理批量静态页面的内置选项https://github.com/vercel/next.js/discussions/14929

我只能考虑使用 bash 脚本来划分工作,在该脚本中设置一个 env 变量并在获取数据以生成路径的代码中使用它,然后运行构建命令与需要拆分的部分一样多的次数数据,在每次迭代中将生成的文件移动到另一个目录,该目录将成为您的合并输出。

COUNTER=1
PARTS=100 # change it to control number of parts
while [ $COUNTER -lt $PARTS ]; do
    let COUNTER=COUNTER+1
     CURRENT=$COUNTER PARTS=$PARTS next build
    # move generated files to another directory
done
Run Code Online (Sandbox Code Playgroud)

在你得到的getStaticPaths

export async function getStaticPaths() {
  const currentPercentage = process.env.CURRENT/process.env.PARTS
  // logic to fetch the corresponding current percentage of the data
  // 1% when there are 100 parts, 0.5% when 200 parts, etc.
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果数据经常更改,您将看到不正确的结果,例如重复的页面或跳过的页面,因为运行脚本时每个分页都会在不同的时刻发生。我相信您可以创建一个辅助节点(或其他语言)脚本来更好地处理大量记录(也许以简化的方式),并为每个数据块生成 JSON 文件以使用它们,getStaticPaths而不是直接从数据库获取它们。