使用TypeScript拓展你自己的VSCode
转自:http://www.iplaysoft.com/brackets.html
使用TypeScript拓展你自己的VSCode! 0x00 前言
在前几天的美国纽约,微软举行了Connect(); //2015大会。通过这次大会,我们可以很高兴的看到微软的确变得更加开放也更加务实了。当然,会上放出了不少新产品和新功能,其中就包括了VS Code的beta版本。而且微软更进一步,已经在github将VS Code的代码开源了。除了这些让人兴奋的消息,我们还应该注意到VS Code提供了对拓展的支持。
所以本文就来聊一聊使用TypeScript开发VS Code拓展的话题吧。
本文所使用的拓展的应用商店页面:
https://marketplace.visualstudio.com/items/JiadongChen.LicenseHeader
github页面:
https://github.com/chenjd/VSCode-StandardHeader
0x01 你好,世界
"万事开头,Hello World"。所以我们就从一个Hello World作为起点,开始一步一步构建自己的VScode的拓展。
在开发vscode的拓展之前,我们先要确保电脑上已经安装了Node.js。之后,我们便可以利用微软所提供的基于Yeoman的模板生成器来生成vscode拓展的模板了。
- npm install -g yo generator-code
之后,我们只需要在终端中运行yo code命令,即可以进入创建拓展模板的引导过程。
- yo code
在引导过程中将TypeScript选择为开发语言,并且填完一些基本信息之后,我们的第一个vscode拓展便创建完成了。
那么,yo code命令主要为我们做了一些什么事情呢?
会根据我们在引导中所填的信息,在当前目录生成一个拓展的文件夹,文件夹名即我们在引导中填入的拓展名称。 该文件夹中主要包括了盛放源文件(extension.ts)的src文件夹、test文件夹以及out文件夹。需要注意的是out文件夹,在编译typescript源文件之前out文件夹是没有创建的,而编译之后会创建out文件夹并且其中的内容是typescript经过编译之后生成的js文件。 生成了资源配置文件package.json,package.json文件描述了该拓展的信息和它的功能。下文我还会具体说明package.json文件。 创建了launch.json以及tasks.json和settings.json(位于项目中的.vscode目录下),其中launch.json文件规定了启动一个在拓展开发(Extension Development)模式的VS Code进程,并且规定在VS Code启动之前会先运行tasks.json文件中所定义的task(根据tasks.json中的定义,相当于npm run compile),即先使用TypeScript的编译器将ts文件编译为js文件。这样我们就可以直接编译(因为是typescript)运行并且调试我们的拓展项目了。 当然,还会根据我们在引导中的选择来决定是否创建一个Git仓库,用来做版本控制。
下面便是我们的拓展项目的完整目录:
- .
- ├── .gitignore //配置不需要加入版本管理的文件
- ├── .vscode // VS Code的整合
- │ ├── launch.json
- │ ├── settings.json
- │ └── tasks.json
- ├── .vscodeignore //配置不需要加入最终发布到拓展中的文件
- ├── README.md
- ├── src // 源文件
- │ └── extension.ts // 如果我们使用js来开发拓展,则该文件的后缀为.js
- ├── test // test文件夹
- │ ├── extension.test.ts // 如果我们使用js来开发拓展,则该文件的后缀为.js
- │ └── index.ts // 如果我们使用js来开发拓展,则该文件的后缀为.js
- ├── node_modules
- │ ├── vscode // vscode对typescript的语言支持。
- │ └── typescript // TypeScript的编译器
- ├── out // 编译之后的输出文件夹(只有TypeScript需要,JS无需)
- │ ├── src
- │ | ├── extension.js
- │ | └── extension.js.map
- │ └── test
- │ ├── extension.test.js
- │ ├── extension.test.js.map
- │ ├── index.js
- │ └── index.js.map
- ├── package.json // 该拓展的资源配置文件
- ├── tsconfig.json //
- ├── typings // 类型定义文件夹
- │ ├── node.d.ts // 和Node.js关联的类型定义
- │ └── vscode-typings.d.ts // 和VS Code关联的类型定义
- └── vsc-extension-quickstart.md
此时,我们只需要点击在VS Code的Debug区域的Start按钮即可。
在接下来开启的一个处于拓展开发模式的新的VS Code中,我们只需要在命令面板中输入Hello World便可以激活这个模板拓展,弹出一个Hello World的消息弹窗。
那么,VS Code到底是如何加载并运行拓展的呢?我们又应该如何开发拓展供自己甚至是分享给更多的人更好的使用VS Code呢?
0x02 关于package.json的两三事
作为拓展项目的资源配置文件,package.json不仅仅描述了该拓展的信息还描述了拓展的功能。需要说明的是,当VS Code启动时,拓展的package.json文件便会被读取,并且VS Code还会对package.json文件中的contributes部分的内容做处理。这一点和拓展的源文件extension.ts有所区别。VS Code并不会在启动时便加载拓展的源代码。
下面我们就来看一看我们刚刚生成的这个拓展项目中的package.json文件的内容吧。
- {
- "name": "Standard-Header",
- "displayName": "Standard-Header",
- "description": "standard-header",
- "version": "0.0.1",
- "publisher": "JiadongChen",
- "engines": {
- "vscode": "^0.10.1"
- },
- "categories": [
- "Other"
- ],
- "activationEvents": [
- "onCommand:extension.sayHello"
- ],
- "main": "./out/src/extension",
- "contributes": {
- "commands": [{
- "command": "extension.sayHello",
- "title": "Hello World"
- }]
- },
- "scripts": {
- "vscode:prepublish": "node ./node_modules/vscode/bin/compile",
- "compile": "node ./node_modules/vscode/bin/compile -watch -p ./"
- },
- "devDependencies": {
- "typescript": "^1.6.2",
- "vscode": "0.10.x"
- }
- }
我们可以看到,package.json描述了该拓展的一些基本信息,例如拓展的名称name、拓展的描述信息description以及拓展的版本号version和发布者的信息publisher等等。顺带提一句,直接通过提高版本号的方式就可以使用拓展发布工具来更新已经发布到VS Code应用商店的拓展版本。
除了这些,我们甚至还可以在package.json文件中配置一些拓展在VS Code的应用商店中的展示信息,例如拓展在商店中的种类:categories、拓展的icon图:icon以及拓展在应用市场主页的一些展示信息:galleryBanner等等。
- ...
- "icon": "res/icon.png",
- "galleryBanner": {
- "color": "#5c2d91",
- "theme": "dark"
- },
- "categories": [
- "Other"
- ],
- ...
当然,更重要的内容是activationEvents、contributes以及scripts和main这几项内容。其中scripts项的内容是使用TypeScript进行开发时所特有的,主要的作用是用来提供对ts文件进行编译的相关信息。而main项则指向了将ts源文件编译后所生成的js文件。
ActivationEvents
正如上文所说,VS Code默认状况下并不会在启动时立刻执行拓展中的代码。因此,为了使拓展能够被激活,我们需要在package.json文件中定义activationEvents项的内容。例如上例中,activationEvents的定义如下:
- ...
- "activationEvents": [
- "onCommand:extension.sayHello"
- ],
- ...
意思是当“onCommand:extension.sayHello”事件被触发之后,拓展会被激活。那么在VS Code中,激活事件都有哪些种类呢?下面我们就来归一下类。
根据文件所使用的语言:onLanguage:${language}
当打开的文件是使用onLanguage所规定的语言时,拓展会被激活。
例如:
- ...
- "activationEvents": [
- "onLanguage:python"
- ]
- ...
根据所输入的命令:onCommand:${command}
当在onCommand中规定的命令被触发时,拓展会被激活。在上文生成的Hello World模板中,我们就可以看到。
- ...
- "activationEvents": [
- "onCommand:extension.sayHello"
- ]
- ...
根据文件夹:workspaceContains:${toplevelfilename}
- "activationEvents": [
- "workspaceContains:package.json"
- ],
无限制:*
- ...
- "activationEvents": [
- "*"
- ]
- ...
由于没有限制,因此在VS Code一启动时便会激活该拓展。因此,这种不加以条件限制就激活拓展的方式并不是十分推荐的。大家最好谨慎使用。
Contribution
在package.json文件中的contributes项中,同样包含很多种类。如果需要归类的话,可以分为以下几个类型。
configuration commands keybindings languages debuggers grammars themes snippets
但是本文限于篇幅,将只关注commands和keybindings这两种。
commands
还以上文中的Hello World为例,我们在commands项中定义了命令的title以及title所对应的具体命令。如下所示:
- "contributes": {
- "commands": [{
- "command": "extension.sayHello",
- "title": "Hello World"
- }]
- },
此时一旦安装了该拓展,我们就可以在VS Code中的命令面板(我在Mac上的快捷键是Shift+cmd+p)中找到“Hello World”,输入便会触发extension.sayHello这条命令,而上文中的拓展激活事件项activationEvents中如果定义的内容是"onCommand:extension.sayHello",则激活事件被触发,拓展的代码被激活。
keybindings
当然,和commands对应的,我们还可以通过在package.json中定义keybindings项,通过绑定快捷键的方式触发命令。这样操作起来更加便捷,例如下文中我们自己开发一个插入标准页眉的拓展时,使用的便是绑定快捷键的方式。
- "contributes": {
- "keybindings": [{
- "command": "extension.insertHeader",
- "key": "shift+cmd+1",
- "when": "editorTextFocus"
- }]
- },
如果我们在VS Code中安装了定义了快捷键触发的拓展,则打开VS Code的KeyBoard ShortCut就可以看到拓展中定义的快捷键和它对应的命令了。
0x03 VS Code运行拓展的原理
通过上一小节的内容,我们就能很清楚的理解上文中那个模板拓展的运行过程了。
VS Code首先会检测到拓展并且读取拓展的package.json文件的内容并将package.json文件中的contributes项应用到VS Code中。这样,我们就可以根据contributes项中的内容,或者是在命令面板中输入contributes项中定义的commands,或者是使用contributes项中所定义的快捷键keybindings来触发extension.sayHello命令。
一旦extension.sayHello触发,VS Code会创建一个叫做onCommand:extension.sayHello的激活事件。
与此同时,所有在自己的package.json文件中将activationEvents设置为onCommand:extension.sayHello的拓展会被激活。并且会根据package.json文件中main项的内容,将./out/src/extension.js文件加载到JavaScript VM中。接下来,VS Code会调用在extension.js文件中的active函数,在active函数中,我们需要提供“extension.sayHello”这个函数的具体实现并执行。
好了,了解了VS Code拓展的基本知识之后我们就可以开始着手开发自己的拓展了,这个拓展的目的是向源文件添加License页眉。
0x04 一个插入License页眉的拓展
既然要打造自己的VS Code,那么自己喜欢的一些操作习惯自然希望能够用在VS Code上。而插入页眉便是这样一个简单的小功能。
我们首先来看一看在上文中那个Hello World模板拓展的源文件即extension.ts文件的基本内容。
- import * as vscode from 'vscode';
- export function activate(context: vscode.ExtensionContext) {
- var disposable = vscode.commands.registerCommand('extension.sayHello', () => {
- ...
vscode.window.showInformationMessage('Hello World!');
...
});- }
首先,我们自然要引入vscode命名空间下的API,以获得控制VS Code的能力。
其次,我们注意到了拓展的源文件需要export一个叫做activate的函数,当拓展的package.json文件中activationEvents所定义的事件被触发时,VS Code会调用activate函数。
最后,我们可以看到我们使用vscode的API注册了一个叫做“extension.sayHello”的命令,并且提供了它的具体实现,按照模板中的逻辑,“extension.sayHello”命令的逻辑是在窗口中显示一个内容为“Hello World”的信息消息。具体的效果在本文一开始的部分各位已经看到了。
那么接下来就十分简单了,我们首先新建一个叫做HeaderGenerator的类,用来执行插入页眉的任务。
- class HeaderGenerator {
- private _disposable: Disposable;
- public insertHeader() {
- // Get the current text editor
- let editor = window.activeTextEditor;
- if (!editor) {
- return;
- }
- // Define header content
- var header = "License Header";
- // Get the document
- var doc = editor.document;
- // Insert header
- editor.edit((eb) => {
- eb.insert(doc.positionAt(0), header);
- });
- }
- dispose() {
- this._disposable.dispose();
- }
- }
插入页眉的具体执行是当前窗口的editor(TextEditor类)的edit方法,通过利用TextEditorEdit类的insert方法实现对当前的文档doc(TextDocument类)插入新的内容。
之后,我们只需在extension.ts文件中的activate函数中实现调用HeaderGenerator类的insertHeader方法即可。
- import * as vscode from 'vscode';
- import {window, commands, Disposable, ExtensionContext, TextDocument} from 'vscode';
- export function activate(context: vscode.ExtensionContext) {
- console.log('Congratulations, your extension "standard-header" is now active!');
- let headerGen = new HeaderGenerator();
- var disposable = vscode.commands.registerCommand('extension.insertHeader', () => {
- headerGen.insertHeader();
- });
- context.subscriptions.push(headerGen);
- context.subscriptions.push(disposable);
- }
当然,为了增加快捷键“shift+cmd+1”的支持,我们还需要在package.json中修改contributes的内容:
- "contributes": {
- "keybindings": [{
- "command": "extension.insertHeader",
- "key": "shift+cmd+1",
- "when": "editorTextFocus"
- }]
- },
之后,让我们先进入拓展开发模式看一下效果。使用快捷键shift+cmd+1,我们可以看到在VS Code的窗口中插入了页眉(截图中的页眉内容我已经换成了MIT协议)。
好了,到此我们的小小的在源文件中插入页眉的拓展就完成了,下面就让我们来使用安装、甚至是发布到VS Code的应用商店让大家一起分享我们的劳动成果吧。
0x05 本地安装或在应用商店发布
为了不必再每次都要进入拓展开发模式才能“使用”我们的拓展,我们就必须让自己的VS Code安装这个拓展。
事实上在本地安装供自己的拓展是十分简单并且方便的事情。VS Code会在.vscode/extensions文件夹中获取本地的拓展。而.vscode/extensions文件夹所在的位置我们可以总结如下:
Windows %USERPROFILE%\.vscode\extensions Mac $HOME/.vscode/extensions Linux $HOME/.vscode/extensions
我们只需拷贝一份我们的拓展到.vscode/extensions文件夹中,VS Code在启动时便能够检查到该拓展了。
当然,除了自己使用自己开发的拓展之外,我们还可以将拓展发布到VS Code的应用商店。此时我们就要借助一个拓展发布工具——vsce了。
首先是安装vsce:
- npm install -g vsce
之后我们还需要到Visual Studio Team Services注册并登陆,以获取Personal Access Token。
一旦获取了Personal Access Token,我们就可以使用vsce创建一个发布者账号了。
- vsce create-publisher
紧接着,登陆并发布:
- vsce login
- vsce publish
发布成功之后,我们就可以在VS Code的应用商店中看到自己的拓展了。
并且在VS Code的命令面板中,我们也可以使用命令安装:
- ext install
好啦,行文至此,使用TypeScript拓展你自己的VS Code讲的已经差不多了。希望各位多多交流~
使用TypeScript拓展你自己的VSCode的更多相关文章
- 使用TypeScript拓展你自己的VS Code!
0x00 前言 在前几天的美国纽约,微软举行了Connect(); //2015大会.通过这次大会,我们可以很高兴的看到微软的确变得更加开放也更加务实了.当然,会上放出了不少新产品和新功能,其中就包括 ...
- CocosCreator TypeScript项目 (vscode 设置中文,默认调试环境设置)
版本:2.2.1 深圳好多公司用的cocoscreator,学习一下. 这篇是如何安装,然后运行一个hello world. 一 下载 cocoscreator:https://www.cocos. ...
- vscode下搭建typescript时提示"无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称"错误的解决方法
根据网上的教程,安装了node.js后,再安装了typescript,,,这时候编译生成或者在vscode的终端里调用npm或者tsc --version时,总是提示 npm : 无法将"n ...
- 《TypeScript 中文入门教程》 1、基础数据类型
转载:https://github.com/MyErpSoft/TypeScript-Handbook/blob/master/pages/zh-CHS/Basic%20Types.md 概述 为了让 ...
- TypeScript中的枚举类型
TypeScript拓展了Javascript原生的标准数据类型集,增加了枚举类型(enmu)和其他语言一 样 它提供我们一种数字类型的值,用来设置由于辨别的名字和方法 enum Students { ...
- vue+typescript基础练习
环境 win10 node -v 8.9.3 vue-cli 3.4 typescript 3.1.5 编辑器 vscode 目标 使用vuecli工具,建立一个项目,使用typescript.并实现 ...
- 与TypeScript的一场美丽邂逅
TypeScript(一)前言:当你点开这篇文章时,我相信你已经在很多地方都已经听说过或者见过TypeScript了.但是可能对TypeScript依然有很多问号:TypeScript到底是什么?为什 ...
- 帮你培养类型思维TypeScript(一)
前言:作为一名程序员,相信你已经熟练掌握了JavaScript语言,由于其应用领域非常的广泛,所以算得上是每一个程序员必须要掌握的语言.但是JavaScript自身的缺点,相信每一个程序员也是深有体会 ...
- 简单三步同步你的 VSCode 用户配置
https://www.cnblogs.com/knight-errant/p/10444777.html 设备重装,换设备,VSCode 又要重新配置了?不不不,简单三步,让你的 VSCode 配置 ...
随机推荐
- Oracle数据库命令行下数据的导入导出
//设置导入导出字符集,导入导出都要设置一下 export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK //导出 exp system/oracle@orcl file=/u ...
- 【POJ3615】Cow Hurdles 最短路,你若LCA,我仍不拦你。
NOIP2013货车运输.仅仅只是数据范围小了很多. 不到150s打完而且AC. . 额.当然.我写的是Floyd. 写LCA的真过分. #include <cstdio> #includ ...
- 系列文章(二):从WLAN的安全威胁,解析电信诈骗的技术症结——By Me
导读:互联网的无线接入已经成为大趋势,其中无线局域网(又称为WLAN,Wireless Local AreaNetwork)以其使用方便.组网灵活.可扩展性好.成本低等优点,成为互联网特别是移动互联网 ...
- Kettle-1-安装配置
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/wl101yjx/article/details/32921691 写在前面一: 数据仓库ETL工具有 ...
- JVM虚拟机—JVM的垃圾回收机制(转载)
1.前言 理解JVM的垃圾回收机制(简称GC)有什么好处呢?作为一名软件开发者,满足自己的好奇心将是一个很好的理由,不过更重要的是,理解GC工作机制可以帮助你写出更好的Java程序. 在学习GC前,你 ...
- JSP使用网站访问人数统计功能,方法与技巧
实现网站访问人数统计功能的步骤: 创建静态登录页面,并指定表单提交由登录处理页面进行处理. 创建登录处理页面获得登录信息,查询数据库,判断该用户是否注册,如果该用户已注册,把已登录用户的信息保存在一个 ...
- for迭代序列的三种方式
while循环是条件性的,for循环是迭代性的. for循环会访问所有迭代对象中的所有元素,并在所有条目都结束后结束循环. for循环迭代序列有三种基本的方式,分别是通过序列项迭代.通过索引迭代.通过 ...
- Java并发(7):阻塞队列
在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(LinkedList是双向链表,它实现了Dequeue接口). 使用非阻塞队列的时候有一个很大问题就是:它不会 ...
- Libev和LibEvent
libev和libevent功能基本相同,名称相近,到底该用哪一个呢?zhouhh@zhh64:~$ sudo apt-cache search libeventlibevent-dev – Deve ...
- gif 命令大全
git init # 初始化本地git仓库(创建新仓库) git config --global user.name "xxx" # 配置用户名 git config --glob ...