Next项目部署

3.7k 词

一、项目打包

目前了解到的next项目的打包有三种模式:

  1. 静态站点生成(SSG)
1
2
3
4
5
const nextConfig = {
output:'export'
};

export default nextConfig;

优点:

  1. 静态站点生成(SSG): 所有的页面内容都在构建时被预渲染,并生成静态文文件
  2. 部署: 适合部署在不支持服务端渲染的环境,比如github Page或者其他静态托管站点托管服务

缺点:

  1. 不支持动态路由。 所有的页面都在构建时生成, 无法使用SSR渲染动态数据,
  2. 不能使用API路由,也就是说不能使用到编写后端接口的功能,next全栈的优势就没了
  3. 可能不是传统意义上的SSR(在页面初次渲染时,能根据不同的条件会返回不同的HTML)

生成的目录结构:

image-20240821183523892

二、混合模式

1
2
3
4
5
const nextConfig = {
output:'standalone'
};

export default nextConfig;

优点:

  • 独立部署: 使用 output: 'standalone' 时,Next.js 会生成一个可以独立部署的目录,包含所有的依赖项和构建产物。
  • 服务器端渲染(SSR): 这种模式支持服务器端渲染,支持动态数据获取,并且在需要时生成静态内容。
  • 容器化部署: 适用于 Docker 容器、无服务器架构(如 AWS Lambda)、或任何需要独立部署的环境。

缺点:

  • 复杂性增加: 虽然 output: 'standalone' 提供了独立部署的优点,但它的配置和部署相对于默认模式可能稍微复杂一些,特别是在需要处理依赖项和环境变量时。

  • 体积可能较大: 由于它会打包应用的所有依赖项,生成的构建文件夹(如 .next/standalone)可能会比其他模式体积更大一些。

  • 冷启动时间: 在无服务器架构(如 AWS Lambda)中使用 standalone 模式时,由于包含了更多的依赖项和代码,冷启动时间(即第一次调用时的延迟)可能会更长一些。

打包出来的文件结构:

image-20240821183910179

三、默认配置

优点:

  • 完整功能: 如果不设置 output,Next.js 会默认提供其完整功能集,包括静态站点生成(SSG)、服务器端渲染(SSR)、客户端渲染(CSR)、API 路由等。

  • 部署: 可以部署到任何支持 Node.js 环境的服务器,可以结合 getStaticPropsgetServerSidePropsgetInitialProps 等方法来灵活处理数据获取和渲染。

  • 灵活性: 默认设置最为灵活,适用于大部分的应用场景,包括 SEO 要求高的项目。

  • 文件结构: 使用默认配置时,Next.js 会在 .next/ 目录中生成所有的构建产物,包括 HTML 文件、JS 文件、CSS 文件等。

    主要文件:

    • .next/server/pages/:包含 SSR 页面所需的代码和静态 HTML 文件。
    • .next/static/:包含静态资源(如图片、CSS、JS 文件)。

打包出来的文件结果:

image-20240821184102687

二、项目部署

SSG 部署(实践过)

通过 SSG(Static Site Generation)打包(export 模式)出来的文件,每个页面都有独立的 HTML 文件,可以通过配置 Nginx 转发,实现部署。

优点:

  • 易于理解:与传统的部署方式相近,部署过程简单明了。
  • SEO 友好:确实返回了整个页面的 DOM 结构,有利于搜索引擎优化,因为搜索引擎可以轻松地抓取页面内容。

缺点:

  • 无法动态渲染:页面内容在构建时已经确定,无法在请求时根据用户或条件动态渲染页面,无法实现真正的服务器端渲染(SSR),只能使用预渲染好的静态页面。
  • Nginx 配置复杂度:根据项目需求,可能需要复杂的 Nginx 配置,特别是在处理路由转发或多页面应用时。
  • 图片处理:需要对图片进行额外的处理,可能需要封装自定义的图片组件,以确保图片在导出模式下能正确加载和显示。

部署到静态托管服务平台

使用平台如 GitHub Pages、Vercel、Netlify 等进行部署。这些平台通常专门针对静态内容的托管。

优点:

  • 简单便捷:这些平台提供了集成的 CI/CD 流程,通常支持一键部署,适合静态网站的快速发布。

  • 全球 CDN:这些平台通常会自动使用 CDN(内容分发网络),提升页面加载速度。

    缺点:

  • 成本未知:可能需要收费。

  • 受限于平台功能:功能上可能会受限于平台提供的服务,对于复杂的应用场景可能不够灵活。

  • 动态功能限制:由于这些平台主要托管静态内容,因此无法直接处理动态功能或后端逻辑。

容器化技术,通过 Docker 部署

使用 Docker 容器化技术,将 Next.js 应用打包成镜像,然后部署到任何支持 Docker 的环境中。

