自己做一块网盘:Cloud Speicher 的开发记录
One archive, two time zones.
自己做一块网盘:Cloud Speicher 的开发记录
这块东西叫 Cloud Speicher,我自己用的时候更愿意把它想成一间私人档案室,而不是又一个网盘客户端。做到现在大概一个多月,登录、权限和文件这些主路径已经走得通。下面记的是为什么要做、我们怎么分工,以及现在用起来还别扭的地方。
为什么要做
起因其实很单纯。市面上那些应用型网盘,我用着一直不太顺手。账号、客户端、同步盘、各种我并不需要的功能缠在一起,真正想做的事——把一份文件放进一个自己说了算的地方,再在需要的时候拿出来——反而要绕一圈。
另一半原因是想试试远程协作。我在德国,负责后端的朋友在中国。服务器由他提供,后端也由他来写;我负责前端架构、界面与交互、接口对接,以及前端侧的测试。两边一说,觉得这件事刚好能一起做,就这么定了。
它从一开始就不是打算公开给人注册的服务。每个人一间自己的目录,另外留一块公共区。仓库公开,是为了能看见这个产品长什么样,不是把它当成一套可以随便部署的开源网盘。
一个人写界面,一个人写服务
八月底开工。前端用 Vue 3、Vite 和 TypeScript,先把注册和登录接上,再往上长文件列表。后端不放在这个前端仓库里。他改接口,我对着约定改页面;对不上的时候就来回对齐,而不是坐在同一张桌子前指着屏幕改。
中间有一段比较磨人。上传一开始并不是现在这套「先登记、再把文件内容流进去、断了还能续」的做法。协议一变,前端得整段重接。小文件很快就通了,大文件在跨国链路上仍容易超时、断连。好在续传的语义两边对上了:已经写进去多少,就从那里接着写。这种来回,大概就是远程协作真正的日常——不是每天挂着长时间语音边测试边讨论,而是把一件事的边界说清楚。
界面我一直在试。做这个项目的时候,我不只是想把功能摆上去,也想借它学一些更好看的风格,看看自己对不同美学到底理解到哪一步。这次选的是蓝晒:整间网盘都按这套气氛来,而不是套一个通用后台再换皮。网格、列表、右侧预览收在同一套蓝色里,图片缩略图也走蓝晒,GIF 和视频只留一帧,免得格子里自己动起来。空目录后来改成六角螺母的点阵,算这间档案室自己的记号。文件名仍按原来的样子保存,大小写和空格都留着。界面有中文、English、Deutsch。
从接口通了,到产品能用
九月下旬标到 1.0.0。先说账号,因为没有这一层,后面的文件操作都立不住。
注册不开放,要邀请码,而且一码只能用一次。登录成功后由后端签发 JWT,之后的请求凭令牌识别用户,私人目录与公共区也按身份和角色划分权限。退出或删号后,旧令牌会失效。这部分从前端的路由保护、会话保存,一直接到了后端鉴权和目录权限。
文件这边,上传、下载、重命名、移动、删除、预览已经形成完整主路径,收藏、分享和回收站也接进了同一套目录逻辑。文件夹下载会在浏览器端递归打包,传输任务则会持久化保存;遇到网络中断时,前端先询问服务端已经收到多少字节,再从断点继续发送。为了把续传接通,我们也把上传会话、文件偏移量和结束时机逐项对了一遍。
性能调整也围绕实际使用展开。登录、网盘、传输和设置等页面按路由拆分;蓝晒预览、视频抽帧、ZIP 打包只在需要时加载。图片、视频和压缩任务限制并发,避免一次打开大目录就把浏览器拖住。
把测试穿插在开发里
功能越接越多之后,我也逐渐整理出了一套前后端联调方法。
接口有改动时,我先用契约检查页确认响应结构、登录会话和文件目录是否符合约定,再跑一遍冒烟测试,把登录、权限、个人目录、上传和下载串起来。可独立验证的部分用 Vitest 固定下来,包括路径处理、续传、回收站、传输持久化和安全回归。最后再连真实服务器,分别用普通用户和管理员手测,并把通过、阻塞和待部署补丁记进测试清单。
这套流程帮我们抓到过不少「接口返回成功,但实际还不能用」的问题。例如管理员字段在对象转换时丢失、上传初始化参数与线上实现不一致、分享码过期时间算错,以及大文件通过跨国链路时超时。比起等功能全部写完再一起排错,边开发边验证让前后端即使隔着时区,也能用同一份契约和结果继续工作。
还别扭的地方
能用,不等于用着已经舒服。眼下比较明显的有几处。
一是界面仍然只按电脑浏览器来设计。窄屏幕、手机上打开,布局还没有认真收过。侧栏、预览、列表这些在桌面上看着合适的东西,换到小屏幕上就会挤。响应式这步还没做上去。
二是上传一次只能选一个文件。不能批量丢进去,也不能直接传整个文件夹。文件一多,就得一个个点,整理资料的时候尤其麻烦。下载文件夹倒是可以在浏览器里打包,上传这边还没有对等的入口。
三是分享码。同一份文件如果隔一会儿再点一次分享,现在会再发一个新码,旧码还在。发过几次之后,手里就有好几个码对应同一个文件,自己也说不清该把哪个发出去。后面会考虑温和一点的做法:特定时间段内再次申请,就沿用已有的码,并把有效期往后推一推,而不是每次都重新开一串。
除此之外还有些更小的口子,比如多选之后还不能一次性移动。都不至于让它不能用,但每天碰到,还是会想赶紧补上。
往后
最近一段时间比较忙,项目可能会先停一阵。现在这个版本能正常使用,发现的问题也已经记在测试清单里。等手头的事情忙完,再回来补响应式、批量上传、文件夹上传,以及分享码复用和有效期刷新。
下面是负责后端的朋友写的一段。他一直用 Spring 做服务,大部分功能已经接上,但他认为真正能拉开差距的特色还没做完:给某个文件夹做定时更新和上传。这件事依赖更完整的文件夹上传与下载,实现起来不轻,加上两边最近都有别的事要忙,所以暂时搁着。
在他看来,这个项目最要紧的是三件事:有特色、够轻量、用着方便。没有特色,就和现成软件看不出差别;什么都往里塞,又会变得臃肿;用着不顺手,也就没有继续用的欲望。所以很多东西我们是故意不做的。
比如放弃了好友,也没有做一套管理员用户管理后台。想改某个账号是不是管理员,得自己进数据库改;第一个邀请码也要自己往库里加。这些确实不够省事,但也是轻量化的取舍:少一套管理面板,就少一堆用不上的复杂度。
现有功能的测试结果还算可观,但还有提升空间。他这边的优先级也比较清楚:先把文件夹上传和下载做扎实,再继续打磨界面交互;等到以后有客户端软件出来,这个项目才算真正完整。
接下来真要继续做,应该会先从文件夹上传和下载开始。它既是批量上传、定时更新的基础,也关系到以后要不要做客户端。响应式和分享码这些问题也会补,只是得等我们先忙完最近这段时间。
"隔着六个小时的时差,把一份档案放进同一间房间。"
留言板
We respect your privacy. Gravatar/GitHub profiles are used only for display.