# 内网实现vscode插件自动更新
# 背景
vscode插件在外网中会自动查询插件市场并更新,但是在内网中,由于连不到插件市场,每次更新都要手动安装插件包,这就容易降低升级意愿。
# 检查版本更新
之前的做法是,在流水线中自动打包生成vsix插件包
然后每次打开vscode插件的时候,拉取FEX-AIGC代码仓库的tag,与本地package.json进行版本比较,如果有更新,则调用vscode.window.showInformationMessage
进行弹窗提示,并附属下载vsix最新包的链接。
缺点就是每次都要手动下载后安装,十分影响使用体验。
# 自动更新
处理方式也很简单
同样判断需要更新时,直接从之前的更新地址将vsix插件包下载下来
下载完成后通过node子进程执行vscode的安装插件命令即可
核心命令就是执行vscode安装目录里的code脚本
xx/bin/code --install-extension path
在安装成功后弹窗提示用户重启vscode
具体代码:
function exec(...args: Parameters<typeof spawn>) {
const [command, spanwArgs = [], options = {}] = args
const { timeout, ...restOpts } = options
return new Promise((resolve, reject) => {
// 需要手动timeout: https://github.com/nodejs/node/issues/43704
const childProcess = spawn(command, spanwArgs, restOpts)
.on('close', resolve)
.on('error', reject)
if (timeout) {
setTimeout(() => {
childProcess.emit('close')
reject(new Error('ETIMEDOUT'))
}, timeout)
}
})
}
async function autoUpdate(latestVersion: string) {
const url = `xxx.vsix`
const savePath = path.resolve(process.cwd(), `fex/vsix/${latestVersion}.vsix`)
const folderPath = path.dirname(savePath)
// 确保文件夹存在
fs.mkdirSync(folderPath, { recursive: true })
const stream = fs.createWriteStream(savePath)
stream.on('finish', async () => {
await exec(`${process.cwd()}${path.sep}bin${path.sep}code`, ['--install-extension', savePath], { stdio: 'ignore', timeout: 3000 })
const buttonLabel = await vscode.window.showInformationMessage(
`插件${name}自动更新完毕, 是否重启该窗口`,
'是',
'否',
)
if (buttonLabel === '是')
vscode.commands.executeCommand('workbench.action.reloadWindow')
})
http.get(url, (res) => {
res.pipe(stream)
})
}
# 总结
通过自动更新,使用者无需再手动安装,也提升了使用FEX-AIGC插件的意愿