本文由 莫潇羽@源码七号站(www.fuyuan7.com)撰写,转载请注明出处。
一、快速摘要:3 分钟看懂 PinMe 2.0 到底是什么
PinMe 2.0 是一个"零配置"的全栈项目部署 CLI 工具。它把"前端 + 后端 Worker + Serverless SQL 数据库"这一整套技术栈打包成一条命令,让你在 pinme create my-app 之后跑一句 pinme save,就能把一个完整的全栈应用直接推到全球边缘节点上跑起来。它的底层把 IPFS 内容寻址、ENS 子域名、eth.limo 网关、边缘 Worker 运行时、Serverless SQL 串成了一条流水线,不用买服务器、不用配 Nginx、不用申请 SSL、不用配 DNS,甚至连账号都可以匿名先用起来。更关键的是,它专门为 AI Agent 设计了可机读协议,通过一行 npx skills add glitternetwork/pinme,你的 Claude Code、Cursor 之类的 AI 编程助手就直接获得了"自己把代码发布到互联网"的能力。
这篇文章会从原理、架构、安装、实操、AI 联动一路拆到避坑技巧,把我自己折腾这套工具的体验完整复盘一遍。
想看完整拆解,往下翻 👇
二、为什么独立开发者最怕"上线"这一步
做过独立项目的人多多少少都有这种体会:把功能写出来其实是整个流程里最有成就感的部分,真正让人抓狂的反而是"怎么让别人能访问"。
我自己刚开始做小工具的时候,踩过的坑能写一篇长文。代码 demo 本地跑得好好的,一旦想发给朋友看,问题就排着队往外冒。先得搞一台云主机,买之前还要纠结买 1 核 2G 还是 2 核 4G、要不要选境外节点、流量包够不够;主机到手之后开始装 Nginx,配反向代理,配静态资源缓存;再去申请一个域名,改 DNS 解析,等运营商生效;然后还得搞一份 SSL 证书,过去要花钱买,现在虽然有 Let's Encrypt 这种免费方案,但脚本写错一点 cron 自动续期就挂了。
如果项目只是一个静态页面也就罢了。一旦项目里加上后端接口、加上数据库,整个工作量就翻番。后端要写 systemd 服务文件,要配进程守护,要做日志切割;数据库要装、要建表、要做用户授权、要规划备份策略。等所有这一套搞完,可能两天就过去了,你这时候才能把项目链接发给朋友。最讽刺的是,如果朋友给你提了点修改意见,你修完代码还得手动 SSH 上去 git pull、重启服务、清缓存。
这就是独立开发者长期以来面对的"基础设施税"——你不是在做产品,你是在给云厂商打工。
更糟的是,这层税还是长期持续的。买的云主机要按月续费,域名一年一续,SSL 证书要管理过期,服务器系统要定期打补丁,数据库要做备份。每一项都不重,但累加起来就是一份持续不断的注意力开销。很多独立项目最后死掉不是因为想法不好,而是因为作者实在懒得维护这些杂事,慢慢就放弃续费了。这种现象多到一定程度,你会发现独立开发者圈子里很多被点过赞的小项目,几年后回去访问全是 404。
2.1 现有方案的局限
近几年其实出现了不少试图解决这个问题的方案。Vercel、Netlify、Cloudflare Pages、GitHub Pages,每一个我都用过一段时间,但每一个都有自己的边界。
Vercel 体验是真的好,推 GitHub 自动构建自动上线,几乎是当代部署体验的天花板。但它的免费额度对中国大陆访问不太友好,境内访问延迟较高,而且一旦你的项目里需要持久化的数据库,Vercel 自身的免费方案就要拉别的服务商来配套,链路一下子就长起来了。
Netlify 跟 Vercel 思路类似,免费层够用,但同样的境内访问问题。GitHub Pages 是真便宜,可惜只支持静态站点,稍微想加一点后端逻辑就要绕远路。Cloudflare Workers 配合 D1 数据库已经非常接近"一站式全栈",但配置 wrangler.toml、绑定 D1、设置环境变量、申请 API Token,这一整套对新手依然有门槛。
更深一层的问题是:这些平台都是中心化的。账号被封、项目被下架、平台政策调整,任何一个环节出问题,你的网站就上不去。对个人作品集、社区资料、长期想留下来的内容来说,这种悬在头顶的不确定感始终是个心病。
2.2 AI 编程时代,部署成了新的瓶颈
这两年 AI 编程工具的能力提升得有点离谱。让 Claude、Codex、Cursor 帮我写一个完整功能的小工具,只要 prompt 给得清楚,几分钟就能出代码。但下一步呢?AI 写完了代码,谁来部署?
我之前做过一个尝试,让 AI 帮我把一个想法跑通,从需求理解到代码生成全程没碰键盘,最后所有文件躺在我电脑上。这时候我意识到一个特别拧巴的现象——AI 把"动脑子"那一段已经替我搞定了,但部署那段"动手"的活儿,反倒成了卡点。
如果 AI Agent 自己就能把代码发布到公网,事情就完全不一样了。整个工作流会变成:你描述需求 → AI 写代码 → AI 自己部署 → 你收到一个能在浏览器里打开的链接。这才是 AI 编程的完全体。
PinMe 2.0 想解决的,就是这个时代背景下的两个核心问题:给人用,要足够无脑;给 AI 用,要足够"协议化"。它的目标是把部署这件事从"需要专业知识的体力活"压成"一条命令"。下一节我们就来看看,这条命令背后到底是怎么把这件事做出来的。莫潇羽@源码七号站 在折腾完整套流程之后,觉得这个思路确实有点意思,值得展开说说。
三、PinMe 是什么:把"创建项目→上线"压缩成一条命令
简单一句话定位:PinMe 是一个一行命令上线全栈应用的零配置 CLI。它的官方口号写得很直接——"Create and deploy your web in one command"。
听起来很像那些营销话术,但它的"一行命令"是有具体所指的。我们对比一下传统流程和 PinMe 流程,差距就比较直观了。
3.1 一张对照表,看清两种流程的差距
|
环节 |
传统部署方式 |
PinMe 方式 |
|
服务器准备 |
买云主机、装系统、配防火墙 |
完全不需要 |
|
Web 服务器 |
装 Nginx、写反向代理配置 |
内置边缘运行时 |
|
SSL 证书 |
申请、配置、自动续期脚本 |
自动签发 |
|
域名解析 |
买域名、改 DNS、等生效 |
自动绑子域名 |
|
后端运行环境 |
systemd 守护、日志切割 |
Worker 全球分发 |
|
数据库 |
装 MySQL/PG、建表、备份 |
Serverless SQL 自动开通 |
|
项目脚手架 |
自己 init、装依赖 |
一条 |
|
后续更新 |
git pull、构建、重启服务 |
|
可以看到,它做的不是"简化"某一步,而是把整条流水线全压扁了。
3.2 它的核心特性可以拆成三块
第一块是 零配置部署。其他平台多多少少会让你写点配置文件、改改环境变量、勾选构建命令,PinMe 把这层全省了。不用注册账号(匿名也能用)、不用配服务器、不用管证书、不用碰 DNS,只要本地有一个 Node.js(16.13.0 以上),从安装 CLI 到第一次上线,十分钟绰绰有余。
第二块是 全栈一键搞定。这是 2.0 版本最大的跃迁。1.0 时代 PinMe 主要解决"静态网站发布"的问题——把 dist 目录推到 IPFS 上,拿到一个永久链接。2.0 直接把后端和数据库一起打包进来,这意味着你用一条 pinme create 拿到的不再是一个静态模板,而是一个"前端 + 后端 + 持久化"的完整全栈骨架,前端可以是 Vite、React、Vue、Next.js、Angular、CRA 任选,后端是基于 Edge Runtime 的 Worker,数据库是开箱即用的 Serverless SQL。
第三块是 AI Agent 原生支持,也是我个人觉得最有想象空间的一块。PinMe 专门为 AI Code Skill 设计了协议,提供了可机读的配置和清晰的命令边界。你只要给 AI 装上 PinMe Skill,AI 就能像人类一样调用 pinme create、pinme save、pinme upload 这一整套命令,把它自己刚写完的代码送上线。
3.3 跟传统部署方案的差异在哪
PinMe 不是 Vercel 的替代品,它更像是另一种思路的延伸。最大的差异点是:底层走的是 IPFS + ENS 这套去中心化基础设施,而不是单一云厂商的中心化机房。
这带来几个好玩的特性:
- 抗下架:内容存在 IPFS 网络上,多节点冗余,理论上没有任何单一机构可以"删掉你的站点"。
- 永久链接:每次部署的内容哈希都是固定的,旧版本不会被覆盖,可以一直访问。
- 自带全球分发:不用自己买 CDN,IPFS 网关本身就是分布式的;Worker 部分跑在边缘节点上,从用户视角看就是天然低延迟。
- 匿名友好:不强制绑定账号才能用,先用起来再说,体验门槛低到几乎没有。
当然作为代价,IPFS 网关的访问速度跟一线 CDN 相比还是有差距,这点后面会单独讲。莫潇羽的实操体验是:对个人项目、原型展示、AI 生成页面这类场景,这种"快、自由、永久"的取舍非常划算。
四、底层原理拆解:IPFS + ENS + Edge Worker + Serverless SQL 是怎么串起来的
很多人看 PinMe 的命令觉得"挺神奇的",其实背后的技术栈一点都不神秘,只是被精心包装得让用户感觉不到复杂度。这一节我们把它拆开,看清楚每一块技术在整个链条里扮演什么角色。
4.1 IPFS:让"文件"有一个永久身份证
要理解 PinMe,先要理解 IPFS(InterPlanetary File System,中文一般叫"星际文件系统")是什么。
传统的网站访问是"按位置寻址":你访问 https://example.com/index.html,本质上是告诉浏览器"去 example.com 这台服务器的特定路径上取一个叫 index.html 的文件"。一旦那台服务器宕机、被关、被攻击,这个 URL 立刻就废了。
IPFS 走的是另一条路线——按内容寻址(Content Addressing)。你把一个文件丢进 IPFS,系统会根据文件内容计算出一个唯一的哈希(CID,Content Identifier),比如 bafybeifdwyoz66u5czbbjvmmais5fzrzrolxbyiydqsbrxessndt3s6zdi 这样的字符串。以后任何人想访问这个文件,只要拿着这个 CID 去问 IPFS 网络:"谁有这个内容?"网络里任意一个保存了这份数据的节点都可以把内容返回给你。
这种模式有几个特别重要的性质:
- 内容防篡改:CID 是内容的哈希,内容只要改一个字节,CID 就完全变了。所以一个 CID 对应的内容永远是确定的,没法被"偷偷换掉"。
- 多节点冗余:同一份内容可以同时存在很多节点上,某个节点挂了,网络里其他节点照样能提供服务。
- 永久可访问:只要这份内容还被至少一个节点"固定"(Pin)着,它就一直能被访问。
PinMe 的"Pin"就是从这儿来的——它本质上是一个 Pinning 服务:帮你把项目文件 Pin 到 IPFS 网络上,确保它持续可访问。
这里有一个新手最容易混的概念,顺手解释一下。IPFS 网络里的数据不是"传统意义上的存了就一直在"。任何一个节点都可以随时清理掉本地的内容缓存,所以一份内容如果没人主动 Pin,理论上可能从网络中被逐渐清除。"Pin"这个动作的含义就是:某个节点向网络宣告"我保证持续保存这份内容"。PinMe 在背后做的事情,就是用它自己的 IPFS 节点集群,长期保有你 push 上来的所有内容,这样你哪怕本地电脑关机了,内容也照样在网络上可访问。
再说说IPFS 的查找逻辑,这块理解清楚后面用起来心里就有数了。当浏览器收到一个 IPFS 请求,它会向 IPFS 网络里的几个已知节点询问"有没有 CID 为 xxx 的内容?",节点之间通过 DHT(分布式哈希表)路由,最后定位到持有这份内容的某个节点,把数据返回。这种机制决定了 IPFS 的访问速度取决于节点分布和你与最近节点的网络距离——节点分布广、PinMe 自己又有专门的网关加速,体验才能勉强接近传统 CDN。
4.2 ENS:给 IPFS 哈希套一个人类能记住的名字
直接用 IPFS 哈希访问网站当然可以,但你试过把 bafybeifdwyoz66u5czbbjvmmais5fzrzrolxbyiydqsbrxessndt3s6zdi 这种东西发到群里吗?发完估计会被人当成乱码举报。
所以需要一个"翻译层",把人类能记住的名字翻译成 IPFS 哈希。传统互联网是 DNS 干这件事,把 example.com 翻成 IP 地址。Web3 世界里干同样事情的,叫 ENS(Ethereum Name Service,以太坊命名服务)。
ENS 跟 DNS 在用法上很像,但记录是存在以太坊区块链上的,理论上没法被任何中心化机构篡改。一个 ENS 域名(比如 pinit.eth)可以解析到一个 IPFS 哈希(通过 ENS 的 contentHash 字段),用户在浏览器里输入这个域名,就能直接拿到对应的 IPFS 内容。
PinMe 在这一层做的事情是:你部署项目时,它会自动给你分配一个 ENS 子域名,比如 my-app.pinit.eth,并把这个子域名指向最新的 IPFS 哈希。当你 pinme save 一次,它就更新一次指向。
4.3 eth.limo:让普通浏览器也能直接打开 .eth
ENS 有个小麻烦:.eth 这个后缀,普通浏览器是不认的。Chrome 收到 pinit.eth 这种地址,默认不会去查以太坊。
eth.limo 这种 ENS 网关就是来解决这个问题的。它本质上是一个公共网关,你访问 my-app.pinit.eth.limo,网关会自动:
- 看到
.eth子域名,去以太坊上查这个 ENS 名对应的 contentHash; - 拿到 IPFS 哈希;
- 去 IPFS 网络上把内容拉回来;
- 通过 HTTPS 返回给你的浏览器。
整个过程对用户来说就是一次普通的 HTTPS 访问,跟访问 example.com 没有体验上的区别。这就让"去中心化网站"对普通用户也变得无感且可用。
flowchart LR
A[浏览器输入 my-app.pinit.eth.limo] --> B[eth.limo 网关]
B --> C[查询以太坊 ENS contentHash]
C --> D[拿到 IPFS CID]
D --> E[向 IPFS 网络请求内容]
E --> F[返回 HTML/JS/CSS]
F --> G[浏览器渲染页面]
4.4 Edge Worker:让后端代码在全球边缘节点跑起来
静态文件可以丢 IPFS,但动态接口怎么办?2.0 版本的 PinMe 给出的答案是:Edge Runtime Worker。
Edge Runtime 这个概念这两年挺火,简单理解就是一种轻量级的 JavaScript/WebAssembly 运行时,部署在全球几十甚至几百个 PoP(Point of Presence)节点上。当用户发起一个请求,网络会自动把请求路由到离用户最近的 PoP,你的后端代码就在那个 PoP 上执行,然后把结果返回。
跟传统的"中心化机房 + 多区域副本"相比,Edge Worker 的优势是:
- 天然低延迟:代码就在用户附近跑,RTT(往返时延)能压到几十毫秒以内。
- 冷启动极快:基于 V8 isolate 这种轻量级隔离机制,启动开销远低于传统容器或函数计算。
- 无服务器:不用关心机器在哪、起多少个、怎么扩容。
PinMe 项目里的 worker/ 目录,装的就是你的后端代码。pinme save 时它会把这部分代码构建、上传、分发到全球节点。从你部署完那一刻起,理论上全世界任意一个用户都能从最近节点拿到你的接口响应。
值得多说一句的是,Edge Worker 跟传统 Node.js 后端写起来略有差异。Edge Runtime 出于安全和性能考虑,默认是不带完整 Node.js API 的——比如没有 fs 文件系统,没有 child_process,某些 Node 原生模块不能直接用。它给你的是一套基于 Web Standards 的 API:fetch、Request、Response、crypto.subtle、URL 这些。
对绝大多数 Web 后端逻辑来说,这套 API 已经够用了。如果你之前写过 Cloudflare Workers、Vercel Edge Functions、Deno Deploy,会发现切换到 PinMe 的 Worker 几乎无缝。如果你过去只写过传统 Node + Express,那需要稍微调整一下思路:不要去写 require('fs').readFileSync(...),而是把静态资源放到前端、把动态依赖通过 fetch 调外部 API。
4.5 Serverless SQL:边缘运行时旁边那个开箱即用的数据库
光有 Worker 不够,大多数应用都得有数据要存。所以 PinMe 2.0 又集成了一层 Serverless SQL,设计思路跟 Cloudflare D1 非常接近——一个基于 SQLite 的、跑在边缘的、按需付费的关系型数据库。
它的核心特征:
- 你不需要自己管实例、不需要管备份、不需要管扩容。
- 用标准 SQL 语法,跟传统 SQLite/MySQL 写起来差不多。
- 数据库节点在边缘网络上,跟 Worker 在同一个网络平面,延迟极低。
- 创建项目时自动开通,绑定到对应的 Worker,不需要手动配连接串。
跟传统数据库相比,Serverless SQL 在用法上有几个需要适应的地方。第一,它鼓励"短连接 + 短事务"——边缘环境下不存在传统意义上的长连接池,每个 Worker 请求都是独立的执行实例,你不需要也不应该去做"连接复用"那一套传统优化。第二,复杂的存储过程、触发器、外键约束之类的高级特性,边缘 SQLite 支持得相对克制。如果你的业务本来就高度依赖这些特性,可能需要权衡一下;但对绝大多数 CRUD 型业务来说,它能处理得很好。第三,迁移是声明式的——你把 .sql 文件丢到 db/ 目录,PinMe 在部署时自动按序执行,版本管理交给目录里的文件名,简单粗暴但实用。
┌──────────────────────┐ edge runtime call ┌──────────────────────┐
│ Edge Worker (JS) │ ─────────────────────► │ Serverless SQL (D1) │
│ 你的后端业务逻辑 │ │ 开箱即用的关系库 │
└──────────────────────┘ ◄───────────────────── └──────────────────────┘
到这里,整个技术拼图就完整了:静态资源走 IPFS + ENS + 网关,动态逻辑走 Edge Worker,数据持久化走 Serverless SQL。PinMe 干的事情,就是把这四块各自都不简单的技术,在用户视角下抹平成一句 pinme save。这种"用工程把复杂度藏起来"的设计,正是莫潇羽@源码七号站 觉得 PinMe 最值得拆开来看的地方——它不是发明了什么新东西,而是把一组很硬核的现代基础设施,变成了任何一个会用 npm 的人都能享受的能力。
五、PinMe 2.0 全栈架构:前端、后端、数据库三件套是怎么协作的
上一节讲的是技术底座,这一节我们把视角拉到"开发者实际接触到的目录结构"上,看看 PinMe 2.0 是怎么把前端、Worker 后端、Serverless SQL 这三块组织在同一个项目里的。
5.1 monorepo 风格的目录组织
执行 pinme create my-app 之后,你会拿到一个长这样的目录结构:
my-app/
├── pinme.toml # 核心配置文件,所有部署参数都写在这里
├── package.json # 工作区根配置(monorepo 入口)
├── worker/ # 后端 Worker 代码
│ ├── src/
│ │ └── index.ts # Worker 入口
│ ├── package.json
│ └── tsconfig.json
├── frontend/ # 前端项目
│ ├── src/
│ │ └── main.ts
│ ├── package.json
│ ├── vite.config.ts
│ └── dist/ # 构建产物(自动生成,不用手动碰)
├── db/ # 数据库迁移文件
│ └── 001_init.sql
└── .env.example # 环境变量样板
这是个典型的 monorepo(单一仓库托管多个子项目)结构。前端、后端、数据库各自独立,但共享同一份顶层配置和部署流水线。
这种组织方式的好处很直接:你心智里有一张清晰的地图。"前端要改样式?去 frontend/ 改;后端逻辑出 bug 了?去 worker/src/index.ts 改;要加张表?在 db/ 里加一个新的 .sql 文件。"分工边界清楚,改起来不会乱。
5.2 pinme.toml:整套部署的"中枢神经"
pinme.toml 是整个项目的心脏。它告诉 CLI:这个项目叫什么、前端构建目录在哪、Worker 入口在哪、数据库迁移在哪、域名怎么绑。一个简化版的样例长这样:
[project]
name = "my-app"
version = "1.0.0"
[frontend]
build_command = "npm run build"
output_dir = "frontend/dist"
[worker]
entry = "worker/src/index.ts"
compatibility_date = "2026-01-01"
[database]
migrations_dir = "db"
name = "my-app-db"
[deploy]
domain = "my-awesome-app"
这份配置文件的设计哲学很"基础设施即代码"——所有部署所需的元信息都写在文件里,跟代码一起进版本控制。换电脑、换协作者、回退到旧版本,部署行为都是确定的。
5.3 三块怎么协同?一次完整的请求流向
光看目录结构还不够直观,我们追一个具体的请求,看它在三块之间是怎么流动的。
假设你在前端写了一个"提交反馈"的表单,用户点击提交后,会发起一个 POST 请求到 /api/feedback。整条链路大概是这样:
sequenceDiagram
participant U as 用户浏览器
participant E as eth.limo / IPFS 网关
participant W as Edge Worker
participant D as Serverless SQL
U->>E: GET /index.html (访问站点)
E-->>U: 返回前端静态资源
U->>W: POST /api/feedback (提交表单)
W->>D: INSERT INTO feedback (...)
D-->>W: 写入成功
W-->>U: 200 OK { id, createdAt }
几个关键点:
- 前端静态资源走的是 IPFS 网关,内容是定死的、可缓存的、永久可访问的。
- 接口请求直接打到边缘 Worker,Worker 内部组织好业务逻辑,该读数据库读数据库,该调外部 API 调外部 API。
- 数据库是边缘 Serverless SQL,跟 Worker 在同一个网络平面,延迟极低。
整套架构对新手特别友好的一点是:你不需要自己思考"前后端怎么粘起来"这个问题。PinMe 会自动把 Worker 暴露成一个跟前端同源的 API 路径,前端可以直接 fetch('/api/xxx'),不用考虑 CORS、不用配代理、不用搞 nginx 转发。
5.4 跟 Vercel + Supabase 这种组合的对比
很多人可能会问:这跟"Vercel 部前端 + Supabase 做后端"有什么区别?
我个人的体验是,差异主要在两个维度:
第一个维度是"集成度"。Vercel + Supabase 是两个独立平台,你要分别注册账号、分别配置、分别连接。链路里多一个外部服务,就多一份配置成本和故障面。PinMe 2.0 是把三层一次性给齐,你只面对一个工具、一个配置文件。
第二个维度是"基础设施风格"。Vercel + Supabase 还是中心化的,数据放在他们机房;PinMe 走的是去中心化路线,前端在 IPFS 上,后端跑在边缘网络上。前者性能更强、生态更成熟;后者更自由、更抗审查、更适合"想长期留下点东西"的小项目。
没有谁绝对优于谁,看你的取舍。如果你的项目对性能 SLA 极度敏感,选成熟方案;如果你的项目是个人作品、是 AI 生成 demo、是一个想"发出去就长在那儿"的轻量站,PinMe 这种思路反而更舒服。
5.5 一体化方案为什么对个人开发者特别友好
把前端、Worker、数据库整合在一个 CLI 里,这件事看起来只是"少装几个工具",实际带来的工程价值比想象中大。
心智负担降一个数量级。你只需要记住一个工具的几条命令,不用同时在脑子里维护"Vercel 怎么用、Supabase 怎么连、Cloudflare D1 怎么 migrate"这一大堆细节。对个人开发者来说,大脑容量是稀缺资源,能省一点是一点。
错误面变窄。链路里每多接一个外部服务,就多一份"它什么时候挂"的可能性。一体化方案虽然把所有鸡蛋放在一个篮子里,但篮子的接缝更少、协议更统一,出问题时排查路径也更短。
升级和回滚是原子的。pinme save 跑一次,前端、Worker、数据库迁移要么一起成功,要么一起失败,不会出现"前端推上去了但 Worker 没更新"这种中间态。这种原子性对生产环境的稳定性是有意义的。
六、从零开始:完整的环境准备与安装步骤
讲完原理和架构,该上手了。这一节我会按"第一次接触 PinMe 的新手"视角,把环境准备到首次部署的每一步都拆开讲。
6.1 最低环境要求
PinMe 本质是个 Node.js 写的 CLI,所以最重要的依赖就是 Node.js 自身。官方给出的最低要求是 Node.js >= 16.13.0,但我个人强烈建议直接上 Node.js 18.x LTS 或更高——一来 16 已经退役了,二来 18+ 对 fetch、URL、AbortController 这些 Web 标准 API 支持更完整,跑 Edge Worker 的本地开发会更顺。
你需要的清单很短:
- Node.js 18.x LTS(或更新版本)
- npm 或 yarn(任选一个包管理器,看个人习惯)
- 一个能稳定连接到互联网的网络环境(用于上传内容到 IPFS)
- 一个文本编辑器(VSCode、Cursor、Sublime 都行)
如果你用 Windows,推荐顺手装一个 WSL2,把开发环境放进 Linux 子系统里;不是必须,但日子会舒服很多。
6.2 检查并安装 Node.js
打开终端,先看一眼当前的 Node 版本:
node --version
# 期望输出:v18.x.x 或更高,比如 v20.11.0
如果显示"command not found",或者版本号低于 16.13.0,就需要先装/升级 Node。莫潇羽@源码七号站 一贯的建议是用 nvm 管理 Node 版本,而不是直接装系统级别的 Node。这样以后想切版本、想隔离不同项目的 Node 版本,几行命令就能搞定。
# macOS / Linux 安装 nvm(以官方一键脚本为例)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# 重新打开终端后
nvm install 20 # 安装 Node.js 20
nvm use 20 # 切换到 20
node --version # 验证
Windows 用户可以装 nvm-windows,逻辑差不多。
6.3 全局安装 PinMe
Node.js 准备好之后,装 PinMe 就一行命令的事:
npm install -g pinme
或者用 yarn:
yarn global add pinme
装完之后验证一下:
pinme --version
# 期望输出类似:2.0.x
如果显示"command not found",大概率是全局 npm 的 bin 目录没在 PATH 里。macOS/Linux 下可以用 npm config get prefix 看一眼前缀路径,把对应的 bin/ 加到 PATH 即可。Windows 下重启一次终端通常就好。
6.4 首次登录认证
PinMe 支持匿名使用,但要享受全部功能(自定义子域名、Plus 特性、Worker/数据库的持久绑定等),需要走一次登录:
pinme login
这个命令会自动拉起你的默认浏览器,完成 OAuth 类型的授权流程。授权通过之后,CLI 会拿到一份认证凭证,本地保存,以后不用每次都登。
我自己第一次用的时候踩过一个小坑:在远程 Linux 服务器上跑 pinme login,服务器没图形界面,浏览器拉不起来,命令就卡住了。后来发现可以通过 AppKey 方式离线登录:
pinme set-appkey <你的 AppKey>
pinme show-appkey # 查看当前生效的 AppKey
这种方式非常适合 CI/CD 环境或者无头服务器场景。在 GitHub Actions 里,把 AppKey 放进 Secrets,流水线里 pinme set-appkey "${{ secrets.PINME_APPKEY }}",就能让自动化部署也用上 PinMe。
6.5 几个常用辅助命令
为了让你心里有底,这里把几个常用的辅助命令汇总一下:
pinme --version # 查版本
pinme --help # 看所有可用命令
pinme login # 登录
pinme logout # 登出
pinme appkey # 查看 AppKey
pinme list # 列出最近的部署历史
pinme ls -l 5 # 只看最近 5 条
pinme list -c # 清空历史
pinme my-domains # 列出自己绑定过的子域名
记不住没关系,pinme --help 是任何时候都能救命的命令。装完 CLI、登录完成,环境就 ready 了,下一节我们开始动手跑一个完整的全栈项目。
七、实操拆解:一行命令搞定全栈项目的完整流程
环境备好,接下来按真实工作流跑一遍。整个流程可以拆成"创建 → 查看 → 修改 → 部署 → 绑域名"五步,我会把每一步的预期输出和我自己踩过的坑都写出来。
7.1 第一步:创建一个全栈项目
进入一个你存放项目的目录,跑下面这条命令:
pinme create my-app
my-app 是你想要的项目名,可以随便起,但建议用小写字母加连字符,避免日后绑定域名时再被名字格式卡住。
这一条命令会触发一整套幕后动作:
flowchart TD
A[pinme create my-app] --> B[创建 my-app 目录]
B --> C[下载官方全栈模板]
C --> D[生成 pinme.toml]
D --> E[npm install 装依赖]
E --> F[平台侧创建 Worker]
F --> G[平台侧创建 Serverless 数据库]
G --> H[首次构建并上传]
H --> I[返回访问链接]
整个过程一般需要 2-5 分钟,主要时间花在装依赖和首次上传上。网络好的话两分钟搞定,网络差可能要五六分钟。命令跑完,你应该会在终端看到类似这样的输出:
✔ Project created at ./my-app
✔ Worker provisioned
✔ Database provisioned
✔ Frontend deployed to IPFS (CID: bafybeixxxxxx...)
🌐 https://my-app.pinit.eth.limo
最后那个链接就是你的项目入口。复制粘贴到浏览器,你应该能看到一个官方模板的初始页面。
我个人的建议:第一次跑的时候不要急着定制项目名,先用一个测试名字跑通整套流程,确认环境没问题之后,再删掉重新建一个正式名字的项目。
7.2 第二步:进入项目目录,熟悉文件
cd my-app
ls -la
前面"五、PinMe 2.0 全栈架构"那一节已经把目录结构画过一遍,这里再强调几个新手最容易困惑的点:
pinme.toml是核心配置,日后绝大多数行为变更都是改它。除非你完全清楚自己在做什么,不要手贱去改name之类的字段——改了之后部署可能会指向一个新项目。frontend/dist/是构建产物目录,别手动往里塞文件,每次构建都会清空。db/*.sql是数据库迁移脚本,文件名前缀的数字决定执行顺序,建议保持001_xxx.sql、002_xxx.sql这种习惯。.env.example是环境变量样板,真正的.env需要你自己 cp 一份并填值。绝对不要把.env提交到 git。
7.3 第三步:本地开发与调试
进入项目后,可以分别启动前端和 Worker 本地开发服务器。具体命令以模板里的 package.json scripts 为准,通常是:
# 启动前端开发服务(默认 5173 端口)
cd frontend
npm run dev
# 另一个终端启动 Worker 本地运行时
cd worker
npm run dev
前端 dev server 会自动把 /api/* 这种请求代理到本地 Worker,所以你可以在本地完整跑通前后端联调,不用每改一次就部署。
数据库本地开发可以用 SQLite 文件版本临时模拟,迁移文件先在本地跑一遍验证 SQL 没问题,再正式部署。
7.4 第四步:部署更新
代码改完、本地跑通,接下来就是把改动同步到线上。这一步在 PinMe 里被压缩成一条命令:
pinme save
注意必须在项目根目录(也就是 pinme.toml 所在的目录)执行。这条命令会按顺序完成:
- 检查依赖:如果有缺失,自动
npm install补齐。 - 构建 Worker:把
worker/src/编译成可部署的格式。 - 上传 Worker:推到平台,分发到边缘节点。
- 应用数据库迁移:把
db/里新增的.sql文件执行到 Serverless SQL 上。 - 构建前端:执行
pinme.toml里配置的build_command。 - 上传前端:把构建产物推到 IPFS,更新 ENS contentHash。
- 返回访问链接。
一次 pinme save 跑完,你的整套全栈应用就更新了。
如果你只改了前端,可以用增量命令(命令名以官方文档为准):
pinme update-web # 只更新前端
pinme update-worker # 只更新 Worker
pin