一、内容简介

在工作中经常用有一些图片来美化我们的前端页面,这时需要我们先将图片下载到本地再通过tinypng这个网站将图片压缩后上传到七牛云,最后将图片链接放在我们的代码中,虽然工作也都在搬砖,但是这种砖不是我喜欢的那种砖。于是,就想到开发一个Vscode插件来帮我自动压缩上传图片。

效果预览:

现在已经算是一个有完整功能的插件了,感兴趣的小伙伴可以在Vscode中搜索插件upload-to-qiniu进行安装。

二、需求分析

  • 1.可在Vscode的setting中配置上传所需的参数,可以根据个人的需求单独进行配置;
  • 2.在开发过程中可在编辑器中直接选择图片并上传到七牛并将图片链接填写到光标位置;
  • 3.鼠标悬浮在图片链接时可以预览图片

三、从零开发

一个好的文档可以帮助我们更容易的开发:如果英文比较好的同学可以直接看Vscode英文文档,这里api会比较全,可以找到更简洁的方案实现功能; 不过我的话,还是花很久时间找了这篇比较全的中文文档

1. 搭建项目

vscode插件的开发需要现在全局安装脚手架:npm install -g yo generator-code
安装成功后,直接对应命令yo code 来生成一个Vscode插件工程

输入对应的配置后,就可以生成一个项目了[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sJjinZ9H-1607143985426)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/811da70c2dd941a280970f500922d5e6~tplv-k3u1fbpfcp-watermark.image)]

2. 启动项目调试

安装好依赖进入项目后,按f5会打开一个新的Vscode编辑器,在命令行面板(Ctrl+Shift+P / Shift+command+P)输入Hello World,如果编辑器右下角弹出弹窗

则说明工程可以正常运行,可以开始我们的需求开发啦;

3. 配置所需参数

在package.json中,可以看到有contributes参数,在这里添加一个configuration来设置插件参数, 如图:

完整configuration配置如下:

"configuration": [{"title": "图片上传工具配置","properties": {"upload_image.domain": {"type": "string","default": "","description": "设置上传域名"},"upload_image.accessKey": {"type": "string","default": "","description": "设置七牛上传accessKey"},"upload_image.secretKey": {"type": "string","default": "","description": "设置七牛上传secretKey"},"upload_image.scope": {"type": "string","default": "","description": "设置七牛上传上传空间"},"upload_image.gzip": {"type": "boolean","default": "true","description": "是否启用图片压缩"}}
}]


点击重新运行后在调试的Vscode编辑器中找到settings,找到Extendsions

可以看到我们配置的配置项已经可以在编辑器中自己设置了:

3. 配置右键菜单

接下来可以实现我们的一个选择图片的交互功能:鼠标点击后右键可以弹出一个菜单选择图片后,拿到图片和我们之前配置的一些参数;

1. 在package.json定义命令和事件:

