如何使用Next.js通过CDN提供静态生成的页面



我正在尝试将Next.js(9.5.2(用于服务器端渲染和静态站点生成。SSR使用assetPrefix对我来说很好。我能够在CloudFront上托管我的所有静态资产。然而,我不确定托管静态页面的最佳方式是什么。

我面临两个问题。

  1. assetPrefix不应用于SSG页面。所以指向JS/CSS的链接将类似于<link rel="preload" href="/_next/static/css/styles.31b6de8d.chunk.css" as="style"/>
  2. 假设我们在CDN上托管生成的HTML,并且我们能够使用assetPrefix为资产提供服务,那么我如何在getStaticPath中使用带有fallback: true的Next.js增量静态再生。我的理解是,如果找不到相应的HTML,页面将在服务器端生成

感谢大家的帮助。

我对自己的问题有部分答案。

对于问题1

这个问题是我自己的错。assetPrefix适用于SSR,但不适用于SSG,因为我没有正确地传递环境变量。在我的情况下,我们有两个不同的CDN URL用于生产和暂存。所以我在next.config.js中有如下内容。因为MY_ENV是从启动我的应用程序的PM2传入的,所以可以保证当Next.js需要访问next.config.js时,MY_ENV始终可用。

// next.config.js
const isProd = process.env.MY_ENV === 'production';
const isStaging = process.env.MY_ENV === 'staging';
const isDevelopment = process.env.MY_ENV === 'development';
if (isProd) {
assetPrefix = 'https://mycdn.cloudfront.net/';
} else if (isStaging) {
assetPrefix = 'https://mycdn.cloudfront.net/staging';
}

然而,当我为静态页面运行next build时,构建步骤不使用PM2,因此MY_ENV不可用。为了使它发挥作用,我需要使用不同的变量运行两次构建。

"build": "npm-run-all --parallel build:production build:staging",
"build:production": "MY_ENV=production next build",
"build:staging": "MY_ENV=staging next build",

对于问题2

如果我能够预先生成所有静态页面。我可以把所有东西都放在CDN上,它们就会起作用。

在我的情况下,ISR更适合。我让ISR工作的方法是要求服务器为每个请求返回HTML,而不是托管在CDN上。由于所有其他资产都托管在CDN上,因此性能仍然很好,此解决方案非常适合我的情况。

如果你像我一样在这个问题上有点挣扎,我希望我的回答能帮助你。

最新更新