uploadonsave生效需满足:项目根目录下存在正确命名的.sftp.json文件,其中"uploadonsave": true为布尔值,remotepath为绝对路径且服务器端已存在,保存时状态栏显示sftp: done才表示成功。

保存文件后没上传,大概率是 uploadOnSave 没生效,或 .sftp.json 放错了位置——它必须在项目根目录下,且文件名是 .sftp.json(开头带点),不是 sftp.json 或 .vscode/sftp.json。
如何确认 uploadOnSave 真的在起作用
VSCode 本身不支持自动上传,全靠 vscode-sftp 插件(作者 liximomo)的 uploadOnSave 字段驱动。这个字段只对当前工作区(workspace)根目录下的文件有效,且仅在「保存动作触发」时比对本地与远程时间戳,有变更才传。
-
uploadOnSave必须是布尔值true,不能写成字符串"true"或遗漏引号导致 JSON 解析失败 - 旧版配置里的
autoUpload已废弃,现在只认uploadOnSave;如果同时写了watcher和uploadOnSave,后者优先,前者仅用于监听删除/新建等事件 - 保存后左下角状态栏出现
SFTP: connecting → done xxx才算成功;若一闪而过或卡在 connecting,说明连接失败,不是上传逻辑问题 - 插件不会创建远程目录,
remotePath对应的路径必须已存在,否则静默失败(无报错,但文件没出现)
remotePath 配置错误的典型表现
remotePath 不是“服务器上放哪”,而是“本地项目根目录映射到服务器的哪个绝对路径”。它决定的是相对路径拼接起点,不是 scp 那种目标目录追加。
- 本地路径为
/Users/me/project/src/main.js,remotePath: "/var/www/html"→ 上传后路径是/var/www/html/src/main.js,不是/var/www/html/main.js - 如果想让
src/内容直接落在/var/www/html/下,得把项目根目录设为src,或改用watcher+files显式指定源路径 - Windows 用户注意路径分隔符:JSON 里统一用
/,不要写,否则解析可能出错 -
remotePath末尾不加斜杠,加了也没用,插件内部会处理
私钥登录失败的三个硬坑
用 privateKeyPath 登录时,VSCode 不展开 ~,也不读取 ssh-agent,必须给绝对路径,且权限要严格限制。
-
privateKeyPath值必须是本地文件系统上的绝对路径,例如"/Users/me/.ssh/id_rsa"或"C:\Users\me\.ssh\id_rsa";写"~/.ssh/id_rsa"一定失败 - 私钥文件权限不能太宽松:Linux/macOS 下需
chmod 600 ~/.ssh/id_rsa,否则 ssh2 库拒绝加载 - 如果服务器禁用了密码登录(
PermitRootLogin without-password或PasswordAuthentication no),配置里还留着password字段,插件会先尝试密码并卡住;删掉password字段,只留privateKeyPath - 首次连接可能不弹信任提示,关掉 VSCode 再重开一次,有时能触发底层 ssh2 的 host key 验证流程
忽略文件和 watcher 的实际行为差异
ignore 和 watcher.files 控制的是不同阶段的行为,混淆会导致误同步或漏同步。
-
ignore只影响上传/下载动作:比如写了"node_modules/**",手动执行SFTP: Upload Folder时跳过该目录,但uploadOnSave仍会对node_modules下的单个文件响应(只要它被保存) -
watcher.files是监听范围:设为"src/**/*"就只响应src/下文件的保存、新增、删除;它不控制上传内容,只控制“什么变化能触发上传” -
watcher.autoDelete: true会同步删除远程对应文件,但仅限于watcher.files匹配到的路径内;删了src/a.js,不会连带删dist/a.js - 排除规则用 glob,不支持正则;
"**/*.log"有效,"^.*.log$"无效
最常被忽略的一点:uploadOnSave 不跨工作区,也不递归子目录以外的路径;如果你在多根工作区里打开两个文件夹,只有激活的那个根目录下的 .sftp.json 生效,另一个完全不参与同步。











