使用VSCode通过SSH远程开发解决Node.js版本问题

发表时间: 2023-12-08 09:06

vscode 通过官方提供的 Remote-ssh 插件,让我们可以直接通过 ssh 的连接方式,打开服务器上的代码库,远程进行开发。

我相信,“高端” vscode 玩家一定尝试过该玩法,简直好处多多。

但是用久了,难免会碰到一些问题。

问题

比如,最近我老是会碰到因为 node.js 版本,导致,项目没法直接通过资源管理器中的 NPM SCRIPTS 运行起来的问题。

什么?!有前端童鞋说自己没碰到过?那么该反思下自己,是不是不喜欢用最新版本的 node.js 去构建项目了。

还是说回咱的问题吧。

之前有个项目,由于比较老了,只能用 14.xx 版本的 node.js 才能正常运行,用更高的版本的 node.js 运行,会有一堆依赖报错的问题,导致项目没法正常的跑起来。

但是,如果升级依赖吧,代价又太大。毕竟这种吃力不讨好的事情,职场老鸟都会避而远之,除非老板同意你这么做,否则没做好的话,锅可少不了。

用 vscode 远程连上服务器的项目后,选择 NPM SCRIPTS 列表中的 npm 脚本,没法正常执行,因为此时用的 node.js 版本不对。

但是,如果通过 vscode 的终端进去,如果版本刚好合适,你会发现可以直接调用类似 npm start 这种命令,直接正常运行项目。

如果不对,也不打紧,可以用 nvm 切换 node.js 版本,接下来你会发现系统中默认的 node.js 版本调整好了,通过类似 npm start 这种命令,项目就可以正常运行了。

但是,直接通过 NPM SCRIPTS 命令还是无法运行,个人推测大概是因为这里还是用的老版本的 node.js。

机缘巧合

虽然这个问题不影响开发,通过命令行去跑项目运行,也不太影响使用体验,但是总感觉有点不爽快。

毕竟发现问题,却没法解决,只能通过别的方式来规避,作为一枚富有探索精神的程序员来说,多少心有不甘。

后来也试图找过一些解决方案,换了好多关键词去 google,甚至 ChatGPT 都想方设法地问了好多次,官方 issue 也翻烂了,还是没找到合适的解决方案。

后来有一次,机缘巧合下,主机升级,重启了。

再连上去,发现用 NPM SCRIPTS ,直接就可以正常运行了,遂恍然大悟。

原来,是因为 vscode-server 每次启动运行的时候,会自动获取当前环境中的 node.js 版本,并用这个版本的 node.js 来运行服务,服务没重启当然不能更换其使用的 node.js 版本了。

验证推测

为了验证自己的推测,连到服务器上探究了一番,果不其然,跟我的猜想一致。

原来当你通过 Remote-SSH 插件连上远程的机器的时候,该插件会在远程的机器的用户文件夹下,创建一个隐藏的目录 .vscode-server,然后顺手在该目录中安装下 vscode-server 软件,然后启动一个 vscode-server 服务。本地的 vscode 其实就是不断地和机器上的 vscode-server 在通信,从而支持通过本地的 vscode 进行远程开发。