优点:

  • 跨平台一致性:Docker 提供了跨平台的一致性,确保应用在任何环境中运行都具有相同的行为。
  • 易于管理和扩展:Docker 容器化使得应用的扩展和管理变得更容易,可以结合 Kubernetes 等技术进行自动化部署和管理。
  • 隔离性强:容器之间相互隔离,确保应用依赖的环境不受其他容器或系统变化的影响。

缺点:

  • 资源开销:与直接在主机上运行相比,Docker 容器会带来一些额外的资源开销。
  • 学习成本:Docker 和容器化技术需要一定的学习和操作经验,初学者可能需要一些时间来熟悉这些工具。

在 Node.js 环境下的服务器上部署(实践过)

直接将 Next.js 项目部署在运行 Node.js 的服务器上,执行 SSR 渲染。

步骤:

  1. .next 文件夹、package.json 文件上传到服务器上(node_modules 也可以一起上传,或者在服务器上安装)。
  2. 在服务器上构建项目:npm run build
  3. 启动生成环境下的项目:npm start
  4. 使用 PM2 守护进程持续部署前端应用:pm2 start npm --name "next-app" -- start

优点:

  • 支持 SSR 渲染:无需复杂的 Nginx 配置,即可在服务端动态生成页面内容,适用于需要根据用户请求动态生成页面的场景。
  • 直接访问服务器:无需通过中间代理层,直接在服务器上处理请求,减少延迟。

缺点:

  • 需要 Node.js 环境:服务器必须配置 Node.js 环境,对node的版本也有严格要求。
  • 需要维护服务器:需要手动管理服务器环境、依赖和更新,运维成本相对较高,例如安装PM2对node进程进行维护和管理。
  • 需要额外的服务器资源: 在服务器上跑项目,在使用npm安装依赖时,有可能会在全局环境下缓存依赖,导致额外的物理内存占用(猜想)

总结(GPT)

以上几种部署方式各有优缺点,适用于不同的项目场景和需求。根据项目的特性、团队的技术栈以及目标用户群体的需求,选择最适合的部署方式。

  • SSG 部署 适用于纯静态站点或内容较少的项目,注重 SEO。
  • 静态托管服务平台 适用于简单的静态站点,快速发布。
  • Docker 部署 适用于需要跨平台一致性、容器化管理和易于扩展的场景。
  • Node.js 服务器部署 适用于需要实时动态渲染、SSR 的项目。

总结(个人)

现在实践过的只有SSG 部署和node环境下部署

对于SSG碰到的问题:

  1. 不会配置nginx,页面只有除此加载能够显示,一刷新就会找不到页面,猜测是路由转发规则没配好
  2. next提供的Image组件无法正常使用,需要添加unoptimized,取消next自带的图片优化才能够显示
  3. …..

对于node环境下直接部署

  1. 无论是npm run dev 还是npm run start(生产环境)都出现样式丢失的问题,页面完全不能看

  2. 没有尝试过下载PM2等工具进行运维,不能确保服务器重启之类的情况会不会导致进程结束

  3. ….

关于SSR的疑问:

GPT:

SSR 的核心在于服务器在接收到用户请求时,根据请求的具体条件(如用户位置、身份等)生成并返回完整的 HTML 页面。这些页面在初次加载时就包含了所有需要的内容,无需额外的客户端请求来获取动态数据。

  • 初次加载的内容:SSR 确保了搜索引擎爬虫可以直接抓取到完整的页面内容。这意味着爬虫能够索引整个页面,包括根据不同条件生成的内容。
  • 后续动态数据的获取:对于通过 JavaScript 动态获取和渲染的数据,爬虫通常仍然无法获取。也就是说,SSR 解决的是页面初次加载时的内容,而后续通过 AJAX 或其他方式获取的数据,除非被渲染到初始 HTML 中,否则爬虫是无法获取到的。

我觉得这种初次渲染返回不同的HTML页面对那些依赖于内容展示的页面(如新闻、博客等)很有利,而对于现在我们官网这种内容固定的并没有很大的优势。
SSR可以显著提高搜索引擎对内容的抓取和索引效果,比如说它可以根据不同的用户,推荐不同的内容,这些内容都是返回直接的HTML的,也就是说它是在页面初次加载的时候,它会在服务端上请求数据,渲染好html结构后再返回。而对于传统的CSR(客户端渲染),它是先把HTML结构返回,在浏览器上请求服务端数据后再更dom结构,我觉得核心点就在这里。

就现在而言我们的官网完全是静态网页,没有用到任何的网络接口。在我看来这是不需要用到SSR的,用SSG就行了。
如果说后续或添加接口,需要通过网络请求去渲染页面的结构,可能才会需要SSR。

留言