「教你用十分钟开发一款提升工作体验的vscode插件🌿 」console, debugger一键删除|自定义代码模板

简介: 「教你用十分钟开发一款提升工作体验的vscode插件🌿 」console, debugger一键删除|自定义代码模板

前奏🎵


我想读我文章的肯定是程序猿或者程序媛,不知道大家编码用的IDE是什么,反正我使用的一直是vscode,寒草和vscode也是亲如一家的好伙伴。

寒草🌿:“vscode,我们做兄弟吧”

vscode🪄:“给劳资滚”

寒草🌿:“好嘞,明儿见”

就这样,不打不相识,我和vscode成为了好伙伴,既然我们工作中很大一部分时间都是在和vscode打交道,并且vscode插件的能力是十分强大的,那么很自然浮现的想法就是:“我是不是可以掌握一些vscode插件开发知识,以达到优化我工作体验的目的?”,这个问题是显而易见的,大家的vscode应该都会装几个提高开发效率,优化开发体验的插件,比如:

  • veture
  • eslint
  • todo highlight
  • ...

这些插件对日常工作真的帮助很大,他们强大的功能也正印证着我上文的观点:

用vscode插件,可以优化我们工作体验

所以我们不妨亲手通过vscode插件开发以对我们朝夕相处的vscode进行能力增强,达到优化工作体验的目的。前一阵我做了一个vscode插件,名字叫做fe-file-rename,大家已经可以在插件商店搜索到,也专门为它写了一篇文章:我的第一次VS Code插件开发:fe-file-rename && 一些絮絮叨叨

fe-file-rename功能介绍:

  1. 批量修改文件名,支持下划线,连字符,大驼峰,小驼峰三种命名方式,并同步修改引用
  2. 当用户修改文件名或者修改文件路径时,自动将引用更新(有开关,可以关闭)

-暂时只支持vue项目-

我想这个vscode插件解决了我修改文件名或者文件路径,不知道去哪修改文件引用,怕错改,怕漏改的问题,大大提高了我的工作体验。

优化工作体验这种事情会上瘾的,最近我又开发了两个vscode插件,来对我的工作体验进行优化,我也会一步一步的引导大家,挖掘工作中的隐藏需求,之后将其实现。

当然,当你的插件出现在vscode插件商店,也是成就感满满🔥~


间奏🎵


创建一个属于你的vscode-extension


官方文档:code.visualstudio.com/api

安装vscode插件开发脚手架


npm install -g yo generator-code


输入yo code初始化代码


网络异常,图片无法展示
|


新建一个项目就这么简单,后续我就通过我最近的两次实践陪大家一起完成两个简单却实用的vscode插件吧🌟~


console,debugger一键删除术🎋


网络异常,图片无法展示
|


插件名:invalid-code-remover,欢迎搜索下载


下面的对话改编自现实工作:

无辜的寒草:“我提mr了,你给我合一下~”

暴躁的leader:“好...诶!你这怎么有console和debugger啊。”

无辜的寒草:“啊啊啊,漏删了”

暴躁的leader:“这种代码不要带到release上来,去删了!”

console和debugger在我们日常调试中经常用到,用的多了漏删了也是家常便饭,我们有很多办法去解决console这个问题:

  • 代码提交时校验
  • 编译时删除

我还没太接触过这两个东西,但是既然我们最好不要让consoledebugger出现在release分支(其实我也有强迫症,不太喜欢看到别人的console或者debugger),那么就需要一个手段去解决,去规避漏删consoledebugger的问题,那么我选择自己去解决,通过我的手段,我首先想到的就是通过vscode插件。


首先我想梳理一下思路:


  1. 右键选择文件或者目录
  2. 读取选择的文件或者目录的所有子文件
  3. 通过正则替换掉之中的console以及debugger
  4. 将处理完成的内容写入文件


好的,既然思路已经有了,那么我们现在开始:


