热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

VsCode之使用WebView通信详解

这篇文章主要介绍了VsCode之使用WebView通信详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

之前我在这篇文章VsCode插件开发之插件初步通信

通过插件完成通信,这回我还是通过插件,只不过方式主要以在ts文件里面使用webview来进行通信。

另外在此声明,一定要好好看仔细看官方文档,国内关于VsCode相关的开发,少之又少,虽然有一个叫小茗同学写的相对较全面,但是大家可以仔细看,其实他的内容大多也来自官方,同时有部分也加上自己的理解和想法。个人建议,关于VsCode插件相关的,最好是跑一跑VsCode相关官方例子,这样有助于对VsCode插件开发有一个大致的思路和全局认识,换言之有一个感性的认识。

官方文档地址:https://code.visualstudio.com/api

官方插件例子:https://github.com/Microsoft/vscode-extension-samples

引用官方的说明:

webview API允许扩展在Visual Studio Code中创建完全可自定义的视图。例如,内置的Markdown扩展程序使用Web视图来呈现Markdown预览。Web视图还可用于构建复杂的用户界面,超出VsCode的本机API支持。

将webview视为iframe扩展程序控制的Vs代码内部。webview几乎可以呈现此框架中的任何HTML内容,并使用消息传递与扩展进行通信。这种自由使得webview非常强大,并开辟了一系列全新的扩展可能性。

官方对于是否应该使用webview需要考虑这么几个方面?

第一,这个功能真的需要存在于VsCode中吗?作为单独的APP或者网站是否会更好?

第二,webview是实现功能的唯一方法吗?可以使用常规 Vs Code API吗?

第三,webview会增加足够的用户价值来证明其高资源成本吗?

在我看来,如果是在VsCode内部进行增加webview,可能导致某种混乱或者不利的影响,还不如直接通过插件开发来进行分离完成功能,这样既解耦又对VsCode本身影响不会太大。

官方的Demo:https://github.com/Microsoft/vscode-extension-samples/blob/master/webview-sample

官方讲解:https://code.visualstudio.com/api/extension-guides/webview

上面我说过跑官方的例子有助于更好的认识,同时对于学习信心的提升也有很大的帮助,同时你可以在此基础上改,从而让你对其认识更加深刻。

项目结构(以项目结构中的组成来讲解)

目录的作用分别如下:

.vscode 运行所必须,同时也包括一些用户区和工作区设置(注意,用户区设置优于工作区设置)

node_modules node.js的依赖库

out 编译输出目录(ts编译成功会输出对应的js)

src 源文件所在目录(主要是ts文件,当然了也可能是ts,就看你插件开发时,选择的是js还是ts)

.gitignore git提交时排除一些无关紧要的(java maven项目对于一些target文件中.class是没必要提交到git仓库的)

.vscodeignore

如图所示:

我觉得它的作用和.gitignore是一样的,之所以存在它,是因为要防止.gitignore不生效的缘故吧(以之前项目开发经历来说,有的时候确实存在.gitignore无效问题)。

当然了,这些源于我个人的看法,github上有关于这个的讨论,感兴趣的可以参考:https://github.com/Microsoft/vscode-vsce/issues/12

有不少外国开发者们在这里提自己的看法。

package-lock.json 通过这个是执行npm install 产生的 package-lock.json顾名思义,主要的作用是锁定安装依赖的版本,保持版本一致性。

