基于远程开发的大型前端项目实践
前言
从去年入职新公司之后,我主要在做的一个前端项目,仅源码体积就接近 1G。说实话,刚接触的时候我也觉得很离谱:一个前端项目为什么能做到这么大?更离谱的是,打包产物能膨胀到 5G。至于它为什么会这样、有没有优化空间,这些并不在本文讨论范围内,也不是我当下能决定的事情。
在这样的体量下,每次切换分支、拉取代码,VS Code 都非常容易卡死。在每次 Git checkout / pull 过程中,编辑器直接无响应,需要等上好一会儿才能恢复。后来意识到这并不是 Git 本身慢,而是 VS Code 在分支切换后会触发一系列行为:
- 文件系统 watcher 数量暴增
- TypeScript / ESLint / Language Server 重新索引
- 插件对
node_modules、构建产物的扫描
这些叠加在一起,在超大仓库里很容易直接把编辑器拖死。
我后来采取的一个笨办法是:拉代码、切分支前先关 VS Code,只用 terminal 操作 Git、运行服务。这样切分支几乎是秒级的,等操作完成后再重新打开编辑器,基本可以避免卡死。这种方式确实有效,但显然只是绕开问题,而不是解决问题。
随着时间推移,另一个问题开始频繁出现:VS Code 和 VS Code Plugin Helper 的内存占用会在长时间运行后持续上涨。不过因为我每次拉代码都会顺手重启编辑器,这个问题倒也还能忍。
真正的转折点,是 CSR 项目全面迁移到 SSR(Next.js)之后。Next.js dev server 带来的内存压力是指数级上升的。哪怕是 16G 内存的 M4 MacBook Pro,也很难支撑。一个 Next.js dev 常驻 8~10G 内存,再加上 VS Code、Chrome,本地如果再起几个 Docker 服务、Go 后端、Redis。基本就是风扇起飞,系统开始频繁内存压缩,开发体验直线下降。更恶心的是,Next 项目冷启动和首次编译非常慢,我甚至还不太敢频繁重启。
也是在这个阶段,我开始认真思考:是不是应该把“运行态”从本地彻底挪走? 在这个背景下,我尝试并最终切换到了 Zed 作为主力编辑器。Zed 是 Rust 编写的编辑器,本身非常轻量,这一点在超大项目里感知非常明显:切分支不需要关闭编辑器、几乎感受不到内存上涨、长时间运行也非常稳定。
当然,我也很清楚的知道 Zed 只能解决编辑器问题,解决不了 Next.js 本身的资源消耗。当一个 Next 项目本身就能吃掉 10G 内存时,不管你用 VS Code 还是 Zed,本地开发环境迟早都会顶不住。
所以,最终我决定 把项目运行环境放到服务器,本地只保留编辑器。 这篇文章,讲的就是我在这个方向上的一次完整实践。
远程服务器开发
把开发环境迁移到服务器,本质上解决的是一个核心问题:
让高资源消耗的部分(Node / Next / Docker / 后端服务)远离本地机器。
但除了性能问题,这种方式还有一个非常实际的好处。
当你换一台新电脑时:
- 不需要重新安装 Node / pnpm / Docker
- 不需要拉仓库、装依赖、折腾环境变量
- 只要一个支持远程开发的 IDE
直接连上服务器,就可以立刻开始开发。
我这里用的是本地虚拟机作为示例,实际换成云服务器或公司内网服务器,原理完全一致。区别只在于是否需要额外配置端口、防火墙、安全组等。
SSH 基础配置
发送 SSH 公钥
先把本地的 SSH 公钥拷贝到服务器,这样可以避免每次登录输入密码。
1 | |
SSH Config 与 ForwardAgent
编辑本地的 ~/.ssh/config:
1 | |
这里的 ForwardAgent 非常关键,它的作用不是复制密钥到服务器,而是将本地的 ssh-agent 转发到远端,让服务器上的 git / ssh 可以使用你本地已经加载的私钥,这样在服务器上执行 git pull、git fetch 时,就不需要再单独配置一套 SSH Key。
[!NOTE] 注意:
这种方式仅对 SSH 协议的 Git 仓库生效,对 HTTPS 仓库无效,同时在不可信服务器上开启存在安全风险
SSH Agent
ssh-agent 是一个驻留在本地用户会话中的密钥代理进程,用于集中管理私钥并按需为 ssh / git 等客户端完成签名操作,其作用主要是避免私钥频繁被直接读取或反复输入密码。配合 SSH Config 中的 ForwardAgent yes 将本地 agent 的 socket 临时映射到远端会话,从而实现远程会话通过本地私钥进行认证的行为。
启动与加载私钥
将私钥显式加载进 agent,如果私钥本身设置了 passphrase,这一步会要求你输入一次密码。之后在 agent 生命周期内,不再需要重复输入。
1 | |
验证当前 agent 中已加载的密钥:
1 | |
常见输出形式:
1 | |
远程服务器判断是否生效
登录服务器后,首先检查环境变量:
1 | |
正常情况下应当输出一个路径,例如:
1 | |
VS Code 远程开发
VS Code 体系(包括 Cursor、Trae、Windsurf 等)都可以通过 Remote-SSH 实现远程开发。
第一步:安装插件
搜索并安装 Remote - SSH 插件,安装完成后,通常会自动附带以下插件:
- Remote - SSH: Editing Configuration Files
- Remote Explorer
如果没有自动安装,手动补齐即可。

