📌 项目地址:vercel-labs/portless | ⭐ 11,613 颗星 | 🔧 TypeScript | 📜 未标注
问题:端口号在本地开发里到处添堵
同时跑几个项目的人都知道这些摩擦:localhost:3000、localhost:5173、localhost:8080,靠数字区分应用,记不住,还经常被占用。更实际的问题是浏览器对 localhost 和真实域名的处理不一致——secure cookie、Service Worker、混合内容拦截,在裸 localhost 上根本测不出真实行为。
vercel-labs 的 portless(TypeScript,11613 stars)给的方案是给每个本地应用一个稳定的命名域名:
- "dev": "next dev" # http://localhost:3000
+ "dev": "portless run next dev" # https://myapp.localhost
域名就是应用名,HTTPS 和 HTTP/2 默认开启。
五分钟上手
全局安装(README 推荐):
npm install -g portless
或者装进项目:
npm install -D portless
运行:
portless myapp next dev
# -> https://myapp.localhost
首次运行时,portless 生成本地 CA、把它加入信任、绑定 443 端口(macOS/Linux 上自动 sudo 提权)。不需要 TLS 就加 --no-tls。
一个提醒值得写进 README 原话:项目还没到 1.0。装在项目里时,不同贡献者可能跑不同版本;状态目录格式可能随版本变化,需要重新执行 portless trust。
端口分配的机制
proxy 随命令自动启动,给应用分配 4000–4999 之间的随机端口,通过 PORT 环境变量传入。Next.js、Express、Nuxt 这类框架会自动读取。
麻烦在忽略 PORT 的框架:Vite、VitePlus、Astro、React Router、Angular、Expo、React Native。portless 对这类框架直接注入对应的 --port flag,必要时再补 --host。注入能穿透 package script——只要命令以框架名或已知 runner 开头,"dev": "vite" 和 "dev": "bunx vite" 都能识别。
我最欣赏的部分:注入的克制
自动改写用户的命令是危险操作,改错了轻则报错,重则构建产物出错。portless 在这里划的边界很细。
只动真正的服务器命令。 dev、serve、preview、start、裸的 vite 或 vite [root] 会拿到注入的端口。vite build、vite optimize、vp test、astro check 这些不接受端口参数的命令,会被识别出来然后原样放过。
看不懂就不碰。 这些情况全部跳过注入:
- 子命令前有它不认识的 flag(
vp --mode dev build) - 复合命令(
&&、|、;) - 尾部带
#注释,或自带--终结符 - env 前缀(
NODE_ENV=production vite) - 委托给其他脚本(
"dev": "npm run dev:vite") - runner flag 在脚本名前面(
bun run --bun dev)
这些命令保留自己的端口,由用户自己去脚本里设置。Expo 的连接模式(--localhost、--lan、--tunnel)会被保留,同时照常注入分配的端口。
这套”宁可不做,也不做错”的清单,说明作者认真想过失败模式。对一个要改写用户命令的工具,这是能不能被信任的分界线。
配置持久化与 CI 行为
三个细节值得单独说。
代理自动启动时,会复用最近一次运行的配置(端口、TLS、TLDs),重启机器后不会静默回退默认值。显式环境变量(PORTLESS_PORT、PORTLESS_HTTPS 等)永远优先。
状态存在 ~/.portless。代理在 sudo 下运行时,这个路径会从发起用户的 home 解析,这样代理和普通权限的应用进程能共享同一套路由注册——一个容易踩的坑被提前处理了。
无 TTY 或 CI=1 的环境里,portless 直接带描述性错误退出,不卡在交互提示上。turborepo 这类任务运行器和 CI 脚本能尽早失败,错误信息是可读的。
“For humans and agents”
README 副标题里写了 agents。端口号对 AI 编程代理是真实的痛点:端口变了、被占了、和验证脚本对不上,代理只能去猜或重试。稳定的 https://myapp.localhost 让代理每次都用同一个 URL 验证开发服务器,不需要先探测端口。加上 HTTPS 默认开启,代理也不会被 self-signed 证书的报错卡住。
对一个还没到 1.0 的工具来说,11613 颗星说明这个痛点足够普遍。如果你本地常年开着三五个 dev server,值得装一个试试。