"activationEvents": [
    "onCommand:invalid-code-remover.removeConsole",
    "onCommand:invalid-code-remover.removeDebugger"
  ],
  "main": "./dist/extension.js",
  "contributes": {
    "commands": [
      {
        "command": "invalid-code-remover.removeConsole",
        "title": "remove console"
      },
      {
        "command": "invalid-code-remover.removeDebugger",
        "title": "remove debugger"
      }
    ],
    "menus": {
      "explorer/context": [
        {
          "command": "invalid-code-remover.removeConsole",
          "when": "filesExplorerFocus",
          "group": "navigation@1"
        },
        {
          "command": "invalid-code-remover.removeDebugger",
          "when": "filesExplorerFocus",
          "group": "navigation@2"
        }
      ]
    }
  }


首先,看一看,我在package.json里面的配置项,首先我有两个指令:


  • invalid-code-remover.removeConsole  删除console
  • invalid-code-remover.removeDebugger  删除debugger


并把他们的触发条件设置为filesExplorerFocus,这样这两个指令对应的title就会出现在你右键点击文件或者目录时出现的菜单上。


网络异常,图片无法展示
|


之后我们看一下入口文件extension.ts的内容:


import * as vscode from 'vscode';
import { removeInvalidCodeEntry } from './handlers';
import { INVALID_TYPE_MAP } from './configs';
export function activate(context: vscode.ExtensionContext) {
    const removeConsole = vscode.commands.registerCommand('invalid-code-remover.removeConsole', (params) => {
        const isSuccess = removeInvalidCodeEntry(params.fsPath, INVALID_TYPE_MAP.get('CONSOLE'));
        if(isSuccess) {
          vscode.window.showInformationMessage('remove console success!');
        } else {
          vscode.window.showErrorMessage('remove console failed!');
        }
    });
  const removeDebugger = vscode.commands.registerCommand('invalid-code-remover.removeDebugger', (params) => {
        const isSuccess = removeInvalidCodeEntry(params.fsPath, INVALID_TYPE_MAP.get('DEBUGGER'));
        if(isSuccess) {
            vscode.window.showInformationMessage('remove debugger success!');
        } else {
          vscode.window.showErrorMessage('remove debugger failed!');
        }
     });
    context.subscriptions.push(...[removeConsole, removeDebugger]);
}
export function deactivate() {}


大家可以把activate理解为一个入口方法。


我通过vscode.commands.registerCommand把上面两个时间注册,并把params.fsPath作为参数,传给了我定义的方法removeInvalidCodeEntry,当然我同时还传了一个类型INVALID_TYPE_MAP.get('CONSOLE'),用去确定用户是想删除console还是想删除debugger


这里也给大家看看我定义的常量,用于确定操作类型和不必要参与删除consoledebugger操作的目录或者文件:


export const UN_MATCH = 0;
export const INVALID_TYPE_MAP = new Map([
    ['CONSOLE', 1],
    ['DEBUGGER', 2]
]);
export const EXCLUDE_DIR_NAME:Set<string> = new Set([
    'public',
    'dist',
    'node_modules',
    'docs',
    'test',
]);
export const EXCLUDE_FILE_EXTNAME:Set<string> = new Set([
    'css',
    'sass',
    'less',
    'md',
    'lock',
    'json',
    'yarnrc',
    'svg',
    'png',
    'gitignore',
    'vscodeignore',
    ''
]);


下面我们进入我的重头戏吧,我把我想讲的内容放在注释里:


