VSCODE - helloword

avatar
前端工程师

我们的主角-vscode

        相信大家对vscode都不陌生,它是微软推出的一款轻量级的代码编辑器,功能强大,颜值高,使用起来嘎嘎香。今天我们则来讲一讲让它更香的东西,vscode插件。

        vscode本身拥有一个插件市场,大家可以从市场里找到各种各样适合自己的插件,他们拥有非常多的功能,比如代码格式化、java开发支持、android开发支持、小程序开发支持、快应用开发支持,等等等。

        使用vscode的插件可以无限的提高咱们的生产效率。老一辈说的好,想不出来骚话了,因为我没见过老一辈的人,那就废话不多说,来讲讲我前几年写过的一个vscode插件的demo。

vscode 插件的项目长什么样呢?

image.png         大概是这个样子滴。其中package是插件的主要配置目录。我们可以配置例如下面这些自定义命令和菜单配置。

 "contributes": {
    "commands": [
      {
        "command": "extension.initTsClass",
        "title": "新建页面(Ts)"
      },
      {
        "command": "extension.initJsClass",
        "title": "新建页面(js)"
      },
      {
        "command": "extension.initJsComponent",
        "title": "新建组件(js)"
      },
      {
        "command": "extension.initTsComponent",
        "title": "新建组件(Ts)"
      },
      {
        "command": "extension.openWebview",
        "title": "新建项目"
      }
    ],
    "menus": {
      "explorer/context": [
        {
          "command": "extension.initTsClass",
          "group": "navigation"
        },
        {
          "command": "extension.initJsClass",
          "group": "navigation"
        },
        {
          "command": "extension.initTsComponent",
          "group": "navigation"
        },
        {
          "command": "extension.initJsComponent",
          "group": "navigation"
        }
      ]
    }
  },

        当然上面这些都是我自己写demo。不完整,vscode可以包含命令、菜单、快捷键、悬浮提示、自动补全、新语言支持、代码片段等功能在内,可谓是十分强大。由于精力有限,我这两天也只是写了包含菜单和命令两个实现。

        package.json的main是我们插件的主入口。我的是./src/extension.js,所有的插件功能设置也都在这里面。

自定义的菜单功能-新建统一的组件和页面

新建页面(Ts|js)

        在工作中,一般我们的页面和组件的开发都是标准的技术选型,比如 vue +ts着中,但是依然有很多人写出了千奇百怪的代码。为了方便统一大家的代码格式,vscode的自定义右键菜单(新建页面、新建组件)就诞生了。         首先我们要先在package.json里注册好我们的菜单命令。

   "contributes": {
      "commands": [{
        "command": "extension.initTsClass",
        "title": "新建页面(Ts)"
      },
      {
        "command": "extension.initJsClass",
        "title": "新建页面(js)"
      },
      {
        "command": "extension.initJsComponent",
        "title": "新建组件(js)"
      },
      {
        "command": "extension.initTsComponent",
        "title": "新建组件(Ts)"
      }]
    }, 
    "menus": {
      "explorer/context": [
        {
          "command": "extension.initTsClass",
          "group": "navigation"
        },
        {
          "command": "extension.initJsClass",
          "group": "navigation"
        },
        {
          "command": "extension.initTsComponent",
          "group": "navigation"
        },
        {
          "command": "extension.initJsComponent",
          "group": "navigation"
        }
      ]
    }

        然后在./src/extension.js引入响应的代码 如下

const vscode = require('vscode');

function activate(context) {
  require('./template/index')(context);// 菜单主要入口
}
exports.activate=activate
function deactivate() {}

module.exports = {
	activate,
	deactivate
}
/template/index 文件
const vscode = require('vscode');
const utils = require('../utils');
const paramCase = require('change-case').paramCase;
const { logger,generators } = utils;

const createComponent = (uri, type) => {
  console.log('恭喜,您的扩展“vscode-plugin-demo”已被激活!');
  new Promise(resolve =>
    vscode.window
      .showInputBox({
        prompt: '请填写组件名称'
      })
      .then(inputValue => resolve(inputValue))
  )
    // @ts-ignore
    .then(val => {
      if (val.length === 0) {
        logger('error', 'Component name can not be empty!');
        throw new Error('Component name can not be empty!');
      }

      let componentName = paramCase(val);
      // if 是初始化页面写入的路径 else 初始化页面整体模板
      let componentDir =  generators.createComponentDir(uri, componentName, true)
         
      // if 是初始化页面写入的路径 else 初始化页面整体模板
      if (type === 'initjsClass'||type === 'initTsClass') {
        return Promise.all([
          generators.createComponent(componentDir, componentName, type),
          generators.createComponentDirBuPath(componentDir, 'components', true),
          generators.createScriptFile(componentDir, "script", true,type === 'initTsClass'?'ts':'js'),
          generators.createCSS(componentDir, "style", true),
        ]);
      }else if(type === 'initTsComponent'||type === 'initjsComponent'){
        return Promise.all([
          generators.createComponent(componentDir, componentName, type),
          generators.createScriptFile(componentDir, "script", true,type === 'initTsComponent'?'ts':'js'),
          generators.createCSS(componentDir, "style", true),
        ]);
      }
      return Promise.all([
        generators.createComponent(componentDir, componentName, type),
        // generators.createCSS(componentDir, componentName),
        // generators.createModelFile(componentDir, componentName),
        // generators.createServiceFile(componentDir, componentName)
      ]);
    })
    .then(
      // @ts-ignore
      () => logger('success', 'React component successfully created!'),
      err => logger('error', err.message)
    );
};
module.exports = function(context) {
         // 注册命令
    const componentsList = [
      {
        type: 'initTsClass',
        commandID: 'extension.initTsClass'
      },
      {
        type: 'initjsClass',
        commandID: 'extension.initJsClass'
      },
      {
        type: 'initJsComponent',
        commandID: 'extension.initJsComponent'
      },
      {
        type: 'initTsComponent',
        commandID: 'extension.initTsComponent'
      }
    ];
    componentsList.forEach(comp => {
      let type = comp.type;
      let disposable = vscode.commands.registerCommand(comp.commandID, uri => {
        createComponent(uri, type);
      });
      context.subscriptions.push(disposable);
    });
}
initTsComponent 文件代码
<template>
</template>

<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator'
import {} from'script.ts'
@Component({})
export default class Index extends Vue {

}
</script>

<style lang="scss">
@import './style.scss';
</style>

这样一个拥有新建组件、新建页面的右键菜单插件功能就被变编写好了。然后我们打开调试,执行如下命令,就可以看到插件效果了。

image.png

效果如下、我的截图工具有问题,懒得解决了就拍照给大家看看

05e22b522ede468951a9b307aef9d823.jpg

小弟也是刚刚学习这一块内容,推荐大家看看www.cnblogs.com/liuxianan/p… 这个博客内容,非常的详细。