不会前端,不花一分钱,我给自己做了个照片墙的网站

date
May 4, 2024
slug
make-a-photo-wall-site-with-chatgpt-and-no-money
status
Published
tags
编程开发
summary
事情的起因是这样的,最近在RSS上订阅了一些博主,偶然发现有个博主还有一个自己的照片网站,就是把自己拍的照片放到自己的网站上,我觉得蛮有意思的,要不也给自己搞一个。那网站的照片放哪呢,为此去花钱买个对象存储也不值得。所以我就去翻了下cloudflare的网站,不愧是互联网里的活菩萨,它提供的对象存储(即R2)每个月有10GB的免费额度,还不限制访问流量。我一般是用手机拍照,一张照片通常在4MB左右,也就说在R2上可以存储2500多张照片,这不用太浪费了。
type
Post
事情的起因是这样的,最近在RSS上订阅了一些博主,偶然发现有个博主还有一个自己的照片网站,就是把自己拍的照片放到自己的网站上,我觉得蛮有意思的,要不也给自己搞一个。那网站的照片放哪呢,为此去花钱买个对象存储也不值得。所以我就去翻了下cloudflare的网站,不愧是互联网里的活菩萨,它提供的对象存储(即R2)每个月有10GB的免费额度,还不限制访问流量。我一般是用手机拍照,一张照片通常在4MB左右,也就说在R2上可以存储2500多张照片,这不用太浪费了。
当然促成我做这个照片墙的网站目的其实还有几方面。一是我想用一个最简单项目来验证chatgpt能在开发一个项目上帮我做到哪个程度。二是我也想借此玩一下当下一些主流的技术,了解下他们的能力和边界。三是我确实偶尔也想有个自己的照片网站,之后博客和照片都将是用来表达自己的想法的方式。
虽然我用Javascript和Node.js开发过很多年的后台服务,但是你要让我写个网站这事对我来说还是有点难度的,还要考虑不同浏览器以及移动端的兼容性问题。另外因为关注独立开发,所以也听说了不少不错的技术栈,所以在开干前,心里还是有个大致的架构在的。所以我就开干了。
这个网站的核心功能只有一个,就是展示照片。先展示照片的小图列表,再通过点击照片到详情页看详细的大图。额外的功能就是顶部加个导航栏,底部也加个底部栏。看起来好像还缺了个上传照片的功能,但是做这个功能太麻烦了,少说也得做个登录界面,还要做个上传的表单,一顿下来,没少工作量。后面我会说下在不需要开发上传图片页面的情况下,怎么实现在苹果的任何设备(iphone、ipad和mac)快速的上传照片。
MVP确定了,那就可以确定技术栈了:
  1. 开发语言:Javascript、Typescript
  1. 网站框架:Next.js
  1. UI框架:Tailwind css
  1. 对象存储:Cloudflare R2
  1. 服务部署:vercel
  1. 域名管理:Cloudflare DNS