第二步:唤起 Remote SSH 命令
使用 cmd + shift + p 打开命令面板,输入 Remote-SSH,选择 Connect to Host。

第三步:添加新的 SSH Host
选择 Add New SSH Host。

随后输入:
1 | |
这里的 -A 表示允许本次 SSH 连接使用本地的 ssh-agent,也就是 ForwardAgent。

第四步:选择 SSH 配置文件
选择你本地的 ~/.ssh/config 文件。
如果你之前已经配置过 Host,这一步只是告诉 VS Code 使用哪份配置。

第五步:连接远程主机
在左侧边栏打开 Remote Explorer,左上角选择 Remotes (Tunnels / SSH)。
在列表中找到你刚才配置的 Host,点击连接。

连接成功后,VS Code 会在远端自动安装 server 组件,这一步可能需要几十秒,耐心等待即可。
第六步:打开远程项目目录
连接完成后,点击 Open Folder,选择你在服务器上已经准备好的项目目录。
[!warning] 注意:
这里选择的是服务器上的目录,不是本地目录。

第七步:端口转发
当你在服务器上启动开发服务(例如 Next.js dev server)后:
- 点击 VS Code 底部的端口(信号塔)图标
- 可以看到当前已经转发的端口
- 支持新增、修改协议(HTTP / HTTPS)

此时,你就可以直接在本地浏览器中访问:
1 | |

Zed 远程开发
Zed 的远程开发流程比 VS Code 更轻量一些,但整体思路是一致的。下面同样按实际操作顺序来。
第一步:打开远程连接面板
在菜单栏中选择:
1 | |
如果你已经在 ~/.ssh/config 中配置过 Host,这里可以直接看到。
为了演示完整流程,可以点击上方的 Connect SSH Server。

第二步:输入 SSH 连接命令
输入:
1 | |
这里同样使用 -A,允许 ForwardAgent。

第三步:安装远程环境
第一次连接时,Zed 会在远端安装必要的运行组件。
这个过程需要一点时间,等安装完成后,连接会自动出现在面板中。

第四步:打开远程项目目录
点击 Open Folder,选择你在服务器上已经存在的项目目录。
注意:Zed 不会帮你创建目录,项目需要提前准备好。

第五步:管理远程配置
可以通过以下路径打开配置文件:
1 | |

这里可以看到所有 SSH 连接配置,包括: username、args、projects, 如果你发现有重复的 SSH 配置,可以直接删除多余项。

第六步:配置端口转发
在 Settings 中增加 port_forwards 配置:
1 | |
字段含义:
local_host:本地访问地址local_port:本地访问端口remote_port:服务器上服务监听的端口

配置完成后,只要你在服务器上启动服务,本地即可直接访问。
另一种选择:Windows + WSL
除了云服务器或远程 Linux 主机,Windows + WSL2 其实也是一个非常成熟、且性价比极高的方案。
本质上,你可以把 WSL 当成一台本地 Linux 服务器:
- Node / Docker / Next 全部运行在 WSL 内
- 编辑器运行在 Windows
- 文件系统与 Linux 环境隔离
在大型前端或全栈项目中,这种模式在以下场景尤其合适:
- 公司主要使用 Windows 设备
- 不方便申请云服务器或内网机器
- 希望获得接近原生 Linux 的运行环境
对于资源消耗型项目,WSL 的稳定性和可控性,往往比直接跑在 Windows 本体上要好得多。
结语
Zed 的确让我彻底摆脱了 VS Code 的内存焦虑,这点非常重要,但真正让我回不去的,是把运行环境迁移到服务器之后,那种本地机器重新变得轻快可控的感觉。
当然,远程开发也并不是银弹:网络延迟、SSH Agent Forward 的安全边界、文件 IO 与 HMR 的体验差异等问题,这些都需要根据团队和项目情况权衡。
但至少对我来说,在超大 Next.js 项目下,这是目前最现实、性价比最高的一条路。