设想:实现一个类似postman的接口调试的插件demo,取名:postPlug
准备工作: code.visualstudio.com/api/
官方开发文档 blog.csdn.net/q1056843325… blog.csdn.net/lusing/arti…
初衷:将自己的组件添加到workbench中,在vscode的侧栏中出现出现插件图标,点击图标,打开新的webview页面,编辑器栏显示模拟postman界面,Send 按钮:发送请求,XMLHttpRequest读取文件,接收返回信息
步骤一:写扩展视图,参考官网tree-view 配置package.json,contributes下配置容器
"viewsContainers": {
"activitybar": [
{
"id": "treeView",
"title": "postman模拟",
"icon": "assert/beautifulGirl.svg"
}
]
},
"views": {
"treeView": [
{
"id": "postplug_item",
"name": "模拟1"
},
{
"id": "postplug_item1",
"name": "模拟2"
}
]
}
爬坑指南,配置完后按f5一直不出来侧栏的图标,排查好久,原来是“views“写成了"view"。。。。。
步骤二:写网络视图,调用webview Api
1、webview无法直接访问本地资源,它在一个孤立的上下文中运行,想要加载本地图片,j s,css等必须通过特殊的vscode-resource协议,类似于file协议;
2、默认不支持从文件加载html,需要自己封装:
private static _getWebViewContent(context: vscode.ExtensionContext, templatePath: string) {
const resourcePath = path.join(context.extensionPath, templatePath);
const dirPath = path.dirname(resourcePath);
let html = fs.readFileSync(resourcePath, 'utf-8');
// vscode不支持直接加载本地资源,需要替换成其专有路径格式,这里只是简单的将样式和JS的路径替换
html = html.replace(/(<link.+?href="|<script.+?src="|<img.+?src=")(.+?)"/g, (m: string, $1: string, $2: string) => {
return $1 + vscode.Uri.file(path.resolve(dirPath, $2)).with({ scheme: 'vscode-resource' }).toString() + '"';
});
return html;
}
这种只适用于简单的webview开发,要开发复杂的页面,则需要打包好整个dist拷到vscode插件里的命令行触发函数里面,
步骤三:搭建react+webpack
参考typescript官方文档: www.tslang.cn/docs/handbo…,
爬坑:运行后组件效果没有出来,打开“开发人员工具”,控制台报错,
because the document's frame is sandboxed and the 'allow-script...
找了好久,原来是无法加载js,加上enableScripts: true才解决 exports is not defined:需要安装webpack打包,安装webpack和webpack-cli后,运行webpack报错: Invalid regular expression: /(\p{Uppercase_Letter}+|\p{Lowercase_Letter}|\d)(\p{Uppercase_Letter}+)/... 更换node版本“nvm use 12.18.4”,重新全局install一遍webpack和webpack-cli 每次运行webpack报错,就切换node版本
步骤四:引入antd绘制界面
爬坑指南:
/node_modules/@types/react/index"' can only be default-imported using the 'esModuleInterop'
flag解决办法:在tsconfig.json中加上"allowSyntheticDefaultImports": true 按需加载:新建.babelrc文件,install babel-plugin-import 注意!!在tsconfig.json的module设置成“esnext“ 报错:Cannot use import statement outside a module,而改成”commons" 打包后报错:antd_1 is not defined 这是因为项目分成两部分打包,一个是编译vscode的主进程,一个是编译antd的渲染层编译vscose需要用 commonjs,编译渲染层需要用esnext。解决:新建一个tsconfig.extension.json用于编译ts主进程,将module设置成“commonjs",再修改package.json,watch命令行设置成“tsc -watch -p tsconfig.extension.json“
步骤五:发送请求
刚开始,尝试使用XMLHttpReques和CORS访问http请求: window.XMLHttpRequest对象是当今所有ajax和web2.0应用技术基础 由于同源策略会抛出异常: No 'Access-Control-Allow-Origin' header is present on the requested resource 同域内的XMLHttpReques访问通常只有一次请求,而跨域的XMLHttpReques有两次,第一次XMLHttpReques请求,method是options,并非前文定义的post,这并不是由js代码控制的,而是浏览器来完成的操作,其作用是判断该请求是否能够被服务器所响应;第二次XMLHttpReques请求才是真正的post请求。 所以要解决前端跨域:协议,域名,端口需要一致才算一个站点
1、jsonp:即json with padding,动态添加一个script标签,而script标签的src属性是没有跨域的限制的。“jQuery AJAX"设为datatype:'jsonp',这个$.ajax方法用的则是jsonp协议,jsonp是一个非官方的协议,它允许在服务器端集成script tags返回至客户端,通过javascript callback的形式实现跨域访问
2、nginx
3、CORS:Cross-Origin Resource sharing
试了很多方法都是跨域的问题,直到在掘金上发现一篇文章 juejin.cn/post/684490…
才明白,postman之所以能访问http请求,是因为插件根本不存在跨域问题,跨域问题是存在浏览器中的。
vscode只运行在服务器端或者浏览器端,它是基于node.js和chromium开发的,它通过electron实现跨平台的。vs code是多进程架构;
webview内部不允许发送ajax请求,所有的ajax请求都是跨域的,因为webview本身是没有host的。在extension.ts里axios是可以发送请求并取到数据的。
所以要引出”消息通信“:发现一个叫cs-channel的npm包,用于vscode间的渲染层和插件层的通信
爬坑指南:元素隐式具有 "any" 类型,因为类型为 "any" 的表达式不能用于索引类型 "(input: RequestInfo, init?: RequestInit | undefined) => Promise< Response>"
解决:在tsconfig.json中加上:"suppressImplicitAnyIndexErrors":true,
另外发现叫“got“的npm包,简化了的http请求,比内置的http模块有更好的接口 www.ctolib.com/got.html
步骤六:发布插件
npm install -g vsce,
vsce package,
vsce publish发布,
增量发布:vsce publish patch
爬坑指南:needs the following permission(s) on the resource /post to perform this action: View user permissions on a resource,需要创建publisher : marketplace.visualstudio.com/manage/crea…
vsce package打包 走的是 vscode:prepublish:"npm run compile";
增量发布vsce publish patch 报错:Command failed: npm version patch npm ERR! Git working directory not clean. npm ERR! M package.jso,解决:修改package.json里的version,删掉package-lock.json重新install 并打包发布;
发布后运行报错:cannot find mpdule...:解决:是因为我运行vsce package的时候只执行了compile编译命令,并没有对主进程进行打包,所以无法读取node_modules的包,所以需要修改package.json,新建一个webpack.build.config.js文件,参考 code.visualstudio.com/api/working…
最后,按f5运行项目,再按shift+command+p输入 postplug,运行结果