用Javascript的原因主要还是可以同时用来开发前后端,配合Typescript可以做到静态语言的类型检查。至于框架上选Next.js也是因为这几年名声很大,所以想尝试下,借此也了解了下CSR和SSR的区别。至于UI,也毫无疑问tailwind,毕竟我是完全的css小白,这种事交给专业的框架来做就好了。部署的话,既然选了next.js,那自然就先用vercel,毕竟同个公司做的,部署也方便。
接下来就可以开始找Chatgpt了,我目前是4.0的版本,所以对它还是寄以厚望的。先告诉它项目背景(功能、技术栈等),接着问它怎么创建工程,怎么先造点假数据把网页的模样做出来。基本模样搞出来了,就得加点样式的魔法了,让他根据我期望的页面效果给出tailwind css的class,说实在的,那些class我做完后至今我都不知道是啥意思,反正能用就行了。
页面这块,靠着半吊子的前端知识,然后和chatgpt的来回疯狂输出,基本上是都搞定了。但在这里我还是出现了第一个卡点,当我做到一半时在想,点击图片是不是弹个大框也可以,不用进详情页。于是让chatgpt帮我实现,它告诉我说要实现一个模态(Modal)窗口,但是来回问了好几次,都没法实现我要的效果,一堆乱七八糟的class,再加上一些react的状态管理,调试了好久都没成功。在这个过程中,我也了解到,一旦加上状态管理,默认采用后端渲染的组件就变成前端组件(Client Component),我自己是期望所有组件都能在后端完成渲染后再返回给浏览器的,也就是SSR,能不让浏览器干的尽量都不要干了。但后来实在搞不定还是放弃了弹框展示的想法。
页面结构基本搞定了,就可以开始实现从R2获取图片了。我先去Cloudflare R2的管理页面上手动上传一些照片用于测试(当然后面肯定不能这么做,太原始了,也很不方便)。虽然R2可以对外公开,也就是你上传的照片可以用cloudflare提供的域名在互联网上公开访问,但我隐约觉得把对象存储这样公开不是很好的样子,而且我还要公开用于上传图片的接口。于是简单阅读了下R2的文档后,了解到可以实现一个Cloudflare的worker,用它来负责上传和读取R2的照片。worker就是cloudflare提供的serverless应用,同样也是免费的。为什么要用worker,而不是直接在网站里读取,是因为听说cloudflare对next.js的支持不是很好,官方也没有提供示例。当然主要原因还是我也想借此玩一下cloudflare的worker。所以写了一个100多行代码的worker用来查看和上传R2的照片,然后部署到了cloudflare,绑定了域名公开了出来。
之后就是去项目那里读取照片了,这一块没什么难度,怎么在next.js里发送请求,怎么应用到组件里,问chatgpt基本都已经能帮你实现。不过像照片墙这种功能,大多时间里照片数量都没有发生变化,你现在访问和一小时后访问,还是这些照片。后台渲染组件的时候其实不需要每次都去worker那里请求,之前在阅读next.js文档的时候也了解过这块,所以也根据文档稍微优化了下逻辑,让next.js获取到照片后缓存一小时,在调用fetch的时候多加个参数即可。
导航栏这些也没啥好说了,问chatgpt也能实现,难度不大。我还给网站加了RSS的功能,所以你如果感兴趣也可以通过RSS来订阅我之后的更新😁。
前面说到我不想开发一个上传界面的功能,可能会涉及到登录和上传的前后端的开发,而且我也不想每次上传都要跑到电脑上来做,更不可能为此开发一个移动端。于是我找了个利器,苹果的快捷指令。我已经通过cloudflare的worker实现了上传图片到R2的功能,并对外提供了API,通过域名发送上传请求即可,当然这是需要密钥的。我再创建一个苹果的快捷指令,执行指令的时候会让我从苹果的照片app中选择一张照片,然后调用这个API完成图片上传到R2的功能,操作非常丝滑,重点是在iphone、ipad、mac都能使用。
项目的部署就很简单了,代码提交到github后,去vercel那里创建一个项目,选择github上对应的仓库即可完成部署。我会先去cloudflare那里把域名的DNS配置好(CNAME到vercel),然后到vercel的这个项目里,把域名配置上去即可,然后就可以用你自己的域名访问你的网站了。
notion image
整个过程我和chagpt交流的非常多,所以还是想总结下使用的体验。
  1. 确实能够帮你完成很多事情,大多逻辑都能帮你实现,甚至你可以截个图让他实现,也可以把有问题的代码发给他,问他里面的报错怎么解决,它通常都能给出解决方案。而且对于你不懂的,他还能给出解释,像tailwind这种,他还能给出一些class的含义,让你当下在用的时候也能理解为什么要这么用。
  1. 回答的语言时不时抽风,我一直都是用中文和chatgpt交流,但提问的prompt里可能会有一些英文,他会时不时的就回答英文,我后面也强调始终用中文回答我的问题,还是会出现他返回给我英文答复的情况。
  1. 由于next.js提供了app router和page router两种开发模式,chatgpt回答的时候大多数都会提供page router模式下的方案,而我用的是app router,所以我时不时的还要让他给我在app router下的代码,我同样也强调了我的模式,还是没什么效果。
  1. 我很多时候期望它给出的代码是基于之前的功能上添加的,新增的代码也希望能够基于之前它已经给过的代码下添加,这些要求我发现chatgpt基本不能得到,需要我时不时去提醒,可能才可以做到。
  1. 当我和chatgpt来回对话了很多次后,在后面提问的时候,回答的速度会显得很慢,可能是上下文内容太多了。
  1. chatgpt有时候喜欢自己造轮子实现,但这个功能可能已经有开源的第三方库可以使用,我时不时的就得提醒下(例如RSS的功能)。
得益于国外强大的saas平台,服务部署(vercel和cloudflare worker)、域名管理、对象存储(R2)、HTTPS 都没有花一分钱。当然域名肯定是要买的,但有些域名其实也很便宜,成本基本可以不计。不得不说开发一款产品的成本越来越低了。
这就是我做的照片墙网站了,欢迎你有空来访问。
 
另外说个题外话,我通常在rss阅读器里看我订阅的博客,对于英文的博客,如果能快速地让我知道博客的概要,将很大程度能提高我阅读的兴趣。受快捷指令启发,我便做了个对链接里的内容进行总结的快捷指令。当我在阅读器里复制文章的链接后,再执行这个快捷指令,它会调用Kimi AI对链接的内容进行总结,最后会询问是否要发送到备忘录(目的也是考虑到当下可能还没有时间看,可以先放到备忘录晚点来阅读和整理)。为了方便使用这些指令,iphone上我把他们都放到了主屏幕,mac上则显示在顶部菜单栏。我开始觉得可能有很多事情都可以用快捷指令来做,只是我还没想到。
notion image
notion image
notion image
notion image