import { UN_MATCH, INVALID_TYPE_MAP, EXCLUDE_DIR_NAME, EXCLUDE_FILE_EXTNAME } from '../configs';
import { lstatSync, readFileSync, writeFileSync, existsSync, readdirSync } from 'fs';
import { join, basename, extname } from 'path';
// 封装isDir方法,用于判断是目录还是文件
function isDir(path: string): boolean {
  const stat = lstatSync(path);
  return stat.isDirectory();
}
export function removeInvalidCodeEntry(path: string, type: number = UN_MATCH): boolean {
  // 如果传入的操作类型不在我接受的类型里,我直接return false;
  if (type === UN_MATCH) {
    return false;
  }
  // 如果传入文件路径不存在,我直接return false;
  if (!existsSync(path)) {
    return false;
  }
  // 异常处理,如果发生异常,我直接return false;
  try {
    if (isDir(path)) {
      // 上文常量中有的目录不需要处理
      if(EXCLUDE_DIR_NAME.has(basename(path))) {
        return true;
      }
      // 是目录的话,去获取其子文件,进行递归
      const files = readdirSync(path);
      files.forEach((file: any) => {
        const subPath = join(path, file);
        removeInvalidCodeEntry(subPath, type);
      });
    } else {
      // 如果该文件类型不需要处理,直接return
      if(EXCLUDE_FILE_EXTNAME.has(`.${extname(path)}`)) {
        return true;
      }
      const fileOptions = { encoding: 'utf-8' as BufferEncoding };
      const content = readFileSync(path, fileOptions);
      // 我采用读取文件之后逐行进行替换的方式,原因我在后续中会进行介绍
      const lines = content.split('\n');
      const handledLines = [];
      // 逐行删除console和debugger
      for (const line of lines) {
        let handledLine = '';
        switch (type) {
          case (INVALID_TYPE_MAP.get("CONSOLE")):
            handledLine = line.replace(/console\..*\(.*\)( )*;?/g, '');
            break;
          case (INVALID_TYPE_MAP.get("DEBUGGER")):
            handledLine = line.replace(/debugger( )*;?/g, '');
            break;
          default:
            handledLine = line;
            break;
        }
        if (handledLine === line || !/^( )*$/.test(handledLine)) {
          handledLines.push(handledLine);
        }
      }
      let handledContent = handledLines.join('\n');
      // 文件写入,当然如果文件没有发生变更,则不需要写入
      if (handledContent !== content) {
        writeFileSync(path, handledContent, fileOptions);
      }
    }
    return true;
  } catch(err) {
    return false;
  }
}


那么我们为什么会采用逐行进行遍历删除console或者debugger的操作呢?


我想多数工程师都会有代码强迫症,如果用了我的插件,之后consoledebugger删除了,却在那里留下了一个空行,岂不是十分的逼死强迫症。所以我使用逐行处理,如果替换后的行变成了空行,不进行push操作,这样就保持了原文件的格式。


下面我们看一下效果:


网络异常,图片无法展示
|

格式丝毫没有影响~完美✨~

大家赶快去下载吧🔥


配置属于你的代码段🎋


网络异常,图片无法展示
|


插件名:trantor-md-snippets,欢迎搜索下载


最近我一直在写公共组件的文档和系统重构的设计,里面有大量的公共格式,但是每次要去别的地方复制粘贴很不爽。


// 比如这种公共的表格
#### Attributes
| 参数 | 说明 | 类型 | 默认值 |
| ---- | ---- | ---- | ---- |
|  |  |  |  |
// 比如这种uml
@startuml
top to bottom direction
component 组件名 [
组件中文描述
组件名连字符表示
--props--
--events--
--methods--
--slots--
]
 子组件 ->  父组件
@enduml


所以我就想能不能借助vscode插件的代码段来解决这个问题,我简单的打两个字母,在按一个Tab,夸嚓,模板就出来了,我直接在上面写就好了~那么说干就干,为了我的工作幸福度,说干就干!


这次就比较简单了,我们先看package.json:


"categories": [
    "Snippets"
],
"contributes": {
    "snippets": [
        {
            "language": "markdown",
            "path": "./snippets.json"
        }
     ]
},


我限制这个插件只在markdown中生效。之后大家去看看我的snippets.json吧


