portless 详细部署教程

portless 是 Vercel Labs 开发的一款开发工具,它能将本地开发中烦人的端口号(如 localhost:3000)替换为稳定、易记的命名 URL(如 https://myapp.localhost)。它支持自动 HTTPS、HTTP/2、多项目路由,并能与 Git Worktrees、Monorepo 等复杂工作流无缝集成。

本教程将指导您完成从安装到日常使用的全流程。


1. 系统要求与安装

1.1 环境要求

  • Node.js:版本 24 或更高
  • 操作系统:macOS、Linux 或 Windows。
  • 包管理器:npm、pnpm 或 yarn。

1.2 安装 portless

推荐全局安装,以便在任意项目中使用:

1
npm install -g portless

也可以作为项目的开发依赖安装:

1
npm install -D portless

注意:portless 目前是预发布版本(< 1.0)。作为项目依赖时,不同协作者可能使用不同版本,状态目录格式可能变化,可能需要重新运行 portless trust

安装完成后,首次运行时会自动生成本地 CA 证书并提示您将其添加到系统信任库中,请按提示操作(可能需要 sudo 权限)。


2. 基本使用

2.1 为项目分配一个固定 URL

在项目根目录下,运行:

1
portless myapp next dev

这会启动您的 Next.js 开发服务器,并通过 https://myapp.localhost 访问。portless 会自动完成以下工作:

  1. 启动一个后台代理服务(首次运行时)。
  2. 为您的应用分配一个空闲端口(如 4123)。
  3. myapp.localhost 域名路由到该端口。
  4. 启用 HTTPS 和 HTTP/2。

2.2 使用默认的 “dev” 脚本

如果您的 package.json 中有标准的 "dev" 脚本,可以更简洁地运行:

1
portless

它会自动从 package.jsonname 字段或项目目录名推断应用名,URL 为 https://<项目名>.localhost

2.3 在 package.json 中配置

您可以将 portless 集成到项目脚本中:

1
2
3
4
5
{
"scripts": {
"dev": "portless run next dev"
}
}

更好的做法是利用 portless.jsonpackage.json 中的 "portless" 键简化配置:

1
2
3
4
5
6
7
{
"name": "@myorg/web",
"portless": "myapp",
"scripts": {
"dev": "next dev"
}
}

现在只需运行 portless,它就会读取配置,以 myapp 为名启动 next dev


3. 配置与定制

3.1 使用 portless.json 配置文件

在项目根目录创建 portless.json 来覆盖默认设置:

1
2
3
4
{
"name": "myapp",
"script": "dev:app"
}

3.2 子域名与多服务

您可以为不同的服务分配子域名:

1
2
portless api.myapp pnpm start        # -> https://api.myapp.localhost
portless web.myapp next dev # -> https://web.myapp.localhost

3.3 Git Worktrees 自动隔离

portless 能自动识别 Git Worktrees。在功能分支的 worktree 中运行 portless 时,分支名会自动作为子域名前缀,避免冲突:

1
2
3
4
5
# 主 worktree
portless run next dev # -> https://myapp.localhost

# 在名为 "fix-ui" 的分支 worktree 中
portless run next dev # -> https://fix-ui.myapp.localhost

3.4 Monorepo 支持

在 Monorepo 根目录放置 portless.json,可统一管理所有工作区包:

1
2
3
4
5
6
{
"apps": {
"apps/web": { "name": "myapp" },
"apps/api": { "name": "api" }
}
}

在根目录运行 portless 会启动所有工作区的 dev 脚本。进入子包目录运行则只启动该包。

3.5 自定义顶级域名 (TLD)

默认使用 .localhost。如需更换(例如使用 .test),启动代理时指定:

1
2
portless proxy start --tld test
portless myapp next dev # -> https://myapp.test

也可以使用多级域名(如 dev.example.com),这对 OAuth 回调等场景非常有用:

1
2
portless proxy start --tld dev.example.com
portless myapp next dev # -> https://myapp.dev.example.com

4. 高级功能

4.1 开机自启服务

安装为系统服务,让 portless 代理在开机时自动运行:

1
2
3
portless service install
portless service status # 查看状态
portless service uninstall # 卸载服务

安装时可指定参数,如 portless service install --lan --wildcard

4.2 LAN 模式:局域网共享

让同一局域网内的设备(如手机、平板)通过 https://myapp.local 访问您的开发服务器:

1
portless proxy start --lan

此后运行 portless myapp next dev,URL 会变为 https://myapp.local(使用 mDNS 发现)。需要安装 avahi-utils(Linux)等依赖。

4.3 团队协作共享

  • Tailscale 分享:与 Tailscale 网络中的队友分享:

    1
    portless myapp --tailscale next dev

    队友可通过 https://devbox.yourteam.ts.net 访问。

  • Ngrok 公网分享:临时将服务暴露到公网:

    1
    portless myapp --ngrok next dev

4.4 命令行参考

命令 说明
portless 运行默认 dev 脚本
portless <name> <cmd> 以指定名称运行命令
portless run [--name] [cmd] 自动推断名称运行命令
portless alias <name> <port> 手动注册一个静态路由(如用于 Docker)
portless list 查看当前所有活跃路由
portless doctor 检查代理、路由、DNS 和证书状态
portless trust 手动将 CA 证书加入系统信任库
portless clean 清除所有 portless 状态、证书和 hosts 条目
portless proxy start/stop 手动启停代理服务

5. 故障排查与提示

5.1 Safari 无法解析 .localhost 域名

Safari 可能不自动解析 .localhost 子域名。运行以下命令将路由写入 /etc/hosts

1
portless hosts sync

5.2 端口冲突或代理未启动

运行 portless doctor 进行全面的健康检查,它会给出具体的修复建议。

5.3 API 代理到另一个 portless 应用导致循环

如果您的前端服务器(如 Vite)代理 API 请求到另一个 portless 应用(如 api.myapp.localhost),务必在代理配置中设置 changeOrigin: true,否则请求会因 Host 头不正确而被错误路由。

5.4 卸载与重置

如需完全移除 portless 及其所有痕迹,执行:

1
portless clean

这将删除 ~/.portless 目录、系统信任库中的 CA 证书以及 /etc/hosts 中的相关条目。


6. 总结

portless 是一个强大的本地开发环境增强工具,它通过提供稳定的命名 URL自动 HTTPS无缝的多项目管理以及便捷的团队协作功能,极大地提升了开发体验。无论是个人项目还是大型 Monorepo,它都能让您专注于代码,而无需再与端口号和管理证书纠缠。

推荐工作流

  1. 全局安装 portless。
  2. 在项目根目录配置 portless.jsonpackage.json
  3. portless 设为默认的 dev 脚本。
  4. 根据需要,使用 --tailscale--lan 与团队共享。