ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Next.js+Laravel 12实战:从零搭建轻量级社交网络

Next.js+Laravel 12实战:从零搭建轻量级社交网络 这套社交网络代码我在仓库里折腾了一年半今天终于把 v1.0 的 tag 打上去把它从一个内部原型推到了一个能稳定跑、能给一个中小团队直接用的正式版本。项目叫 YFSNS定位是轻量级社交网络技术栈就是标题里写的 Next.js 加 Laravel 12。最早想做它的原因很简单组里小伙伴想有个自己人说话的地方但市面上的平台不是信息流被算法控得死死的就是广告和营销号多到没法看。后来索性自己动手写了这套东西一路从用户模块写到信息流、通知、私信、部署上线。如果你也在考虑自己搭一套社区或者想拆解一套完整的前后端分离社交网络是怎么落地实现的这篇应该对你有用。我会从为什么选型、核心模块怎么设计、信息流怎么实现、实时消息怎么接一直聊到部署和真机跑起来之后踩过的一些坑代码、配置、踩坑记录都会贴关键部分。1. 为什么在2025年还要自研一套轻量级社交网络1.1 主流平台让人疲惫的三个点先说说这个项目最初的问题来源。通用社交平台现在给我的感觉是你想看朋友的真实动态平台却只想让你看它想让你看的内容。算法把信息流编排成了无限滚动的广告牌看着刷了很久实际上有价值的信息很少。第二是隐私边界模糊点赞、关注、浏览记录全部变成训练模型的原材料普通用户根本没有选择权。第三是社区氛围的问题一个帖子下面经常是立场先行理性讨论的空间越来越小。这不是说大平台没有价值而是它们追求的是让更多人停留更久和让一个小圈子好好交流这两个目标天然冲突。我在企业里做技术管理那几年见过太多团队建了微信群、钉钉群结果消息被工作群淹没重要讨论根本留不下来。熟人之间需要的那个纯粹一点、安静一点的交流空间恰好是通用平台给不了的。1.2 轻量级社交网络的真实使用场景YFSNS 的目标用户画像一开始就很清楚不需要和大厂竞争用户时长只需要解决特定人群的私密交流问题。实际测下来比较合适的场景有三个。一是企业或团队内部的信息中枢。员工在这里发动态、互相评论离职和换人不用重建群聊。二是校园或兴趣小组的小圈子几十到几百人规模大家关注的是共同话题而不是流量。三是开源项目的配套讨论区代码托管平台都有 issue但社区需要的松弛感、晒成果、闲聊issue 给不了。这几个场景共同的特点是用户规模小、信任度高、内容以真实动态为主。所以我在设计功能边界时没有直接堆模块而是砍掉了一堆大平台标配的东西比如推荐算法、热搜榜、陌生人关注这些通通不进 v1.0。1.3 YFSNS 的定位与功能边界YFSNS 的定位是轻量级三个字。做轻的秘诀不是代码少而是职责边界清晰。v1.0 最终保留的核心功能是账号系统、动态发布与时间线、关注关系、点赞评论、一对一私信、站内通知、个人主页、基础审核。不做的是复杂话题系统、视频流、推荐引擎、广告系统。这个取舍背后有一个很实际的成本考量。社交产品环形链路很长用户注册、发布内容、互动、通知、再回来每一步都可以做到极其复杂。在一个人维护的项目里每加一个复杂模块都要付出长期的维护成本所以 v1.0 宁可做少做稳也不能做多做崩。对我来说稳定跑半年胜过上线一堆没人用的功能。1.4 从原型到 v1.0版本演进的节奏YFSNS 的代码演进其实很有意思。最早它是一套 Laravel 全栈项目Blade 模板直接渲染页面跑在本地。用了一个月之后我发现光靠服务端渲染做交互越来越别扭于是决定重写前端接入 Next.js后端保留 Laravel 并专职做 API。这个过程大概经历了 v0.1 到 v0.4 的实验到 v0.5 前后端分离才算稳定。后面保持小步迭代v0.6 加入评论和点赞v0.8 加入私信和通知v0.9 做性能优化和压力测试v1.0 之前主要修的是部署链路和数据一致性问题。整个节奏差不多是每一两个月一个大版本每次发版都有一张明确的功能与问题清单。版本号不是给自己看的是给使用者和测试者一个明确的沟通锚点。2. 技术选型实录Next.js 和 Laravel 12 是怎么凑到一块的2.1 为什么没有继续用 Livewire 或 Blade 全家桶老读者可能知道Laravel 官方其实推荐过 Laravel Livewire 的全栈路线Blade 写页面、Livewire 做交互确实能把开发速度拉满。我也这么写过一版但随着功能变多问题也出来了复杂的状态同步逻辑会让 Livewire 组件变得很重调试体验一般。更关键的是如果以后想给移动端 App 复用接口全栈模式会产生很大浪费。所以第二轮设计时我明确把前端从 Laravel 里拆了出去做纯接口和后端业务逻辑。这一拆等于把前后端的边界定死了。Laravel 只负责用户、内容、通知等领域模型和 API 输出Next.js 只负责页面渲染、交互和状态管理。前端和后端可以并行开发测试也能互相隔离。对独立开发者来说边界清晰的最大好处是心智负担小改前端不用怕影响接口调接口的时候不用去翻 Blade 模板。2.2 Next.js 15 承担前端渲染与内容可见性前端我选了 Next.js 15 的 App Router 模式不要小看这个选择对社交类产品的影响。YFSNS 虽然定位是私密圈子但企业交付场景里还是有人会去搜索公开资料、看团队主页SSR 带来的首屏渲染和内容可见性仍然有价值。Next.js 的另一个优势是生态成熟Tailwind CSS、zustand、SWR、react-dropzone 这些库可以直接用不用自己造轮子。App Router 的服务端组件和客户端组件边界也帮了大忙。公开页面、个人主页、用户列表这些对实时性要求不高的部分我放在服务端组件里直接 fetch 后端数据交给 SSR 渲染发布动态、点赞、私信这些强交互模块则下沉为客户端组件用 SWR 做数据缓存和更新。这样首屏快交互也不拖沓很多功能写起来比纯客户端方案直观得多。2.3 Laravel 12 带来的开发效率曲线后端选 Laravel 12核心原因是它把社交产品需要的那几块基础设施基本都备齐了。Sanctum 做 API 认证Policies 做授权Notifications 做站内通知队列和 Redis 处理异步任务广播系统连 Reverb 就能上 WebSocket。对一个全栈开发者来说不需要到处拼第三方组件这是效率的关键。Laravel 12 相比更早版本有几个让我觉得舒服的点默认目录结构更简洁App 目录按能力组织而不是按层级生硬堆砌框架对 PHP 版本要求上移强制团队用更新版本减少了很多历史依赖问题。我在实际项目里体验最强的是调试链路php artisan tinker配合模型事件排查数据问题比之前快很多。2.4 RESTful API 版本设计与数据交换约定前后端约定统一走 RESTful JSON接口路径挂在/api/v1下面。为什么不用 GraphQLYFSNS 的信息流查询结构其实很固定REST 够用GraphQL 的 schema 维护对单人项目来说是额外负担。我保留了几个简单约定列表接口统一返回data和meta两个字段meta 里放游标信息和分页大小错误码统一成code message details的结构所有时间字段一律 ISO 8601前端展示时再转本地时区。这些约定不复杂但能省掉很多接口联调时的争议。比如meta.next_cursor为 null 时表示没有下一页前端只需要判断一个字段不用关心分页策略。越小的团队越需要这种书面契约因为它能弥补沟通成本。3. 认证与用户体系Laravel Sanctum 承担守卫职责3.1 认证方案对比JWT、Token、Session 各取所需先说结论YFSNS 用的是 Laravel Sanctum 的 token-based 认证配合 httpOnly Cookie 在前后端之间传递凭证。对比过 JWT 之后我放弃它的理由是JWT 的状态吊销麻烦一旦 token 被泄漏你很难在服务端把它立刻拉黑。Sanctum 的 token 存在数据库里删除一条记录就是吊销逻辑非常直观。Session 方式更适合传统服务端渲染对于前后端分离的 Next.js 项目需要额外的 CORS 和 CSRF 处理复杂度反而更高。Sanctum token 方案等于把认证状态变成了服务端可控的资源安全性和可维护性都更均衡。认证看似基础但它决定了后面权限、审计、多端登录的设计空间值得多花一点时间想清楚。3.2 用户表与注册登录的实现细节用户表的结构尽量精简核心字段是用户名、邮箱、密码、头像、简介、邮箱验证时间。username 和 email 都建了唯一索引。为什么用户名也要唯一因为 YFSNS 的定位是私密圈子用户名就是 identity重名会带来 提及和主页链接的混乱。注册和登录的控制器没有用 Laravel Breeze/Jetstream 的现成逻辑而是手写了一套简版接口。密码用框架自带 hash 加密验证码、频率限制用 throttle 中间件配置。一个关键细节是注册后不强制邮箱验证但未验证用户不能发动态这里用email_verified_at字段配合中间件来做分级能力。这样既降低注册摩擦又阻止了批量垃圾内容的产生。3.3 token 保存在哪后端下发 httpOnly Cookie 的做法这里是我踩过最多坑的地方。早期版本我图方便把 Sanctum token 返回给前端存在 localStorage 里。效果是能跑但仔细想不太能接受XSS 一旦发生token 可以被脚本直接拿走等于账号拱手让人。后来我把方案改成了Laravel 登录成功后在响应里通过 Set-Cookie 下发一个 httpOnly Cookie前端浏览器自动保存Next.js 的 API 路由层再从同一个 Cookie 读 token转发给 Laravel。这样浏览器端的 JavaScript 从头到尾拿不到明文 tokenCSRF 风险由 SameSiteLax 和自定义 header 双重缓解。代价是每个页面请求都多走一跳 Next.js API 路由但对 YFSNS 的体量来说这点开销非常值得。安全和性能的权衡没有标准答案关键是明白每一种选择的代价在哪。3.4 权限控制Policy 让删帖与编辑更安全接口只有认证还不够得管住谁能删谁的帖子。Laravel 的 Policy 在这里很顺手我在app/Policies/PostPolicy.php里定义了update和delete方法判断逻辑就一句当前用户 ID 是否等于帖子作者 ID管理员另算。在控制器里配合$this-authorize(delete, $post)调用Laravel 会自动返回 403省去了到处写 if 的重复代码。YFSNS 目前的权限模型比较简单用户只能编辑和删除自己的内容超管用户可以处理举报内容。后面如果要加圈主管理成员帖子的功能给 Policy 加一种角色判断即可调用点不用动。把权限收敛到 Policy 层长期维护成本会低很多。4. 信息流Feed核心实现表结构、游标分页与热度排序4.1 关注、点赞、评论的关系表设计信息流是社交产品的命根子关系表设计必须一次到位。YFSNS 最核心的四张业务表是follows、posts、likes、comments。follows表记录关注关系follower_id 和 following_id 都指向 users 表唯一索引防止重复关注。posts表放动态内容除了 user_id、content还预留了attachmentsJSON 字段存图片列表方便以后扩展视频。点赞和评论是典型的从属关系表。likes表唯一索引是(user_id, post_id)防止同一个人反复点赞comments表挂 post_id并保存内容快照避免用户删除后评论没有内容可展示。设计关系表时我坚持一个原则凡是数量都能从明细表里算出来除非性能实在扛不住否则不做冗余计数字段。这个原则让 YFSNS 至今没有出现那种改不完的数据同步 bug。4.2 首页 Feed 查询一条链路的 SQL 和代码首页 Feed 的查询链路是这样的先查出当前用户关注的用户 ID 列表再加上自己的 ID然后用这个集合去 posts 表里筛帖子。代码写出来很短$followingIds Follow::where(follower_id, $currentUserId) -pluck(following_id) -push($currentUserId); $feed Post::query() -whereIn(user_id, $followingIds) -with([user:id,name,username,avatar]) -withCount([likes, comments]) -orderByDesc(id) -cursorPaginate(perPage: 20);这个写法在关注人数几千、帖子总量百万级以内完全够用。索引请务必建上posts(user_id, id)这样的联合索引否则 whereIn 扫描会很难看。千万级以后再考虑推拉结合的时间线方案现在不需要过度设计先把查询链路写对比堆一堆高级组件重要得多。4.3 游标分页为什么比 offset 分页更适合社交场景YFSNS 从第一版就用 cursorPaginate没有给 offset 留机会。offset 分页在数据量上来之后有两个硬伤一是深分页时数据库要跳过大量行性能急剧下降二是用户发布新帖子会把后面页的数据整体往后推导致上一次看到的帖子在下一页重复出现。Laravel 的cursorPaginate默认按 id 做游标排序它把分页条件变成where id ?天然规避了这两个问题。接口返回的 meta 里带next_cursor前端翻页时把这个值传回来即可。如果你自己实现游标建议优先用自增 id而不是 created_at后面踩坑章节会细说为什么。4.4 简单热度排序避免信息流全是旧内容纯时间倒序的问题在于午后发的旧帖子会一直压在顶部新内容反而沉下去。YFSNS 做了一版不复杂的加权排序score 点赞数 * 2 评论数 * 3 时间衰减因子时间越近权重越高。实现上不用 Redis 实时计算直接构造 SQL 表达式排序即可$feed Post::query() -whereIn(user_id, $followingIds) -withCount([likes, comments]) -selectRaw(posts.*, (likes_count * 2 comments_count * 3) UNIX_TIMESTAMP(posts.created_at) / 86400 AS score) -orderByDesc(score) -cursorPaginate(20);这个公式是经验值重点不是调参本身而是先让信息流有一个新鲜且有互动的排序信号。跑了一段时间观察用户行为再逐步把信号做得复杂而不是一上来就上推荐模型。朋友圈式的纯时间线适合熟人但 YFSNS 的场景里加入少量互动权重内容活跃度确实明显提升。5. 实时消息怎么做从 Laravel Reverb 广播到 Next.js 收信5.1 为什么实时通知选择了 WebSocket 而不是轮询私信和通知是 YFSNS 里用户感知最强的地方。早期用的是前端 setInterval 每 30 秒轮询一次通知接口开发简单服务器也扛得住。问题是两个通知到达延迟不稳定最坏要等 30 秒在弱网下轮询请求会无限堆积体验很差。所以 v0.8 开始接 WebSocket。我选了 Laravel 12 原生配套的 Reverb而不是自己搭 Swoole 或 Node.js Socket 服务原因是 Reverb 作为同生态组件和 Laravel 的广播事件、频道认证、队列机制是无缝集成的改造成本低很多。技术选型有时候不一定要选最酷的要选和你现有代码关系最近的。5.2 私有频道、用户通知与消息事件的广播定义在设计实时事件时我把通知和私信分成了两条线。用户被点赞、被评论时触发 Laravel 的 Notification 系统同时通过 ShouldBroadcast 接口把通知广播到该用户的私有频道private-App.Models.User.{id}。私信则单独走private-conversations.{conversationId}频道保证只有对话双方能订阅。事件类示例class PostLikedNotification extends Notification implements ShouldBroadcastNow { public function broadcastOn(): array { return [new PrivateChannel(App.Models.User. . $this-post-user_id)]; } public function broadcastWith(): array { return [ post_id $this-post-id, liker $this-liker-username, message $this-liker-username . 赞了你的动态, ]; } }用ShouldBroadcastNow是为了让事件立即推出去不走队列延迟对实时通知来说更重要。通知正文里的文案尽量简短因为浏览器 notification 弹窗的展示区域很有限写太长很难看。5.3 Reverb 的 Nginx 升级代理配置Reverb 默认监听 8080 端口但我并不想让公网直接暴露这个端口而是通过 Nginx 做反向代理和 WebSocket 升级。踩过一次坑之后配置写成这样location /app/ { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 60s; }关键就在Upgrade和Connection这两行。不写它们WebSocket 请求会被当成普通 HTTP 处理客户端收到的往往是 400 或 404。Reverb 进程本身用 Supervisor 守护崩了会自动拉起。如果你部署环境里还有防火墙记得把 8080 端口只对内网开放公网入口走 Nginx。5.4 Next.js 客户端怎么用 Laravel Echo 接住推送前端这边我用 laravel-echo 来订阅频道底层传输走 Pusher 协议但服务端是 Reverb。初始化时需要指定broadcaster: reverb并告诉 Echo 后端的 wsHost 和 wsPortconst echo new Echo({ broadcaster: reverb, key: process.env.NEXT_PUBLIC_REVERB_APP_KEY, wsHost: window.location.host, wsPort: 6001, forceTLS: window.location.protocol https:, authEndpoint: /api/broadcasting/auth, auth: { headers: { Authorization: Bearer ${token}, }, }, }); echo.private(App.Models.User.${currentUserId}) .notification((notification) { toast(notification.message); mutate(/api/v1/notifications); });注意authEndpoint要指向 Laravel 的广播认证接口并且带 Authorization header否则私有频道订阅会被 403 拒绝。如果你用了前面说的 httpOnly Cookie 方案这里就要由 Next.js 的 API 路由去中转认证而不是直接在浏览器里带 headers。5.5 弱网环境下的取舍实时推送只负责提醒WebSocket 不是万能的。在移动端网络频繁切换时长连接容易断Reverb 自带心跳重连但重连期间的消息推送必然有延迟。YFSNS 的处理策略是实时推送负责提醒和刷新入口真正的数据一致性永远靠 REST 接口兜底。用户点开私信或者通知列表时前端一定会重新请求一次未读数和服务端最新数据不做纯粹乐观更新。这个设计让我放心很多。即使 WebSocket 完全挂掉用户刷新页面也能拿到全部消息体验只是从秒到退化成手动刷新不会丢数据。做实时功能一定要想好降级方案否则线上一个连接异常就能让整个功能变成灾难。6. 部署实录2核4G服务器上的优化组合拳6.1 前后端分离部署的目录与 Nginx 配置YFSNS 跑在 2核4G 的云服务器上日常也就几十个并发压力不大但部署还是要讲究。我的目录结构是/var/www/yfsns-api放 Laravel/var/www/yfsns-web放 Next.js。前端构建时用 standalone 模式只保留最小运行文件# .env 里开启 NEXT_OUTPUTstandalonenext build后把.next/standalone复制到指定目录用 node 启动server.js监听本地 3000 端口。Nginx 那边两个域名各自配置站点一个指到 PHP-FPM 的 Unix Socket一个指到 127.0.0.1:3000。location ^~ /api/ { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }这里我把 Next.js 的 API 路由和常规页面一起走 3000 端口浏览器只和 Next.js 同源通信Laravel 侧再收紧 CORS整体攻防面小了很多。如果以后要把 Laravel 独立暴露只需要调整 Nginx 转发规则业务代码不用动。6.2 Laravel 生产环境的缓存与队列进程Laravel 部署有个老规矩上线前跑一遍配置缓存和时间缓存组合命令否则几百个 PHP 文件在每次请求时都要重新解析性能差异非常明显。php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache php artisan migrate --force队列进程也交给 Supervisor 托管消费默认的 Redis 队列。邮件、图片处理、通知分发都走队列主请求只做轻量操作。Supervisor 配置里numprocs4内存占用可控出现异常会自动重启不用人工盯着。进程管理工具很重要裸跑队列命令的话一次连接泄漏就能让你半夜被报警吵醒。6.3 MySQL 索引优化与慢查询YFSNS 数据量没过百万但索引还是要建对。除了前面提到的时间线联合索引likes和follows的唯一索引不仅是业务约束也是走查询的最优路径。慢查询日志开了之后我发现一条意想不到的瓶颈通知列表的notifications表没索引where notifiable_id ?全表扫描。补上索引后从 500ms 降到 20ms 以内。生产环境我还会定期跑ANALYZE TABLE更新统计信息并让 MySQL 的innodb_buffer_pool_size调整到内存 1G 左右。这些操作不复杂但能避免数据量和查询模式变化后索引失效。有时候性能问题不是代码问题是索引和统计信息没有跟上数据增长。6.4 图片上传的存储方案与压缩链路v1.0 支持在动态里传图片存储我选了对象存储加 CDN而不是服务器本地目录。服务器本地磁盘太小日志和备份一多就撑不住。上传链路是前端压缩、后端校验、对象存储直传三块组合前端用 canvas 把大图压到宽边 1600px 内后端校验 MIME 白名单和大小最后签发临时凭证让浏览器直传对象存储。这一步把服务器的出口带宽压力也卸掉了。用户发的图片被放到 CDN 上Nginx 只需要转发 API 请求。真机上 1G 图片高速点击测试服务器 CPU 曲线依然平稳。对于小成本项目来说对象存储的开销远低于自己维护图片服务尤其是要考虑多地域访问和防盗链场景时用云服务是最省心的选择。7. 开发中踩过的坑和对应的解决方案7.1 Next.js 的 fetch 默认缓存让新动态消失这个坑在前后端分离初期最容易踩。Next.js 15 的 App Router 里服务端组件中的 fetch 默认会走数据缓存我在个人主页里 fetch 用户帖子列表页面明明改了数据库刷新居然看到的还是旧数据。排查半天发现是缓存命中给了空响应。解决方式是在读取实时性高的接口时显式声明fetch(/api/v1/users/${id}/posts, { next: { revalidate: 0 } }); // 或者 fetch(apiUrl, { cache: no-store });出版信息流和动态详情时必须 no-store个人简介这种低频修改的可以用 revalidate 做增量更新。缓存逻辑要想清楚否则用户端的修改没生效反馈会让你排查到崩溃。7.2 PHP 版本和环境升级带来的兼容性坑Laravel 12 对 PHP 版本要求明显比之前高了。我的生产服务器原本跑 PHP 8.1直接 composer install 就报依赖不支持。最后操作系统镜像重新选了支持 PHP 8.3 的新版本才顺利跑起来。这个坑提醒我升级框架大版本前要先把运行环境的 PHP 版本检查清单列好不能用旧机器硬扛新框架。Docker 化部署能规避大部分这类环境问题但我的服务器性能太小跑容器反而增加损耗所以最终还是用宿主机加多版本 PHP 共存的方式管理。7.3 CORS 与同一站点 Cookie 的取舍早期 localStorage 方案下跨域调 Laravel API 必须配 CORS。配了允许来源、允许 header、允许方法还不够cookie 模式下还要处理withCredentials。我最终切到 Next.js API 路由做 BFF 之后浏览器只和同源打交道Laravel 侧把 CORS 策略收紧到只允许内网域名反而减少了一个攻击面。如果你不想上完整的 BFF也要至少把 Sanctum 的 stateful domains、cors 配置放在一起通盘规划。最怕的是这里配一半那里配一半线上出现各种奇怪跳转和登录失效。7.4 Reverb 在 Nginx 下 WebSocket 握手失败这个坑值得单独说。Reverb 监听 8080一开始我在 Nginx 写反向代理时只写了常规 proxy_pass没有 Upgrade 头结果前端 Echo 一直在 failed 和 retry 循环。WebSocket 初始握手是靠 HTTP Upgrade 完成的代理如果不把这个头传过去后面全部白搭。还有一个细节proxy_set_header Connection upgrade;在不同请求里可能带来问题普通 HTTP 请求也拿到 upgrade 连接头。更稳妥的做法是用map在 HTTP/1.1 判断但小流量下直接写死也能跑。我调试时用tail -f /var/log/nginx/access.log看返回码看到 101 就说明代理成功了。7.5 游标分页用时间字段导致的重复和遗漏我一开始用 created_at 做游标因为觉得时间排序对用户更直观。结果遇到同秒发布多条帖子时游标判断where created_at ?会把同一秒的帖子一起滤掉或重复返回信息流出现诡异的跳页。换成自增 id 做主排序之后这个问题彻底消失因为 id 单调递增不存在同值歧义。如果你非要用时间排序至少要把orderByDesc(created_at)改成orderByDesc(id)不要把时间放进游标判断。显示层可以用时间格式化但排序主键和游标主键必须是 id 这样严格单调的字段。这是很多人第一次写信息流时都会遇到的经典坑。7.6 图片上传超限Nginx 和 PHP 的双重限制上线后第一个线上反馈是传图失败而且只在图片大于 2M 时触发。查半天不是代码问题是 Nginx 默认client_max_body_size 1mPHP-FPM 的upload_max_filesize和post_max_size也限制在 2M。三方都要改才能让大文件请求顺畅Nginx 的 location 里加上client_max_body_size 20mPHP 配置里把两处大小调大改完重启服务。前端压缩虽然把图片控制在 1.5M 以内但服务端限制还是得留足余量否则接口被人直接调用传大文件时依然会失败。上传相关限制建议在项目文档里单独列一节方便部署时检查。坑位现象根因解决方案Next.js fetch 缓存修改后页面不更新App Router 默认数据缓存实时接口显式 no-storePHP 版本不兼容composer install 失败Laravel 12 要求更高 PHP升级到 PHP 8.3 或容器化CORS 配置混乱登录状态丢失前后端跨域且 Cookie 策略不一致Next.js 做 BFFLaravel 收紧 CORSReverb 握手失败WebSocket 一直重连Nginx 缺少 Upgrade 头配置 Upgrade/Connection游标分页重复翻页出现旧内容created_at 同值歧义改用自增 id 做游标图片上传超限大于 2M 失败Nginx 和 PHP 双限制统一调大上传限制8. v1.0 上线只是开始Roadmap 与开源计划8.1 为什么选这个节点正式发布v1.0 不是某个功能做完才发布的而是所有基础设施稳定后发布的。我的标准很简单连续两周线上无重大 bug2 万条动态和千级关注量下接口 P95 响应在 300ms 以内部署流程只需一条脚本从 push 到上线不超过 10 分钟。当这些条件都满足继续喊内部测试版意义不大正式发布是对这段工作的一次确认。选择这个节点还有一个原因已经有三个小团队主动要拿去试用。外部使用者的反馈和内部测试完全不一样他们会遇到你没想过的网络环境、浏览器版本和操作习惯。正式发布意味着我要开始对陌生人负责这比自娱自乐要有效得多。8.2 下一步功能规划群组、话题与移动适配接下来几个版本优先级很明确。v1.1 会加群组功能让一个站里可以有多个独立讨论圈这是团队场景的高频需求。群组的设计会复用已有的用户和权限体系等于是给关注关系加了一层空间维度。v1.2 加话题标签把动态按主题聚合信息流能更聚焦。v1.3 会把 PWA 适配补齐让手机浏览器离线访问和桌面图标体验更好先不急着上原生 App保持轻量。功能规划我遵循一个原则每个版本只解决一个核心痛点做完测稳再进下一个。社交产品最怕把用户拉进来之后发现某个核心链路不稳定信任一旦破损很难修复所以宁可发版慢一点。8.3 关于开源维护想说的一些话YFSNS 会以开源方式发布许可证定在 MIT。做开源对我自己的价值是让这套代码接受更多真实场景的检验。我对它的期待不是 star 数量涨多少而是在企业内部、校园社团里被更多人跑起来反馈真实的问题我才能把它打磨得更好。开源维护不是把代码推到 GitHub 就完事。issue 规范、贡献指南、安全漏洞响应时间都是要做的。我给自己定的节奏是平时工作日修 bug周末做新功能。个人项目最怕的不是没时间而是没有节奏感。8.4 想快速跑起来一条命令清单如果你想先把 YFSNS 跑起来看看效果核心命令就这几条git clone https://github.com/your-repo/yfsns.git cd yfsns/api cp .env.example .env composer install php artisan key:generate php artisan migrate --seed php artisan serve cd ../web cp .env.example .env.local npm install npm run dev数据库连接、Reverb key、对象存储参数都在各自的.env里配置。前端 dev server 默认走 3000 端口后端 API 在 8000 端口本地跑通之后再把 Nginx 和 HTTPS 加上。我建议你第一步先注册用户发一条动态感受一下整个链路再去看代码细节。如果看完这篇你也起了自己搭一套社交网络的心思我的建议是先把用户模型和 Feed 想清楚其他功能都可以靠后。这两块是整个产品的骨架骨架正了后面加什么功能都不至于翻车。YFSNS v1.0 只是一个开始真正有意思的部分是后面根据真实使用反馈持续打磨的过程。
返回列表