{
"设计文档: 视图组件图": {
        "prefix": "Components",
    "body": [
            "@startuml",
            "top to bottom direction",
            "component ${1:组件名} [",
            "${2:组件中文描述}",
            "${3:组件名连字符表示}",
            "--props--",
            "$4",
            "--events--",
            "$5",
            "--methods--",
            "$6",
            "--slots--",
            "$7",
            "]", 
            "${8: 子组件} -> ${9: 父组件}",
            "@enduml"
    ],
    "description": "设计文档: 视图组件图"
    },
    ...
}


这里我只举了一个例子,当我输入Components的时候就会有这样的提示:


网络异常,图片无法展示
|


按下Tab,这个代码段就出来了:


网络异常,图片无法展示
|


当然如果安装了plantUML的话,可以直接试一下:


网络异常,图片无法展示
|


后续我也会给大家分享如何去做前端设计,敬请期待~

相关文章
|
2月前
|
iOS开发 MacOS
【Mac系统】解决Vscode中LeetCode插件不能刷剑指offer题库
文章讨论了解决Mac系统中Vscode里LeetCode插件无法刷剑指Offer题库的问题,并提供了一些相关的使用技巧和资源链接。
133 1
|
15天前
|
开发框架 .NET C#
VSCode开发.net项目时调试无效
【9月更文挑战第22天】在使用 VSCode 开发 .NET 项目时遇到调试问题,可从项目配置、调试配置、调试器安装、运行环境、日志和错误信息等方面排查。确认项目类型及文件配置,检查 `launch.json` 文件及配置项,确保调试器扩展已安装并启用,验证 .NET 运行时版本和环境变量,查看 VSCode 输出窗口和项目日志文件,检查权限及代码错误。若问题仍未解决,可查阅官方文档或社区论坛。
|
2月前
|
前端开发 Go
vscode10大常用插件
本文介绍了前端开发中常用的工具及VSCode必备插件。推荐使用VSCode作为入门工具,并介绍了WebStorm和HBuilder等其他选项。VSCode插件包括:Open-In-Browser、live-server、Beautify、Code Runner、Image Preview、Path Intellisense、Turbo Console Log、css-auto-prefix、Bracket Pair Colorizer 和 Auto Rename Tag,这些插件能够显著提升开发效率和代码质量。此外,还提供了录制Gif图的工具GifCam。
79 5
vscode10大常用插件
|
26天前
|
人工智能 C++ 开发者
verilog vscode 与AI 插件
【9月更文挑战第11天】在Verilog开发中,使用Visual Studio Code(VS Code)结合AI插件能显著提升效率。VS Code提供强大的编辑功能,如语法高亮、自动补全和代码格式化;便捷的调试功能,支持多种调试器;以及丰富的插件生态。AI插件则可自动生成代码、优化现有代码、检测并修复错误,还能自动生成文档。常用插件包括Verilog AI Assistant和Verilog Language Server,可根据需求选择合适的工具组合,提高开发效率和代码质量。
|
1月前
开发小技巧vscode
开发小技巧vscode
36 2
|
2月前
|
前端开发 IDE 开发工具
OpenSumi问题之OpenSumi 对于 VS Code 插件生态要如何支持
OpenSumi问题之OpenSumi 对于 VS Code 插件生态要如何支持
|
2月前
|
JSON 前端开发 JavaScript
这 2 个插件,让你的 vscode更牛逼
这 2 个插件,让你的 vscode更牛逼
|
2月前
vscode——Prettier插件保存自动格式化
vscode——Prettier插件保存自动格式化
52 0
|
2月前
|
JavaScript Linux iOS开发
【Mac系统】Vscode使用LeetCode插件报错‘leetcode.toggleLeetCodeCn‘ not found
在Mac系统下使用VSCode的LeetCode插件时遇到“leetcode.toggleleetcodecn”命令找不到的错误解决方法,主要是通过从Nodejs官网下载并安装最新版本的Node.js来解决环境配置问题。
148 0