Published on

如何编写你的第一个vscode插件

Authors
  • avatar
    Name
    ttyS3
    Twitter

准备工作

  1. 安装好最新版本的vscode(这个自动不用说),但是我这里要强调一下的是,vscode插件用vscode自己来写,能省很多事情,虽然你也可以用WebStorm之类的来写

  2. 安装好基本的工具,Git和Node.js(包含我们需要的npm)

  3. 安装YeomanVS Code Extension Generator

    npm install -g yo generator-code
    

Yeoman号称“现代webapps脚手架工具”,使用它可以非常方便地生成各种项目的代码,而不是每个字节都要你从0撸起。 你需要生成的那个项目的“模板”,在Yeoman里被称为“生成器"(generator), 这为是为什么我们安装了Yeoman之后, 还要安装VS Code Extension Generator (就是我们命令行中的generator-code, 这里的code不是代码的意思,则是指vscode) 在Yeoman的官网你可以找到上千个生成器: https://yeoman.io/generators/

第一个vscode插件

代码生成

❯ yo code

     _-----_     ╭──────────────────────────╮
    |       |    │   Welcome to the Visual  │
    |--(o)--|    │   Studio Code Extension  │
   `---------´   │        generator!    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |     
   __'.___.'__   
 ´   `  |° ´ Y ` 

? What type of extension do you want to create? (Use arrow keys)
❯ New Extension (TypeScript) 
  New Extension (JavaScript) 
  New Color Theme 
  New Language Support 
  New Code Snippets 
  New Keymap 
  New Extension Pack 
(Move up and down to reveal more choices)

不得不说这个生成器真是方便和强大。既然我们是要生成扩展,当然是选”New Extension“了,那么这个选项分两种语言可选:TypeScript 和 JavaScript.

虽然老灯更熟悉JavaScript, 但是,这里老灯要选择的是TypeScript,后面会为解释为什么。

然后这个yo还会问你一些问题:

? What's the name of your extension? wudeng
? What's the identifier of your extension? wudeng
? What's the description of your extension? this is a demo extension for fun
? Initialize a git repository? Yes
? Which package manager to use? npm

插件名称,这里由于我们只是创建一个演示插件,起名比较随意,就叫wudeng(无灯)吧。 然后它会问你identifier(标识),默认和名字一样就OK,嗯,直接回车。 identifier一般会用来组成插件在vscode插件市场的URL,也会用于插件安装时的快速安装命令。 因此,一般是使用纯小写英文。 然后description是简短地描述一下,你这个插件是干嘛的。 接着会问你是不是要初始化git仓库,当然是yes. 最后问你是用哪个包管理器,npm 或 yarn, 老灯这里就直接使用npm了(2020年了,npm不再比yarn慢多少了).

yo-code-gen-2020-05-04-18-58-05.png

运行调试

我们直接用vscode打开刚才生成的那个目录(wudeng), 为了方便区, 我们把此时打开的vscode窗口叫做”代码编辑窗口“,然后,神奇的操作来了! 直接按F5,没错,就是F5, vscode会开始自动构建插件代码,然后自动启动了另一个vscode窗口。 这个窗口有点特别,它不是普通的窗口,而是加载了我们当前打开的插件的窗口。

窗口的标题有vscode自动加的前缀 Extension Development Host] - , 为了方便区别,我们把此vscode窗口叫做”扩展开发宿主窗口“。

vscode-dev-host-2020-05-04-19-10-10.png

然后,我们在新开的”扩展开发宿主窗口“中,在命令面板(Ctrl+Shift+P)中输入Hello World命令。

vscode-dev-hello-world-2020-05-04-19-12-12.png

按回车之后,vscode右下角弹出提示信息:

vscode-hello-msg-2020-05-04-19-12-51.png

接下来,我们看下,即使是这么简单的东西,它是如何实现的。

在”代码编辑窗口“,我们双击打开src/extension.ts这个源码文件。 可以看到它注册(registerCommand)了一个标识为wudeng.helloWorld的命令(command), 这个命令的处理函数非常简单,就是一个箭头函数,功能就是显示一条提示信息(showInformationMessage), 信息内容为 Hello World from wudeng!

() => {
    vscode.window.showInformationMessage('Hello World from wudeng!');
}

我们把文字内容修改成 Hello World from 也无荒野也无灯!会如何? 重新在”扩展开发宿主窗口“中执行Hello World命令,发现,执行结果并没有改变。 因为,插件并没有重新加载。我们更新了代码,vscode自动重新编译生成了新的插件代码,但是”扩展开发宿主窗口“ 没有重新加载新生成的代码。 要让插件代码重新加载也很简单,我们切到”代码编辑窗口“,点击顶部的绿色Restart按钮(或者按快捷键Ctrl+Shift+F5)

vscode-dev-toolbar-2020-05-04-19-24-20.png

然后”扩展开发宿主窗口“就会自动重新加载新的插件代码。

vscode-hello-mod-msg-2020-05-04-19-25-43.png

tips:

除了在”代码编辑窗口“,点击顶部的绿色Restart按钮(或者按快捷键Ctrl+Shift+F5), 还可以”扩展开发宿主窗口“中,按Ctrl+Shift+i打开调试控制台,然后把光标定位到调试控制台, 再按F5即可重载插件。

小试牛刀

当然,发个hello world确实显得这个文章没有太多意义了。你这个hello world插件又不能实际工作。 所以,发hello world当然不是老灯的本意了。hello world满大街都能找到。 文章的重点部分,当然是在这后面部分了。

缘由

其实在此之前老灯一直不会写vscode插件。也没有想过要写vscode插件,只到有一天,老灯开始用Hugo写博客,发现某个Hugo插件一直用起来不爽, 于是就想,能不能想办法改一改。我主要用它的New Post功能来创建新的日志markdown文件。 为什么不直接新建markdown文件,然后再写日志?因为Hugo的markdown文件不是普通的markdown文件,它在文件最开始会有一些Front Matter, 而通过Hugofy的New Post,它实际上是调用的hugo new post/xxx/xxx.md来创建新日志,因此会自动生成Front Matter.

hugo-new-front-matter-2020-05-04-19-45.gif

这个New Post操作本身没有问题。 但是它对于“右击某个目录,然后在这个目录下创建日志”这种简单地需求都无法满足。 看上去它的命令行方式的New Post操作是OK,但是,试想一下非常常见的需求: 在Hugo我们习惯用文件夹的方式来组织日志,默认情况下,目录就是分类,假设我有一个linux父分类, 然后其下有Fedora, ArchLinux, Debian等子分类,按照这个Hugofy的命令,我们要输入的文件名为 linux/fedora/日志标题.md,而如果插件有这种支持,我们就可以直接在fedora目录上右击,然后选择新建日志。

因此,我做的第一个修改,就是增加右键菜单的支持。 其次还有一些bug, 比如下载Hugo主题的功能不能正常工作, Hugo有错误这个插件完全没提示是什么错误,然后你会一头雾水不知道怎么解决。 错误提示信息不够友好和准确等等。下面会一一详细说明,并试图操刀解决。

第一刀: 优化新建日志和page bundle支持

我们先来做第一步吧,把源码fork到自己的仓库: https://github.com/ttys3/hugofy-vscode

然后clone到本地,用vscode打开,然后执行F5,发现并没有像预期的那样,打开一个新的Extension Development Host] - 窗口。 而是弹出了一个popup,让你选是C++还是Node.js等,然后我想,既然是Node.js的项目,就选Node.js吧,然而结果还是不能运行。 然后查看了下vscode console的日志,发现是提示找不到vscode这个module, 明明在package.js里已经加了这个module的,为什么运行的时候还提示找不到呢?

我用meld这个对比工具,把hugofy-vscode的目录跟我们的hello world扩展目录进行了对比,发现hugofy-vscode的目录下缺少一些vscode需要的文件。 总体来说,整个.vscode这个目录是缺失的。直接把hello world下面的.vscode目录复制过去,发现F5功能神奇地可以工作了。

然后大概浏览了一下代码,发现这些代码没有严格遵守typescript的写法。 于是编辑 tsconfig.json 启用严格类检测: "strict": true /* enable all strict type-checking options */

代码里充斥着各种分号;, 自从用习惯了Golang之后,我再也不习惯写带分号的语句了。 那么,Typescript本身是不是支持和提倡无分号语句呢,于是我进行了一翻搜索。

TypeScript follows the same ASI rules as JavaScript. Semicolons are technically not required in either language, save for a few rare, specific cases.

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#semicolon-formatter-option

https://stackoverflow.com/questions/51004223/are-semicolons-necessary-in-typescript-2/51004311#51004311

https://medium.com/@eugenkiss/dont-use-semicolons-in-typescript-474ccfe4bdb3

既然ts像js一样遵循ASI规则,那我们就可以放心地省略分号了。

编辑 .eslintrc.json 禁用分号:

"@typescript-eslint/semi": "never",
"semi": "off"

然后,咱也没写过ts这玩意啊。倒底靠不靠谱呢?

咱也没太多时间看官方手册来学个ts, 像吃快餐一样的快速上手教程最适合,我们就要看两下就开搞的那种,嗯,找到一个不错的上手教程 https://ts.xcatliu.com/

老灯花了几分钟大概了解了一下ts这个语言。

然后,开始撸vscode插件了,先拿Hugofy这个插件开刀。

根据vscode文档 https://code.visualstudio.com/api/references/contribution-points ,我们要增加右键菜单,需要修改package.jsoncontributes字段. (你不是第一次搞vscode插件么,你怎么知道这些的?当然是通过搜索找到了文档)

我们在contributes字段下增加keymenus,其值为一对象:

{
    "explorer/context": [
        {
            "when": "explorerResourceIsFolder",
            "command": "hugofy.newPost",
            "group": "hugo"
        }
    ]
}

when表示,只有在exploer, 也就是vscode左边的文件浏览器,才会触发这个右键菜单。并且,我们的需求是,只要求对目录右击时能有右键菜单。 因为这个when的条件是explorerResourceIsFolder的值为true的时候。 command 为要执行的命令,这个命令是我们在插件初始化时注册的。 对于一个第一次撸vscode插件的人来说,要知道这一点显然是不容易的,因此,我这个资源是从so上面搜索到的 https://stackoverflow.com/questions/38267360/vscode-extension-api-identify-file-or-folder-click-in-explorer-context-menu

这个答案中还提到了插件开发中一个非常重要的技能,调用Developer: Inspect Context Keys来获取这些信息。

vscode-dev-inspect-ctx-keys-2020-05-04-22-51-27.png

注意要打开控制台(Ctrl+Shift+i), 不然你是看不到结果的。但是我上面那个图还是不能太直观的描述这个inspect操作,因此老灯又做了个gif动图:

vscode-dev-ctx-inspect.gif

好了,现在我们测试一下右键菜单,是不是出来了?

right-click-ctx-menu-new-post-test-2020-05-04-23-20.gif

右键菜单是出来了,但是执行的命令呢? 原代码是不能处理右键菜单的,因此我们要引入一个参数。右击了哪个对象,这个对象必须传入到我们的命令里。 通过一次调试,我们可以发现,我们需要的被右击的目录的路径,就在对象的 fsPath这个属性里。但是如果是直接执行的命令(非右击的情况),命令处理函数 是收不到任何对象的,此时它是undefined, 因此我们修改后的newPost()函数必须要同时支持这两种情况。

另外一点是,由于我们主要是采用Hugo的page bundle的方式来组织日志及其资源(图片,视频等), 因此,markdown文件的默认名称就是index.md,我们需要快速的创建日志文件,而不需要用户再次手动输入index.md这些字符串,这样太麻烦了。 查询vscode api文档,得知showInputBox是可以有默认值的,这个值放在value属性里,就像这样:

vscode.window.showInputBox({ placeHolder: 'Enter filename', value: 'index.md' })

好了,命令处理函数修改好了。如果我们输入中文的路径呢?中文路径在URL显示的时候非常不友好,会被转码为urlencode之后的形式。 因此,我们要么手动在Hugo markdown文件里的Front matter里加一个slug字符,手写上英文版的slug, 要么,还有更自动的方式? 没错,我们可以修改代码,让它自动完成中文到拼音的转换。当我们输入测试中文时,新建时目录名自动转换为拼音的ce-shi-zhong-wen.

我们再来看下修改后的效果:

chinese-slug-auto-convert-test-2020-05-04-23-33.gif

这里,文件名相对于content/post的路径是linux/archlinux/ce-shi-zhong-wen/index.md, 如果我们使用原来的插件而不是我们修改过后的, 要输入这么长的路径,是不是很麻烦?而经过修改后的插件,我们只需要在archlinux目录上右击,然后输入测试中文,后面的index.md插件已经预先写好了, 所以,在写page bundle或分类路径比较深的情况下,这次修改带来了非常大的方便。

第二刀: 修复主题下载

修复请求问题

原来的代码主题下载不工作,我们先分析下为什么。通过一些简单的console.log日志打印,我们很快就能发现,原来的插件代码调用的是https.get来请求github api. 但是github的api进行了一些重定向操作,而https.get是不支持重定向的,怎么办?我们换一个更重量级的库来请求https? 好像没有必要。 https.get非常轻量级且能完成工作,我们需要的只是让它能处理http重定向而已。又是一番搜索,很快,找到一个名为follow-redirects库,正是为解决重定向问题而生的。 我们只需要把原来的import代码换成import { https } from 'follow-redirects', 然后实际的代码都不用动,就解决这个问题了。 另外要记得安装一个这个库:npm i follow-redirects

修复逻辑问题

很多时候,一个主题对于它自己的名称(主要会用于URL路径加载资源文件)是有要求的。 所以我们不能直接github的仓库名称是什么,我们把主题git clone下来就存到什么目录,这会导致问题。

现在的问题是,Hugo的主题仓库里,很多仓库名称命名并不统一。有些是hugo-xxx-theme的格式的名称,真正的主题名就是中间的xxx, 有些是hugo-theme-xxx,最后的xxx才是真正的主题名称。还有各式各样的,比如xxx-hugo-themehugo-xxxxxx-hugotheme-xxxxxx-theme等。 还有一些更过分的, 比如xxx-hugo-yyy-theme 之类的。这种程序没法自动处理,因为真正的主题名,有可能是xxx, 也有可能是yyy.

总之,我们在处理主题名称的时候,要进行规范化处理,提取出真正的主题名。当然,这种处理是要尽可能是避免的,最好的解决办法是,Hugo官方出面,规范化主题repo的命名, 不规则的主题,要重新命名后再加入官方repo.对于一个已经存在300个以上主题的仓库来说,要这样办是非常困难的,因为重新命名主题,可能会破坏现存用户的主题更新操作。

还有一点是,当用户切换主题时,如果Hugo server已经启动了,则我们需要重启Hugo server以应用新的主题。

优化请求

原插件都是要进行二次请求,第一次请求用于从gohugoio/hugoThemes这个仓库获取所有主题列表,第二次请求根据用户选择了哪个主题,再请求一次api获取这个主题的git clone URL. 但是我们仔细观察,会发现gohugoio/hugoThemes这个仓库有些特殊,它里面的主题,都是采用git submodule的方式添加进来的,而不是添加的实际文件。 而我们观察第一次api请求获取主题列表时,里面有一个字段名为html_url, 这个值就像这样:https://github.com/marketempower/axiom/tree/34156c0530092c3cef71bfeaa133c19673bb58b1" 眼尖的童鞋一眼就能看出,完全没有必要进行第二次请求,因为主题的仓库url就可以从这个html_url里提取出来,比如上面这个提取出来就是https://github.com/marketempower/axiom.git 然后也有极个别主题html_url字段值为null的,这是为什么呢?原来这几个主题的源git仓库不是github, 而是在其它git仓库托管服务商那里,比如在gitlab之类的。数了一下,发现这种类型的仓库数量只在个位数。因此我们可以优化代码,使这个代码在90%以上的情况,都不需要进行第二次api请求就能直接知道主题的git URL.

第二点优化就是,原代码是每次在执行下载主题的命令时才开始下载主题列表,而这个获取过程,在国外可能会很快,但是国内的情况大家也都明白,耗时是比较长的。这就导致了,你点击下载主题的命令,但是过了好长时间才会有结果出来。所以,我们可以在插件初始化时就在后台下载好主题列表,然后,我们引入一个缓存机制,后续任何时候要下载主题,都不需要进行第二次API请求来获取主题列表。 通过查询vscode api文档,我们知道,插件初始化时会调用 activate, 那么我们就在activate处理函数里加上这个主题获取的动作。

//文件顶部加上声明
let extCache: any

const themelistCacheKey = 'ttys3.hugoy.themeList'

// Extension activation method
const activate = (context: any) => {
    // 插件加载,初始化缓存对象
    extCache = new vscache(context)
    // 注册插件命令
    context.subscriptions.push(
        vscode.commands.registerCommand('hugofy.getVersion', getVersion),
        vscode.commands.registerCommand('hugofy.newSite', newSite),
        vscode.commands.registerCommand('hugofy.newPost', newPost),
        vscode.commands.registerCommand('hugofy.build', build),
        vscode.commands.registerCommand('hugofy.downloadTheme', downloadTheme),
        vscode.commands.registerCommand('hugofy.setTheme', setTheme),
        vscode.commands.registerCommand('hugofy.startServer', startServer),
        vscode.commands.registerCommand('hugofy.stopServer', stopServer)
    )

    //获取Hugo主题列表并缓存
    themeUtils.getThemesList().then((themeList: any) => {
        extCache.put(themelistCacheKey, themeList)
    })
};

exports.activate = activate

优化主题选择列表

由于Hugo官方主题git仓库是使用的submodule, 虽然我们可以一个请求获取绝大多数主题的git URL, 但是对于这个主题的star数量,还是获取不到的。 如果要一次性给300个主题来一个star数据获取,通过REST API也会导致请求过于频繁。有没有办法解决呢? 办法当然是有的,GitHub GraphQL API可以一次请求和返回多个资源,但是不同于REST API可以有限地公开请求(不需要登录),GitHub GraphQL API是需要有密钥才能请求的。 直接使用,当然会给使用者造成一定的麻烦,毕竟人家只是需要安装个插件,然后还要提供一个github 密钥,有点麻烦了。因此,这种可以做成可选方案。 如果提供了Github API密钥,就可以显示更详细的信息(fork数量,star数量,最近更新代码时间等,然后可以根据star排序等等)。否则,就显示名称 + URL.

使用GitHub GraphQL API是可行的,我们可以随便一次请求3个主题的fork数量,star数量,创建时间,最后提交代码的时间:

github-graphql-hugo-themelist-2020-05-05-01-24-50.png

当然,这里老灯时间有限,就不实现这个功能了,或许在看文章的你有时间,可以尝试实现,来提交PR.

第三刀: 其它改进

优化错误提示和处理

当Hugo server启动失败的时候,大部分是由于主题缺少必要的配置(有些主题会需要一些特别配置),或者,这个主题本身的代码存在问题。 原插件显示的是错误的Hugo命令不存在这种”错误的错误信息“。我们修改之后,让它显示详细的失败错误信息,以方便用户修正主题配置,顺利应用新主题。

detailed-error-message-2020-05-05-01-41.gif

提示信息优化方面也有很多工作可以做,比如,当用户点击下载一个主题时,很可能由于网络原因下载失败,此时,应该友好地显示一个“重新下载”的按钮,而不是重新返回主题列表, 再让用户肉眼找到之前他想下载的那个主题。 当一个主题下载成功的时候,用户很可能是想尝试一下使用这个主题的,插件不应该傻傻地只完成主题下载。而是应该提供一个“使用当前主题“的按钮,用户点击后即可应用当前主题, 并自动打开预览页面。

优化后的效果,选择下载主题时,主题列表可以瞬间显示, 另外,下载成功时会有”应用此主题“和”启动服务器“的按钮:

hugo-quick-theme-list-and-down-succeed-actions-btn-2020-05-05-01-37.gif

这里可以讨论的地方有很多,甚至老灯当前发布的这个版本可能也有很多地方还可以优化的。

增加默认快捷键

每次按Ctrl+Shift+p,然后再通过搜索关键字hugo来执行相应的命令,对于需要频繁执行的操作来说,会显得非常麻烦。如果有一个默认的快捷键映射,会更加方便。 这个插件有8个命令,所以在默认的快捷键映射上,也不可能占用8个快捷键,这样太浪费了。因此我这里使用第一组合键+second key of chord的方式。 比如,新建Post, 快捷键设置为ctrl+shift+h p,意思是,先按ctrl+shift+h然后释放,再按一下p然后释放,动作就触发了。设置主题(theme)的快捷键为 ctrl+shift+h t,这里的h取的是Hugo的意思,但是这里有个小问题,不过应该不会成为问题。vscode默认的快捷键里,ctrl+shift+h是有映射成Search: Replace in Files的。 但是由于vscode左侧快捷菜单就有搜索和替换的快捷按钮,因此,这个应该不会成为问题。如果实在是需要频繁的进行文件之间的替换操作,也可以自行设置快捷键。 插件只是提供默认地映射,用户可以自行修改。

有了快捷键,下载主题(d), 切换主题(t), 启动hugo服务器(s), 新建日志Post(p) 等等这些操作都非常顺畅了。而且键的字母默认是跟操作本身相关联的,基本上取的首字母,比较有意义, 从而记忆方面也不成问题。

根据vscode文档,我们需要向package.json文件contributes字段下增加如下快捷键配置:

"keybindings": [
    {
        "key": "ctrl+shift+h s",
        "command": "hugofy.startServer"
    },
    {
        "key": "ctrl+shift+h b",
        "command": "hugofy.build"
    },
    {
        "key": "ctrl+shift+h d",
        "command": "hugofy.downloadTheme"
    },
    {
        "key": "ctrl+shift+h p",
        "command": "hugofy.newPost"
    },
    {
        "key": "ctrl+shift+h n",
        "command": "hugofy.newSite"
    },
    {
        "key": "ctrl+shift+h t",
        "command": "hugofy.setTheme"
    },
    {
        "key": "ctrl+shift+h x",
        "command": "hugofy.stopServer"
    },
    {
        "key": "ctrl+shift+h v",
        "command": "hugofy.getVersion"
    }
]
vscode-hugoy-keybindings-2020-05-05-03-07-01.png

使用快捷键操作一下主题下载和主题切换:

download-switch-theme-2020-05-05-02-20.gif

第四刀: webpack打包

webpack作为前端打包界的扛把子, 插件打包这种事自然少不了它。 事实上当你使用vsce命令发布插件时,vsce就会提示你,你的插件包含的文件数太多了,应该采用打包器打包一下。

但是这里,我们面对的是一个现存的插件,它在创建之初就没有使用webpack. 因此我们要给它加上webpack打包。

打包这部分主要是参考 https://code.visualstudio.com/api/working-with-extensions/bundling-extension

以及这个文档中提到的参考PR https://github.com/Microsoft/vscode-references-view/pull/50

如果把代码贴出来就太长了,所以这里我说一下commit: https://github.com/ttys3/hugofy-vscode/commit/aa848221624ce13a52985568f2eeb19bd5d3ec28

注意:

由于tasks.json中的problemMatcher换成了$ts-webpack,而vscode默认并不支持这个, 因此我要要安装一个额外的插件TypeScript + Webpack Problem Matchers. 在vscode中,打开Quick Open (Ctrl+P),执行 ext install eamodio.tsl-problem-matcher 即可快速安装。

如何发布插件

此部分基本上参考 https://code.visualstudio.com/api/working-with-extensions/publishing-extension

vscode采用vsce(Visual Studio Code Extensions的缩写)命令进行插件的打包,发布和管理。 如果没有安装,首先我们要安装一下这个工具:

npm install -g vsce

发布插件时需要PAT(Personal Access Token的缩写), 这个PAT怎么获取呢?

首先,你要有一个Azure DevOps organization,如果没有Azure账号,你要注册一个。 登录Azure账号后,进入 https://dev.azure.com/ 会进入你的组织主页。

比如老灯的组织名是wudeng, 那么进入的是https://dev.azure.com/wudeng/,进入这里之后,啥项目也不用创建。 咱不用管其它的,只需要点击带齿轮的小人图标,进去之后点击+New Token创建新的PAT。

azure-devops-PAT-menu-2020-05-05-02-42.gif

这里要注意的是, Organization 一定要选 All accessible organizations,不然你后面会遇到ERROR Failed request: (401)错误。 权限范围那里,找到Marketplace, 并勾选上 AcquireManage:

azure-pat-form-2020-05-05-02-45-50.png

创建好PAT后一定要记得复制保存好,因为后面不会再显示了。

OK, 有了PAT,我们可以开始创建 publisher 了:

vsce create-publisher ttys3

publisher 是对于插件开发者的标识, 这个标识是唯一的,老灯这里就用ttys3吧。

根据 https://code.visualstudio.com/api/references/extension-manifest , 我们需要在package.json中增加publisher,这个值就是我们刚才创建的。

另外还有一些字段比较重要:

{
	"name": "hugofy",
	"publisher": "ttys3",
	"repository": "https://github.com/ttys3/hugofy-vscode",
    "version": "0.3.3"
}

插件的唯一标识是由publisher.name组成的,因此要选用好的方便记忆和搜索的名字。 repository是源码仓库,这个方便大家点击和查看源码。 version是版本号

发布插件:

cd 插件所在目录
vsce publish 要发布的版本号

比如 vsce publish 0.3.3

发布成功后,新的版本不会马上出现,要等待几分钟后才可以看到。

发布之后就会得到一个插件页面,比如我这个是 https://marketplace.visualstudio.com/items?itemName=ttys3.hugofy

vscode-market-ext-page-2020-05-05-02-57-25.png

后记

由于篇幅关系,文章中不可能涉及太多代码,如果希望参与一起改进的朋友,可以直接查看仓库源码 http://github.com/ttys3/hugofy-vscode 这也是老灯第一次使用ts写代码, 终究逃不过”真香定律“, Angular被ts拉拢了,Vue3直接采用ts编写了, 而React由于历史原因, 它比ts出来得早,因此它不可能是采用ts编写的,不过目前React也支持采用ts来编写代码

所以,老灯觉得,以ts目前这个势头,学一下还是有必要的。

本文参考

https://code.visualstudio.com/api/get-started/your-first-extension

https://liiked.github.io/VS-Code-Extension-Doc-ZH/

https://code.visualstudio.com/api/working-with-extensions/bundling-extension

https://code.visualstudio.com/api/working-with-extensions/publishing-extension#.vscodeignore

https://code.visualstudio.com/api/references/vscode-api

https://code.visualstudio.com/api/references/contribution-points

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#semicolon-formatter-option

https://stackoverflow.com/questions/51004223/are-semicolons-necessary-in-typescript-2/51004311#51004311

https://medium.com/@eugenkiss/dont-use-semicolons-in-typescript-474ccfe4bdb3

https://ts.xcatliu.com/basics/type-assertion

https://github.com/microsoft/TypeScript/issues/27293

https://github.com/wmonk/create-react-app-typescript/issues/214

https://scripter.co/hugo-leaf-and-branch-bundles/

https://github.com/microsoft/vscode-extension-samples/blob/master/helloworld-sample/src/extension.ts

https://stackoverflow.com/questions/39599514/vs-code-add-a-new-file-under-the-selected-working-directory/39599731#39599731

https://stackoverflow.com/questions/38267360/vscode-extension-api-identify-file-or-folder-click-in-explorer-context-menu