# 查看运行的进程ps -ef |grep .vscode-serverroot      1253     1  0 15:00 ?        00:00:00 sh /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/bin/code-server --start-server --host=127.0.0.1 --accept-server-license-terms --enable-remote-auto-shutdown --port=0 --telemetry-level all --connection-token-file /root/.vscode-server/.1a5daa3a0231a0fbba4f14db7ec463cf99d7768e.tokenroot      1265  1253  0 15:00 ?        00:00:18 /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/node /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/out/server-main.js --start-server --host=127.0.0.1 --accept-server-license-terms --enable-remote-auto-shutdown --port=0 --telemetry-level all --connection-token-file /root/.vscode-server/.1a5daa3a0231a0fbba4f14db7ec463cf99d7768e.tokenroot      1368  1265  0 15:00 ?        00:00:03 /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/node /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/out/bootstrap-fork --type=ptyHost --logsPath /root/.vscode-server/data/logs/20231204T150019root      7379  1368  0 15:49 pts/4    00:00:00 /bin/bash --init-file /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/out/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.shroot      8272  1265  0 15:53 ?        00:00:06 /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/node --dns-result-order=ipv4first /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/out/bootstrap-fork --type=extensionHost --transformURIs --useHostProxy=falseroot      8283  1265  0 15:53 ?        00:00:00 /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/node /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/out/bootstrap-fork --type=fileWatcherroot      8356  8272  0 15:53 ?        00:00:00 /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/node /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/extensions/json-language-features/server/dist/node/jsonServerMain --node-ipc --clientProcessId=8272root      8601  8374  0 15:53 ?        00:00:00 /root/.vscode-server/code-1a5daa3a0231a0fbba4f14db7ec463cf99d7768e command-shell --cli-data-dir /root/.vscode-server/cli --parent-process-id 8374 --on-port --require-token 420f17f0d59aroot      8753  8272  0 16:15 ?        00:00:01 /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/node --max-old-space-size=3072 /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/extensions/node_modules/typescript/lib/tsserver.js --serverMode partialSemantic --useInferredProjectPerProjectRoot --disableAutomaticTypingAcquisition --cancellationPipeName /tmp/vscode-typescript0/a6e9883aad51f1da31b8/tscancellation-5a954acdf4ef24e6466c.tmp* --locale zh-cn --noGetErrOnBackgroundUpdate --validateDefaultNpmLocation --useNodeIpcroot      8754  8272  1 16:15 ?        00:00:04 /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/node --max-old-space-size=3072 /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/extensions/node_modules/typescript/lib/tsserver.js --useInferredProjectPerProjectRoot --enableTelemetry --cancellationPipeName /tmp/vscode-typescript0/a6e9883aad51f1da31b8/tscancellation-2340bc35bd699f3648c0.tmp* --locale zh-cn --noGetErrOnBackgroundUpdate --validateDefaultNpmLocation --useNodeIpcroot      8770  8754  0 16:15 ?        00:00:00 /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/node /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/extensions/node_modules/typescript/lib/typingsInstaller.js --globalTypingsCacheLocation /root/.cache/typescript/5.2 --enableTelemetry --typesMapLocation /root/.vscode-server/bin/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/extensions/node_modules/typescript/lib/typesMap.json --validateDefaultNpmLocationroot      8797   543  0 16:19 pts/0    00:00:00 grep --color=auto .vscode-server

所以,了解了原理以后,再想解决我们碰到的问题,就很简单了。

我们把服务器上的 vscode-server 服务关掉,重开一下就好了。

不要用 vscode 指令

当然,这里其实还有个坑。

在 vscode 界面,按住 ctrl+p,然后在出现的输入框里键入 > remote-ssh 会自动列出一些可以使用的 remote-ssh 命令。

里面会有 在主机上终止 VS Code 服务器在主机上卸载 VS Code 服务器 等指令。

但是你用了就会发现一个坑,这些命令都有用,但是他在终止、卸载完,就会立马重新装一个新的 VS Code 服务器,根本不给你调整环境中 node.js 版本的时间。

所以我们成功的执行我们的操作,我们得想别的方案来实现。

在主机上手动卸载 vscode-server

我们连接上主机,通过下面的方式,即可成功卸载掉 vscode-server

# 列出所有依赖 .vscode-server 路径的进程ps -ef |grep .vscode-server# 杀掉所有依赖于 .vscode-server 路径的进程ps uxa | grep .vscode-server | awk '{print }' | xargs kill -9# 删除掉 .vscode-server 文件夹rm -rf ~/.vscode-server/

当然卸载掉以后,先别急着重新用我们的 vscode 编辑器连接服务器上的项目。

先用 nvm 切换下系统中默认的 node.js 版本。

# 默认指向对应的想用的 node.js 版本nvm alias default nodeVersin

为了验证我们设置 node.js 版本的操作是否成功,可以试着断开远程的连接,重新登录下。

如果发现没问题,即可重新在本地用 vscode 连接服务器上的项目。

当然,这地方还有个需要注意的点是,不能傻傻的使用 nvm use nodeVersion 就以为将 node.js 默认的版本切换成功了。

这个操作只针对当前 bash,退出去重新进来,就会发现,系统中默认的 node.js 版本又是之前的版本了。

反思

现在,让我们回过头来看,会发现,其实解决问题的思路并不复杂。关键是,我们要了解清楚引起问题的原因是什么。

知其然更要知其所以然,才能在碰到问题的时候,抽丝剥茧,迅速的定位到问题所在。

参考链接

下面是一些参考资料,有兴趣进一步研究的童鞋可以作为参考

  1. Attention Required! | Cloudflare
  2. Attention Required! | Cloudflare
  3. GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions

#记录我的12月#