"activationEvents": ["*"],"main": "./out/extension.js","contributes": {"commands": [{"command": "extension.choosedImage","title": "选择图片"}],"menus": {"editor/context": [{"when": "editorFocus","command": "extension.choosedImage","group": "navigation"}]},

我的理解是:activationEvents为需要注册的事件;commands定义事件名和标题;menus定义事件执行的时机和命令显示的位置。

2. 在extension.js中编辑事件:

import * as vscode from 'vscode'export function activate(context: vscode.ExtensionContext) {let texteditor = vscode.commands.registerTextEditorCommand('extension.choosedImage',async (textEditor, edit, args) => {// 获取七牛参数const qiniuConfig = vscode.workspace.getConfiguration('upload_qiniu_config')const uri = await vscode.window.showOpenDialog({canSelectFolders: false,canSelectMany: false,filters: {images: ['png', 'jpg'],},})}console.log(qiniuConfig, uri))context.subscriptions.push(texteditor)
}

通过getConfiguration获取在编辑器中配置的内容;showOpenDialog来调出文件选择框:

这里有一个需要注意的点就是在使用getConfiguration获取配置参数时,传的名字应该与package.json中的configuration中设置的key值相同。

3. 完成图片上传七牛云功能:

这里使用nodeqiniu.jsnpm install qiniu安装依赖后,实现一个简单的上传功能就好:
新建一个util文件夹,单独写一下上传逻辑

util/upload.tsconst qiniu = require('qiniu')const getToken = (accessKey: string, secretKey: string, scope: string) => {const options = {scope,}const mac = new qiniu.auth.digest.Mac(accessKey, secretKey)const putPolicy = new qiniu.rs.PutPolicy(options)const uploadToken = putPolicy.uploadToken(mac)return uploadToken
}// 七牛上传配置
export interface QiNiuUpConfig {domain: string // 上传后域名accessKey: string // 七牛参数secretKey: string // 七牛参数scope: string // 七牛上传空间gzip: boolean // 是否需要压缩
}export const upImageToQiniu = (loaclFile: string,cb: { (res: any): void; (arg0: any): void },upConfig: QiNiuUpConfig
) => {const config = new qiniu.conf.Config()// config.zone = qiniu.zone.Zone_z2const formUploader = new qiniu.form_up.FormUploader(config)const putExtra = new qiniu.form_up.PutExtra()const token = getToken(upConfig.accessKey, upConfig.secretKey, upConfig.scope)// 获取当前时间戳var key = new Date().getTime()formUploader.putFile(token, key, loaclFile, putExtra, function (respErr: any,respBody: any,respInfo: any) {const url = upConfig.domain + '/' + respInfo.data.keycb(url)})
}

4. 将图片链接写人编辑器中:

通过上面的方法已经可以获得图片上传后的链接,接下来就是将链接写入编辑器中:
首先判断编辑器选择位置,editor.selection中可以获得光标位置、光标选择首尾位置。若光标有选中内容则editBuilder.replace替换选中内容,否则editBuilder.insert在光标位置插入图片链接:

// 将图片链接写入编辑器
function addImageUrlToEditor(url: string) {let editor = vscode.window.activeTextEditorif (!editor) {return}const { start, end, active } = editor.selectionif (start.line === end.line && start.character === end.character) {// 在光标位置插入内容const activePosition = activeeditor.edit((editBuilder) => {editBuilder.insert(activePosition, url)})} else {// 替换内容const selection = editor.selectioneditor.edit((editBuilder) => {editBuilder.replace(selection, url)})}
}

这时一个完整的上传图片到七牛并将返回链接写入编辑器功能完全实现:

let texteditor = vscode.commands.registerTextEditorCommand('extension.choosedImage',async (textEditor, edit, args) => {const qiniuConfig = vscode.workspace.getConfiguration('upload_qiniu_config')const uri = await vscode.window.showOpenDialog({canSelectFolders: false,canSelectMany: false,filters: {images: ['png', 'jpg'],},})if (!uri) {return}const upConfig = {accessKey: qiniuConfig.accessKey,secretKey: qiniuConfig.secretKey,domain: qiniuConfig.domain,gzip: qiniuConfig.gzip,scope: qiniuConfig.scope,}// 图片本地路径const loaclFile = uri[0].pathupImageToQiniu(loaclFile,(res: string) => {let url = res// 将图片链接写入编辑器addImageUrlToEditor(url)},upConfig)}
)

5. 实现鼠标悬浮预览图片:

使用vscode.languages.registerHoverProvider注册一个鼠标悬浮事件,registerHoverProvider内通过provideHover函数返回 new Hover() 来显示内容。

预览图片功能开发思路:

  • 1.Hover对象可支持markdown语法,可使用![](图片链接)来显示一张图片
  • 2.在Vscode插件中不可使用http图片,只能显示https图片,所以可以通过node将图片链接转为base64链接后,使用![](base64链接)来显示
  • 3.在转换base64图片时,需先判断是否为http、https,根据不同类型使用node对应的http、https模块来进行转换
  • 4.通过http(https).get请求图片后,可根据content-type来判断当前链接是否为图片
  • 5.当图片过大时,生成的base64链接可能很长导致图片显示失败,所以在转base64时,可以将图片添加七牛裁剪参数后进行转换

平时在使用Vscode开发时,鼠标hover在链接会有单独的提示可以打开链接,但是在文档中并没有找到对应的api,所以我只能获取到对应行的文本和鼠标悬浮位置,通过正则来匹配当前hover位置是否有链接,所以我们先在实现了一个获取当前文本中所有链接及对应位置的方法:

util/handleHover.ts// 获取http链接 在字符串中的位置
const getHttpLinkPosition = (content: string): Array<any> => {const regx = /['"][http(s)://](\S*)['"]/gconst arr = []let str = contentlet textStart = 0while (str) {let httpIndex = str.indexOf('http')if (httpIndex === 1) {// 'http || "httplet resREGX = str.match(regx)if (resREGX) {arr.push({start: textStart,end: textStart + resREGX[0].length,value: resREGX[0],length: resREGX[0].length,})str = str.substring(resREGX[0].length)textStart += resREGX[0].length}} else if (httpIndex > -1) {str = str.substring(httpIndex - 1)textStart += httpIndex - 1} else {str = str.substring(str.length)}}return arr
}

这个正则可能并不是最好的方案,只是匹配了'|" + http(s)开头到'|"结尾的位置为链接地址,同时将链接所在文本的位置及链接长度(start、end、length)一起返回。
有了这个获取链接位置的方法后,再加一个获取hover位置对应链接的方法:

util/handleHover.ts// 将链接左右两边的引号删掉
const filterHttpLink = (link: string): string => {if (link) {link = link.substr(0, link.length - 1)link = link.substr(1)}return link
}// 获取hover的 http链接
export const getHoverHttpLink = (content: string, position: number): string => {let link = ''const httpPositions = getHttpLinkPosition(content)if (httpPositions.length) {httpPositions.forEach((item) => {if (item.start <= position && item.end >= position) {link = item.value}})}// 如果有链接,去除链接两边的引号后返回return filterHttpLink(link)
}

有了这些方法后,我们只要在extension.ts中注册一个registerHoverProvider事件,在使用![](图片链接)来显示图片,开发过程中在这里有几个坑需要注意:
1.只能显示https的链接,所以我们需要添加一个方法,将网络链接转为base64链接
2.当图片过大时base64链接可能过长显示不出来,所以是通过七牛添加裁剪参数后,再转为base64:

util/handleHover.tsimport * as https from 'https'
import * as http from 'http'// 图片添加裁剪参数
export const addImageCropParam = (url: string,width?: number,height?: number,type?: number
): string => {// 如果url中已经带有裁剪参数,先去掉之前的参数const [path] = url.split('?imageView2')url = pathlet cropUrl = type ? `?imageView2/${type}` : '?imageView2/2'if (!!width) {cropUrl += `/w/${width}`}if (!!height) {cropUrl += `/h/${height}`}if (!!width || !!height) {url += cropUrl}return url
}// 将图片链接转为base64
export const translateImageUrlToBase64 = (url: string): Promise<string> => {return new Promise((resolve, reject) => {let resUrl = ''// 链接是否为httpsconst isHttps = url.includes('https')if (!url) {resolve(resUrl)} else {url = addImageCropParam(url, 100);(isHttps ? https : http).get(url, {}, function (res: http.IncomingMessage) {const contentType = res.headers['content-type']// 请求为图片if (contentType && contentType.includes('image')) {// url = addImageCropParam(url, 100)var chunks: Array<any> = [] //用于保存网络请求不断加载传输的缓冲数据var size = 0 //保存缓冲数据的总长度res.on('data', function (chunk: any) {chunks.push(chunk)//累加缓冲数据的长度size += chunk.length})res.on('end', function (err: any) {//Buffer.concat将chunks数组中的缓冲数据拼接起来,返回一个新的Buffer对象赋值给datavar data = Buffer.concat(chunks, size)//将Buffer对象转换为字符串并以base64编码格式显示const base64Img = data.toString('base64')resolve(`data:image/png;base64,${base64Img}`)})} else {resolve(resUrl)}})}})
}

现在我们需要做图片预览的辅助函数已经都有了,就是需要添加registerHoverProvider里的逻辑,这部分逻辑就非常简单了:

extension.ts// 鼠标悬浮预览图片
vscode.languages.registerHoverProvider('*', {async provideHover(document, position) {const { character } = position// 当前行的文本内容const currentLineText = document.lineAt(position).text// 匹配当前行内链接const httpLink = getHoverHttpLink(currentLineText, character)var strToBase64 = await translateImageUrlToBase64(httpLink)const markString = strToBase64 ? new vscode.MarkdownString(`![](${strToBase64})`, true) : ''return {contents: [markString],}},
})

写到这里,我们的完整功能已经实现,看下效果:

四、发布插件

功能开发完成后可以将我们的插件发布到Vscode上,别的小伙伴就可以安装你开发的插件愉快的开发啦~~。

1.创建账号

首先我们进入文档中提到的组织主页,完成验证登录后创建一个组织。进入主页后,
点击Personal access tokens安装文档中的创建一个新的token(此处为中文文档,英文的看不懂,有看得懂的小伙伴可以评论告诉我后再进行补充)。

2.创建发行放

这里文档中已经介绍的很清楚,如果命名行创建不成功也可以使用提示的地址进行注册。

3.插件发布

这里我并没有在终端登录成功,而是在本地vsce package打包后生成.vsix文件,在管理页中添加插件,然后将生成的.vsix文件上传就显示上传成功啦:
在Vscode中搜索插件upload-to-qiniu也可以搜到对应插件:

测试一下安装的新插件

开心

从零开发Vscode上传图片插件相关推荐

  1. 前端开发VScode常用插件

    名称 功能 Auto Close Tag 自动闭合HTML标签 Auto Import Typescript 自动import提示 Auto Rename Tag 修改HTML标签时,自动修改匹配的标 ...

  2. HeyUI组件库发布vscode插件,PS教程: 如何开发vscode插件?

    前沿 HeyUI组件库,我们项目组已经用了一年多了. 一直没有对应的组件库插件,我一直耿耿于怀. 所以,抽时间查阅了vscode的插件开发教程,终于把vscode的插件完成了. 在此奉上我们的插件库链 ...

  3. 前端开发Vscode插件

    前端开发vscode必备插件: 1.vscode代码换肤: 名称:One Dark Pro 展示: 用法: 进入插件页面后点击设置颜色主题进行切换 2.项目代码量统计工具: 名称:VS Code Co ...

  4. flutter开发vscode插件推荐(开发必备)

    这里是坚果前端小课堂,大家喜欢的话,可以关注我的公众号"坚果前端,",或者加我好友,获取更多精彩内容 vscode开发插件推荐 扩展是完成工作的快捷方式.许多扩展有助于减少重复性工 ...

  5. [VsCode] 开发所使用的VsCode的插件

    vscode 的插件 必须 Chinese (Simplified) Language Pack for Visual Studio Code Markdown Preview Enhanced De ...

  6. VSCode 开发Vue必备插件

    工欲善其事,必先利其器 以下就是开发Vue必备插件: Vetur -- 语法高亮.智能感知.Emmet等 包含格式化功能, Alt+Shift+F (格式化全文),Ctrl+K Ctrl+F(格式化选 ...

  7. vscode 开发vue必备插件_vsCode开发vue项目必备插件

    VSCode 开发Vue必备插件 对于很多使用vscode编写vue项目的新手同学来说,可能不知道使用什么插件,这里简单说一下我常用的几款插件. 1. vetur 实现在 vue 文件中: 语法错误检 ...

  8. oir 用image j打开的插件_Windows 上使用 VSCode Remote 插件进行远程开发

    直到 VSCode remote-ssh 插件出来和我买了一台 NUC 机器之前,我一直在维护两套开发环境,一套防在公司的 CentOS 虚拟机上,另一套则是家里的 Windows 机器.因为代码同步 ...

  9. VSCode拓展插件推荐(HTML、Node、Vue、React开发均适用)

    VSCode拓展插件推荐(HTML.Node.Vue.React开发均适用) 相似功能的插件,不推荐全都装上,请挑选一个使用 本列表所有插件都经过本人测试,且认为相对好用,但是不代表不存在任何问题,大 ...

最新文章

  1. 8086实时时钟实验(一)——《x86汇编语言:从实模式到保护模式》05
  2. 使用phpmaill发送邮件的例子
  3. vv7无法启动显示发动机故障_点火系统故障引起发动机不能启动的排除方法
  4. GridView position = 0重复加载的问题
  5. Makefile:Makefile 使用总结
  6. stm32移植paho_如何在STM32上移植Linux?超详细的实操经验分享
  7. 算法工程师的能力素质模型
  8. java练手代码大全手机版_Java版打字练习游戏源码
  9. 计算机软件高级职称有啥用,计算机软考高级职称有什么用
  10. 【VS问题已解决】警告被视为错误 - 没有生成“object”文件
  11. 十门峡旅游攻略:临安十门峡的春天
  12. 《转贴》机器学习 机器视觉 图像处理 牛人牛站
  13. 通过后台数据在百度地图标记多个点
  14. 几个常用的免费高清无版权图片网站
  15. 虚拟机打电话发短信方法
  16. 用php把图片合成视频,图片音乐合成视频 多张图片合成视频|图片合成视频软件...
  17. 二维数组中的查找--元素从左到右递增,从上到下递增
  18. Debian10开启路由转发以及配置dhcp中继
  19. pgsql——查询常用
  20. 短信验证码登录需求的坑点整理

热门文章

  1. ucos OS_ENTER_CRITICAL
  2. 惊!最靠谱的谷歌与edge浏览器安装扩展插件方法
  3. Python爬虫之网页采集器
  4. 面试直通卡大放送,微软面试官带你揭秘面试潜规则!
  5. 第三次入手卡版掉毛飞翼
  6. 企业微信 php回调模式,老师,我的是微信企业号,开启回调模式一直不行,总提示 请求该url失败...
  7. 计算机软件基础第二版p,《计算机软件基础(二)》
  8. 抽屉实现评论数据结构及评论内容显示示例
  9. 响应式网页设计_响应式网页设计:我们从这里去哪里?
  10. 没文化真可怕(一些互联网职位)