package.json 从node.js的角度来说它是一个模块描述文件(包含安装模块所需的依赖声明及其版本号、作者名、描述等。

以小茗同学的package.json来讲解,这个文件里面的内容作用分别为如下(大家可以做一个参考,实际情况根据需求而定):

{
  // 插件的名字,应全部小写,不能有空格
  "name": "vscode-plugin-demo",
  // 插件的友好显示名称,用于显示在应用市场,支持中文
  "displayName": "VSCode插件demo",
  // 描述
  "description": "VSCode插件demo集锦",
  // 关键字,用于应用市场搜索
  "keywords": ["vscode", "plugin", "demo"],
  // 版本号
  "version": "1.0.0",
  // 发布者,如果要发布到应用市场的话,这个名字必须与发布者一致
  "publisher": "sxei",
  // 表示插件最低支持的vscode版本
  "engines": {
    "vscode": "^1.27.0"
  },
  // 插件应用市场分类,可选值: [Programming Languages, Snippets, Linters, Themes, Debuggers, Formatters, Keymaps, SCM Providers, Other, Extension Packs, Language Packs]
  "categories": [
    "Other"
  ],
  // 插件图标,至少128x128像素
  "icon": "images/icon.png",
  // 扩展的激活事件数组,可以被哪些事件激活扩展,后文有详细介绍
  "activationEvents": [
    "onCommand:extension.sayHello"
  ],
  // 插件的主入口
  "main": "./src/extension",
  // 贡献点,整个插件最重要最多的配置项
  "contributes": {
    // 插件配置项
    "configuration": {
      "type": "object",
      // 配置项标题,会显示在vscode的设置页
      "title": "vscode-plugin-demo",
      "properties": {
        // 这里我随便写了2个设置,配置你的昵称
        "vscodePluginDemo.yourName": {
          "type": "string",
          "default": "guest",
          "description": "你的名字"
        },
        // 是否在启动时显示提示
        "vscodePluginDemo.showTip": {
          "type": "boolean",
          "default": true,
          "description": "是否在每次启动时显示欢迎提示!"
        }
      }
    },
    // 命令
    "commands": [
      {
        "command": "extension.sayHello",
        "title": "Hello World"
      }
    ],
    // 快捷键绑定
    "keybindings": [
      {
        "command": "extension.sayHello",
        "key": "ctrl+f10",
        "mac": "cmd+f10",
        "when": "editorTextFocus"
      }
    ],
    // 菜单
    "menus": {
      // 编辑器右键菜单
      "editor/context": [
        {
          // 表示只有编辑器具有焦点时才会在菜单中出现
          "when": "editorFocus",
          "command": "extension.sayHello",
          // navigation是一个永远置顶的分组,后面的@6是人工进行组内排序
          "group": "navigation@6"
        },
        {
          "when": "editorFocus",
          "command": "extension.demo.getCurrentFilePath",
          "group": "navigation@5"
        },
        {
          // 只有编辑器具有焦点,并且打开的是JS文件才会出现
          "when": "editorFocus && resourceLangId == Javascript",
          "command": "extension.demo.testMenuShow",
          "group": "z_commands"
        },
        {
          "command": "extension.demo.openWebview",
          "group": "navigation"
        }
      ],
      // 编辑器右上角图标,不配置图片就显示文字
      "editor/title": [
        {
          "when": "editorFocus && resourceLangId == Javascript",
          "command": "extension.demo.testMenuShow",
          "group": "navigation"
        }
      ],
      // 编辑器标题右键菜单
      "editor/title/context": [
        {
          "when": "resourceLangId == Javascript",
          "command": "extension.demo.testMenuShow",
          "group": "navigation"
        }
      ],
      // 资源管理器右键菜单
      "explorer/context": [
        {
          "command": "extension.demo.getCurrentFilePath",
          "group": "navigation"
        },
        {
          "command": "extension.demo.openWebview",
          "group": "navigation"
        }
      ]
    },
    // 代码片段
    "snippets": [
      {
        "language": "Javascript",
        "path": "./snippets/Javascript.json"
      },
      {
        "language": "html",
        "path": "./snippets/html.json"
      }
    ],
    // 自定义新的activitybar图标,也就是左侧侧边栏大的图标
    "viewsContainers": {
      "activitybar": [
        {
          "id": "beautifulGirl",
          "title": "美女",
          "icon": "images/beautifulGirl.svg"
        }
      ]
    },
    // 自定义侧边栏内view的实现
    "views": {
      // 和 viewsContainers 的id对应
      "beautifulGirl": [
        {
          "id": "beautifulGirl1",
          "name": "国内美女"
        },
        {
          "id": "beautifulGirl2",
          "name": "国外美女"
        },
        {
          "id": "beautifulGirl3",
          "name": "人妖"
        }
      ]
    },
    // 图标主题
    "iconThemes": [
      {
        "id": "testIconTheme",
        "label": "测试图标主题",
        "path": "./theme/icon-theme.json"
      }
    ]
  },
  // 同 npm scripts
  "scripts": {
    "postinstall": "node ./node_modules/vscode/bin/install",
    "test": "node ./node_modules/vscode/bin/test"
  },
  // 开发依赖
  "devDependencies": {
    "typescript": "^2.6.1",
    "vscode": "^1.1.6",
    "eslint": "^4.11.0",
    "@types/node": "^7.0.43",
    "@types/mocha": "^2.2.42"
  },
  // 后面这几个应该不用介绍了
  "license": "SEE LICENSE IN LICENSE.txt",
  "bugs": {
    "url": "https://github.com/sxei/vscode-plugin-demo/issues"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/sxei/vscode-plugin-demo"
  },
  // 主页
  "homepage": "https://github.com/sxei/vscode-plugin-demo/blob/master/README.md"
}

目前我改写的官方demo的package.json文件为如下:

{
  "name": "helloworld",
  "displayName": "HelloWorld",
  "description": "",
  "version": "0.0.1",
  "engines": {
    "vscode": "^1.30.0"
  },
  "categories": [
    "Other"
  ],
  "activationEvents": [
    "onCommand:extension.helloWorld",
    "onCommand:extension.loginValidate"
  ],
  "main": "./out/loginValidate",
  "contributes": {
    "commands": [
      {
        "command": "extension.helloWorld",
        "title": "登录"
      },
      {
        "command": "extension.loginValidate",
        "title": "登录验证"
      }
    ]
  },
  "scripts": {
    "vscode:prepublish": "npm run compile",
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./",
    "postinstall": "node ./node_modules/vscode/bin/install",
    "test": "npm run compile && node ./node_modules/vscode/bin/test"
  },
  "devDependencies": {
    "typescript": "^3.1.4",
    "vscode": "^1.1.25",
    "tslint": "^5.8.0",
    "@types/node": "^8.10.25",
    "@types/mocha": "^2.2.42"
  }
}

两者对比,后者更简单。

注意:其中我主要改写官方的这一部分

"activationEvents": [
    "onCommand:extension.helloWorld",
    "onCommand:extension.loginValidate"
  ],
  "main": "./out/loginValidate",
  "contributes": {
    "commands": [
      {
        "command": "extension.helloWorld",
        "title": "登录"
      },
      {
        "command": "extension.loginValidate",
        "title": "登录验证"
      }
    ]
  },

这一部分分别对应extension.ts和loginValidate.ts,如下图所示:

大家可以看到,其实两者区别并不大,主要的差异还是registerCommand括号里面的。

有朋友也行会疑惑这个是什么意思不太明白。

registerCommand主要是注册命令,这个注册命令与图中的一致:

保持一致的话,就能F5运行插件项目打开一个新的窗口(可理解为是插件),通过快捷键ctrl+shift+p就可以看到如图:

点击这个登录验证回车,即可出现如下webview视图

对了还有一点要强调一下,目前有个小局限性就是不能命令有一定的限制,主要是因为这个地方:

由于指定该主函数,所以只能对应的loginValidate.js起作用,所以extension.js就不能起作用了,如果你要强行点击登录就会出现命令找不到,如图所示:

tsconfig.json(关于它的详解,可以参考这篇文章:https://www.jb51.net/article/161435.htm)

虽然有详解不过我还是要说一下,如果一个目录下存在一个tsconfig.json文件,那么它意味着这个目录是TypeScript项目的根目录。tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项。

tslint.json 主要用于typescript的语法检查

最后贴一下我的loginValidate.ts代码(extension.ts代码就不贴了,前面说到过它们的区别,基本上是大同小异):

loginValidate.ts

// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {

  // Use the console to output diagnostic information (console.log) and errors (console.error)
  // This line of code will only be executed once when your extension is activated
    console.log('Congratulations, your extension "loginValidate" is now active!');

  // The command has been defined in the package.json file
  // Now provide the implementation of the command with registerCommand
  // The commandId parameter must match the command field in package.json
  let disposable = vscode.commands.registerCommand('extension.loginValidate', () => {
    // The code you place here will be executed every time your command is executed

    // Display a message box to the user
    const panel = vscode.window.createWebviewPanel(
      'catCoding',
      'Login Validate',
      vscode.ViewColumn.One,
      {
        // Enable scripts in the webview
        enableScripts: true
      }
    );

    panel.webview.html = getWebviewContent();
  });

  context.subscriptions.push(disposable);
}

// this method is called when your extension is deactivated
export function deactivate() {}
function getWebviewContent() {
  return `


  
  
  


用户名:

密  码  :

            

`; }

另外关于通信方面的,目前可以在此使用原生Javascript的ajax,这个webview相当于html,那么就可以在里面引用其它的前端组件来借此实现某个功能,但是请注意,可能会有一定的限制,比如不能使用alert这种弹框方式。

另外建议编写webview的时候,特别是编写里面的html,最好在外面编写,直接使用浏览器运行没有问题,然后再嵌入进去,这样有助于排除一些不必要的错误,利于效率的提高。

今天写到这吧,后面笔者会分享有关于vscode二次开发更多的知识。本次分享出来,希望能够给小伙伴们带来帮助。也希望大家多多支持。


推荐阅读
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • RN即ReactNative基于React框架针对移动端的跨平台框架,在学习RN前建议最好熟悉下html,css,js,当然如果比较急,那就直接上手吧,毕竟用学习前面基础的时间,R ... [详细]
  • 这么多流媒体服务器?你怎么技术选型?
    在上一篇文章里我们介绍了我们介绍了MCU和SFU的优缺点,webRTC通信方案SFU和MCU的区别?下面就来探讨下常见的SFU开源解决方案,当然,你也可以自己实现SFU流媒体服务器 ... [详细]
  • 安卓端开源移动浏览器开源项目
    进入android开发以来,webview用的比较多,后来又看了一些基于webview的浏览器代码,慢慢的将积累的东西做成了一个安卓移动浏 ... [详细]
  • Itwasworkingcorrectly,butyesterdayitstartedgiving401.IhavetriedwithGooglecontactsAPI ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • linux qt打开常用文件格式,设置Linux Qt文件默认打开方式为QtCreator
    Linux自定义文件打开方式也可参照文本抱歉,本文前段时间写的ubuntu下的Qt工程文件默认打开方式是不好用的,因为其他的文本文件也会受到影响,强迫症患者,每次打开Qt工程都是先 ... [详细]
  • React项目搭建流程
    1.先要有node.js环境,略~(https:www.cnblogs.comjyughynjp11207114.html)2.安装react脚手架,create-react-app3.创建项目cmd输入create-react-app project-name,如:1create-react-app02-react-app-demo如果发现有如下 ... [详细]
  • html css在线便宜,在线HTML、CSS和JS工具汇总
    本文提供了在线HTML、CSS和JS工具汇总,它们都是直接在浏览器上可以使用的在线工具,基本上都是比较简单操作的,只适合简单的调试工作&# ... [详细]
author-avatar
留心6_136
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有