一、项目打包
目前了解到的next项目的打包有三种模式:
- 静态站点生成(SSG)
1 | const nextConfig = { |
优点:
- 静态站点生成(SSG):
所有的页面内容都在构建时被预渲染,并生成静态文文件
- 部署: 适合部署在不支持服务端渲染的环境,比如github Page或者其他静态托管站点托管服务
缺点:
- 不支持动态路由。 所有的页面都在构建时生成, 无法使用SSR渲染动态数据,
- 不能使用API路由,也就是说不能使用到编写后端接口的功能,next全栈的优势就没了
- 可能不是传统意义上的SSR(在页面初次渲染时,能根据不同的条件会返回不同的HTML)
生成的目录结构:
二、混合模式
1 | const nextConfig = { |
优点:
- 独立部署: 使用
output: 'standalone'
时,Next.js 会生成一个可以独立部署的目录,包含所有的依赖项和构建产物。 - 服务器端渲染(SSR): 这种模式支持服务器端渲染,支持动态数据获取,并且在需要时生成静态内容。
- 容器化部署: 适用于 Docker 容器、无服务器架构(如 AWS Lambda)、或任何需要独立部署的环境。
缺点:
复杂性增加: 虽然
output: 'standalone'
提供了独立部署的优点,但它的配置和部署相对于默认模式可能稍微复杂一些,特别是在需要处理依赖项和环境变量时。体积可能较大: 由于它会打包应用的所有依赖项,生成的构建文件夹(如
.next/standalone
)可能会比其他模式体积更大一些。冷启动时间: 在无服务器架构(如 AWS Lambda)中使用
standalone
模式时,由于包含了更多的依赖项和代码,冷启动时间(即第一次调用时的延迟)可能会更长一些。
打包出来的文件结构:
三、默认配置
优点:
完整功能: 如果不设置
output
,Next.js 会默认提供其完整功能集,包括静态站点生成(SSG)、服务器端渲染(SSR)、客户端渲染(CSR)、API 路由等。部署: 可以部署到任何支持 Node.js 环境的服务器,可以结合
getStaticProps
、getServerSideProps
、getInitialProps
等方法来灵活处理数据获取和渲染。灵活性: 默认设置最为灵活,适用于大部分的应用场景,包括 SEO 要求高的项目。
文件结构: 使用默认配置时,Next.js 会在
.next/
目录中生成所有的构建产物,包括 HTML 文件、JS 文件、CSS 文件等。主要文件:
.next/server/pages/
:包含 SSR 页面所需的代码和静态 HTML 文件。.next/static/
:包含静态资源(如图片、CSS、JS 文件)。
打包出来的文件结果:
二、项目部署
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 渲染。
步骤:
- 将
.next
文件夹、package.json
文件上传到服务器上(node_modules
也可以一起上传,或者在服务器上安装)。 - 在服务器上构建项目:
npm run build
。 - 启动生成环境下的项目:
npm start
。 - 使用 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碰到的问题:
- 不会配置nginx,页面只有除此加载能够显示,一刷新就会找不到页面,猜测是路由转发规则没配好
- next提供的Image组件无法正常使用,需要添加unoptimized,取消next自带的图片优化才能够显示
- …..
对于node环境下直接部署
无论是npm run dev 还是npm run start(生产环境)都出现样式丢失的问题,页面完全不能看
没有尝试过下载PM2等工具进行运维,不能确保服务器重启之类的情况会不会导致进程结束
….
关于SSR的疑问:
GPT:
SSR 的核心在于服务器在接收到用户请求时,根据请求的具体条件(如用户位置、身份等)生成并返回完整的 HTML 页面。这些页面在初次加载时就包含了所有需要的内容,无需额外的客户端请求来获取动态数据。
- 初次加载的内容:SSR 确保了搜索引擎爬虫可以直接抓取到完整的页面内容。这意味着爬虫能够索引整个页面,包括根据不同条件生成的内容。
- 后续动态数据的获取:对于通过 JavaScript 动态获取和渲染的数据,爬虫通常仍然无法获取。也就是说,SSR 解决的是页面初次加载时的内容,而后续通过 AJAX 或其他方式获取的数据,除非被渲染到初始 HTML 中,否则爬虫是无法获取到的。
我觉得这种初次渲染返回不同的HTML页面对那些依赖于内容展示的页面(如新闻、博客等)很有利,而对于现在我们官网这种内容固定的并没有很大的优势。
SSR可以显著提高搜索引擎对内容的抓取和索引效果,比如说它可以根据不同的用户,推荐不同的内容,这些内容都是返回直接的HTML的,也就是说它是在页面初次加载的时候,它会在服务端上请求数据
,渲染好html结构后再返回。而对于传统的CSR(客户端渲染),它是先把HTML结构返回,在浏览器上请求服务端数据
后再更dom结构,我觉得核心点就在这里。
就现在而言我们的官网完全是静态网页,没有用到任何的网络接口。在我看来这是不需要用到SSR的,用SSG就行了。
如果说后续或添加接口,需要通过网络请求去渲染页面的结构,可能才会需要SSR。