搜尋
首頁開發工具VSCodevscode+babel開發一個智慧型移除未使用變數的插件(實戰)

本篇文章分享一個在vscode中結合babel開發一個智慧移除未使用變數外掛程式的方法,希望對大家有幫助!

vscode+babel開發一個智慧型移除未使用變數的插件(實戰)

vscode 已成為前端不可缺少的開發工具之一,之所以vscode 能夠獲得開發者的青睞,我想和它「無所不能」的插件體係有很大一部分關係。在工作中我們能用它來開發純工具型的插件,也可以用它開發一些和公司業務相結合的功能插件。這裡我分享一個透過結合babel來實現一個能夠智慧移除未使用的變數插件,希望對大家開發 vscode 插件有一定的啟發和幫助。 【推薦學習:《vscode入門教學》】

正文

#今天我們先來熟悉vscode 外掛程式專案的建置流程

1.使用官方提供的鷹架初始化一個項目

安裝腳手架

# npm 形式
npm install -g yo generator-code
# yarn 形式
yarn global add yo generator-code

運行腳手架

# 运行脚手架
yo code

選擇模板,考慮到有些開發者對TypeScript 並不熟悉,所以我們在這裡選擇New Extension (JavaScript)

? What type of extension do you want to create? New Extension (JavaScript)
? What's the name of your extension? rm-unuse-var
? What's the identifier of your extension? rm-unuse-var
? What's the description of your extension? 移除未使用的变量
? Enable JavaScript type checking in 'jsconfig.json'? Yes
? Initialize a git repository? Yes
? Which package manager to use? yarn

這是我們最終生成的目錄結構

vscode+babel開發一個智慧型移除未使用變數的插件(實戰)

##我們先來運行一下這個插件試試

vscode+babel開發一個智慧型移除未使用變數的插件(實戰)

點擊上面運行按鈕,會打開一個新的vscode 窗口,在新窗口中按下

Ctrl Shift P輸入Hello World,在視窗右下角會看到一個提示框,說明我們第一個vscode 外掛程式運行成功運行了。

vscode+babel開發一個智慧型移除未使用變數的插件(實戰)

2、自訂指令、快速鍵、選單

vscode 許多功能都是基於一個個指令實現的,我們可以自訂一些指令,這個指令會出現在按下

Ctrl Shift P後的指令清單裡面,同時可以給指令設定快速鍵、設定資源管理器選單、編輯器選單、標題選單、下拉式選單、右上角圖示等。

3、如何新增指令清單

package.json 部分設定

{
  // 扩展的激活事件
  "activationEvents": ["onCommand:rm-unuse-var.helloWorld"],
  // 入口文件
  "main": "./extension.js",
  // 添加指令
  "contributes": {
    "commands": [
      {
        // 这里的值必须和activationEvents里面配置的一样
        "command": "rm-unuse-var.helloWorld",
        // 这个就是我们指令的名称,可以修改这里的值重新运行插件试试看
        "title": "Hello World"
      }
    ]
  }
}

在開發中快速鍵的使用方式是最便捷的,接下來我們修改一下配置,讓插件支援快捷鍵的方式運作。

{
  "contributes": {
    "commands": [
      {
        // 这里的值必须和activationEvents里面配置的一样
        "command": "rm-unuse-var.helloWorld",
        // 这个就是我们指令的名称,可以修改这里的值重新运行插件试试看
        "title": "Hello World"
      }
    ],
    // 快捷键绑定
    "keybindings": [
      {
        "command": "rm-unuse-var.helloWorld",
        "key": "ctrl+6",
        "mac": "cmd+6"
      }
    ]
  }
}

我們再重新運行一下,透過快捷鍵

Ctrl 6看看我們的外掛程式是否能夠正常運作。沒錯就是這麼簡單,我們的插件已經能夠支援快捷鍵的形式運作了。

4、叫helloWorld 太土了,下一步我們來修改指令的名稱

package.json

{
  "activationEvents": ["onCommand:rm-unuse-var.rm-js-var"],
  "main": "./extension.js",
  "contributes": {
    "commands": [
      {
        "command": "rm-unuse-var.rm-js-var",
        "title": "Hello World"
      }
    ],
    "keybindings": [
      {
        "command": "rm-unuse-var.rm-js-var",
        "key": "ctrl+6",
        "mac": "cmd+6"
      }
    ]
  }
}

因為我們在

extension.js中註冊了指令的名稱,所以也要同步修改

let disposable = vscode.commands.registerCommand(
  "rm-unuse-var.rm-js-var",
  function () {
    vscode.window.showInformationMessage("Hello World from rm-unuse-var!");
  }
);

#5、安裝babel相關函式庫

我們修改程式碼可以分為3 個步驟

1、將程式碼解析成AST 語法樹 2.遍歷修改 AST 語法樹 3.根據修改過的AST 語法樹產生新的程式碼

這3 個步驟babel 都有對應的函式庫來處理

  • @babel/parser 產生AST 語法樹,文件位址(https://www.babeljs.cn/docs/babel-parser)

  • ##@babel/traverse

    遍歷AST 語法樹,文件位址(https://www.babeljs.cn/docs/babel-traverse)

  • @babel/generator

    根據AST 語法樹生成程式碼,文件位址(https://www.babeljs.cn/docs/babel-generator)

  • #@babel/types

    工具庫,文件位址(https ://www.babeljs.cn/docs/babel-types)

#6、我們來看下這些函式庫的基本用法,例如實作一個將es6 的箭頭函數轉換成普通函數

轉換前

const say = () => {
  console.log("hello");
};

轉換後

function say() {
  console.log("hello");
}

程式碼實現,程式碼部分寫死僅供學習參考

const t = require("@babel/types");
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const generate = require("@babel/generator").default;
// 1、将代码解析成 AST 语法树
const ast = parser.parse(`const say = () => {
  console.log("hello");
};`);
// 2、遍历修改 AST 语法树
traverse(ast, {
  VariableDeclaration(path) {
    const { node } = path;
    // 写死找到第一个申明
    const declaration = node.declarations[0];
    // 定义的内容
    const init = declaration.init;
    // 判断是否是箭头函数
    if (t.isArrowFunctionExpression(init)) {
      // 将原来的表达式替换成新生成的函数
      path.replaceWith(
        t.functionDeclaration(
          declaration.id,
          init.params,
          init.body,
          init.generator,
          init.async
        )
      );
    }
  },
});
// 3、根据修改过的 AST 语法树生成新的代码
console.log(generate(ast).code);
/*
function say() {
  console.log("hello");
}
*/

很多同學一定好奇現在我們的表達式比較簡單還好,如果複雜的話定義巢狀會非常深複雜,這個時候該怎麼知道要替換哪個節點? 。其實這裡可以藉助

astexplorer.net/

這是一個線上轉換 AST 的網站。我們可以打開兩個窗口,把轉換前的程式碼放到第一個窗口,把需要轉換的介面放到第二個窗口。這時候我們就可以比較一下轉換前後的差異,來實現我們的程式碼了。

vscode+babel開發一個智慧型移除未使用變數的插件(實戰)

vscode+babel開發一個智慧型移除未使用變數的插件(實戰)

6、思考插件如何实现?

1、获取编辑器当前打开的 js 文件的代码 2、将代码解析成 AST 语法树 3、遍历 AST 语法树,删除未使用的定义 4、根据修改过的 AST 语法树生成新的代码 5、替换当前 js 文件的代码

其中 2、4 我们已经会了,接下来只需要看下 1、3、5 如何实现就行

1 和 5 我们可以通过 vscode 提供的方法

1、获取编辑器当前打开的 js 文件的代码

import * as vscode from "vscode";
// 当前打开的文件
const { activeTextEditor } = vscode.window;
// 然后通过document下的getText就能轻松获取到我们的代码了
const code = activeTextEditor.document.getText();

5、替换当前 js 文件的代码

activeTextEditor.edit((editBuilder) => {
  editBuilder.replace(
    // 因为我们要全文件替换,所以我们需要定义一个从头到位的区间
    new vscode.Range(
      new vscode.Position(0, 0),
      new vscode.Position(activeTextEditor.document.lineCount + 1, 0)
    ),
    // 我们的新代码
    generate(ast).code
  );
});

好了接下来我们就剩核心的第 3 步了。

3、遍历 AST 语法树,删除未使用的定义

我们先来分析一下,未使用的定义包含了哪些?

import vue from "vue";
const a = { test1: 1, test2: 2 };
const { test1, test2 } = a;
function b() {}
let c = () => {};
var d = () => {};

然后在线 ast 转换网站,复制这些内容进去看看生成的语法树结构

vscode+babel開發一個智慧型移除未使用變數的插件(實戰)

我们先来实现一个例子吧,比如把下面代码中没有用的变量移除掉

转换前

var a = 1;
var b = 2;
console.log(a);

转换后

var a = 1;
console.log(a);
  • scope.getBinding(name) 获取当前所有绑定
  • scope.getBinding(name).referenced 绑定是否被引用
  • scope.getBinding(name).constantViolations 获取当前所有绑定修改
  • scope.getBinding(name).referencePaths 获取当前所有绑定路径

代码实现

const t = require("@babel/types");
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const generate = require("@babel/generator").default;

const ast = parser.parse(`var a = 1;
var b = 2;
console.log(a);`);

traverse(ast, {
  VariableDeclaration(path) {
    const { node } = path;
    const { declarations } = node;
    // 此处便利可以处理 const a = 1,b = 2; 这种场景
    node.declarations = declarations.filter((declaration) => {
      const { id } = declaration;
      // const { b, c } = a;
      if (t.isObjectPattern(id)) {
        // path.scope.getBinding(name).referenced 判断变量是否被引用
        // 通过filter移除掉没有使用的变量
        id.properties = id.properties.filter((property) => {
          const binding = path.scope.getBinding(property.key.name);
          return !!binding?.referenced;
        });
        // 如果对象中所有变量都没有被应用,则该对象整个移除
        return id.properties.length > 0;
      } else {
        // const a = 1;
        const binding = path.scope.getBinding(id.name);
        return !!binding?.referenced;
      }
    });
    // 如果整个定义语句都没有被引用则整个移除
    if (node.declarations.length === 0) {
      path.remove();
    }
  },
});
console.log(generate(ast).code);

7、了解基本处理流程之后,我们就来看下最终的代码实现吧

const t = require("@babel/types");
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const generate = require("@babel/generator").default;

const ast = parser.parse(
  `import vue from 'vue';
  var a = 1;
var b = 2;
var { test1, test2 } = { test1: 1, test2: 2 };
function c(){}
function d(){}
d();
console.log(a, test1);`,
  {
    sourceType: "module",
  }
);

traverse(ast, {
  // 处理 const var let
  VariableDeclaration(path) {
    const { node } = path;
    const { declarations } = node;

    node.declarations = declarations.filter((declaration) => {
      const { id } = declaration;
      if (t.isObjectPattern(id)) {
        id.properties = id.properties.filter((property) => {
          const binding = path.scope.getBinding(property.key.name);
          return !!binding?.referenced;
        });
        return id.properties.length > 0;
      } else {
        const binding = path.scope.getBinding(id.name);
        return !!binding?.referenced;
      }
    });

    if (node.declarations.length === 0) {
      path.remove();
    }
  },
  // 处理 import
  ImportDeclaration(path) {
    const { node } = path;
    const { specifiers } = node;
    if (!specifiers.length) {
      return;
    }
    node.specifiers = specifiers.filter((specifier) => {
      const { local } = specifier;
      const binding = path.scope.getBinding(local.name);
      return !!binding?.referenced;
    });
    if (node.specifiers.length === 0) {
      path.remove();
    }
  },
  // 处理 function
  FunctionDeclaration(path) {
    const { node } = path;
    const { id } = node;
    const binding = path.scope.getBinding(id.name);
    if (!binding?.referenced) {
      path.remove();
    }
  },
});
console.log(generate(ast).code);

8、vscode 设置我们的插件只支持 js 文件的限制

因为我们现在实现是针对 js 文件的,所以打开其他类型的文件我们可以让我们的快捷键失效。 我们可以修改package.jsonpackage.json

{
  "contributes": {
    "commands": [
      {
        "command": "rm-unuse-var.remove",
        "title": "Hello World"
      }
    ],
    "keybindings": [
      {
        "command": "rm-unuse-var.remove",
        "key": "ctrl+6",
        "mac": "cmd+6",
        "when": "resourceLangId == javascript"
      }
    ]
  }
}

9、整合到我们前面创建的项目中去

此处省略... 相信看了上面这些介绍大家已经完全有能力自己整合了

10、打包发布插件

打包我们可以vsce工具

全局安装 vsce

# npm
npm i vsce -g
# yarn
yarn global add vsce

打包插件

打包前先修改 README.md 文件否则会报错

vsce package

执行完毕之后会生成一个.vsix 文件

如果要在本地 vscode 使用可以直接导入

vscode+babel開發一個智慧型移除未使用變數的插件(實戰)

如果要发布到市场的话,我们需要先注册账号 https://code.visualstudio.com/api/working-with-extensions/publishing-extension#publishing-extensions

# 登录账号
vsce login your-publisher-name
# 发布
vsce publish

发布成功之后就能在我们的市场上看到了 marketplace.visualstudio.com/items?itemN… 也可以在 vscode 中搜索打我们的插件

vscode+babel開發一個智慧型移除未使用變數的插件(實戰)

总结

到此为止,相信大家对 vscode 插件开发的基本流程已经有了了解。

觉得文章对你有所帮助,可以点个赞 

当然 vscode 插件还有非常多的配置没有介绍,后面如果有时间可以单独整理成一篇文章来介绍

如果在开发过程中有问题或者其他前端技术问题也可以加我微信rjjs1221交流,或者直接在评论区回复。

源码地址 https://github.com/taoxhsmile/rm-unuse-var

更多关于VSCode的相关知识,请访问:vscode教程!!

以上是vscode+babel開發一個智慧型移除未使用變數的插件(實戰)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金社区。如有侵權,請聯絡admin@php.cn刪除
Visual Studio的價值:權衡成本與其收益Visual Studio的價值:權衡成本與其收益Apr 12, 2025 am 12:06 AM

VisualStudio在.NET开发中价值高,因其功能强大且全面。尽管成本和资源消耗较高,但其带来的效率提升和开发体验改善显著。对于个人开发者和小型团队,Community版是理想选择;大型企业则适合Professional或Enterprise版。

Visual Studio的可用性:哪些版本是免費的?Visual Studio的可用性:哪些版本是免費的?Apr 10, 2025 am 09:44 AM

VisualStudio的免費版本包括VisualStudioCommunity和VisualStudioCode。 1.VisualStudioCommunity適用於個人開發者、開源項目和小型團隊,功能強大,適合個人項目和學習編程。 2.VisualStudioCode是一個輕量級的代碼編輯器,支持多種編程語言和擴展,啟動速度快,資源佔用少,適合需要靈活性和可擴展性的開發者。

如何為Windows 8安裝Visual Studio?如何為Windows 8安裝Visual Studio?Apr 09, 2025 am 12:19 AM

在Windows8上安裝VisualStudio的步驟如下:1.從微軟官方網站下載VisualStudioCommunity2019安裝包。 2.運行安裝程序並選擇所需組件。 3.完成安裝後即可使用。注意選擇與Windows8兼容的組件,並確保有足夠的磁盤空間和管理員權限。

我的計算機可以運行與代碼嗎?我的計算機可以運行與代碼嗎?Apr 08, 2025 am 12:16 AM

VSCode可以在大多數現代電腦上運行,只要滿足基本系統要求:1.操作系統:Windows7及以上,macOS10.9及以上,Linux;2.處理器:1.6GHz或更快;3.內存:至少2GBRAM(推薦4GB或更高);4.存儲空間:至少200MB可用空間。通過優化設置和減少擴展使用,可以在低配置電腦上獲得流暢的使用體驗。

如何使程序與Windows 8兼容?如何使程序與Windows 8兼容?Apr 07, 2025 am 12:09 AM

要讓程序在Windows8上順暢運行,需採取以下步驟:1.使用兼容性模式,通過代碼檢測並啟用該模式。 2.調整API調用,根據Windows版本選擇適當的API。 3.進行性能優化,盡量避免使用兼容性模式,優化API調用並使用通用控件。

VS代碼在Windows 8上有效嗎?VS代碼在Windows 8上有效嗎?Apr 06, 2025 am 12:13 AM

Yes,VSCodeiscompatiblewithWindows8.1)DownloadtheinstallerfromtheVSCodewebsiteandensurethelatest.NETFrameworkisinstalled.2)Installextensionsusingthecommandline,notingsomemayloadslower.3)Manageperformancebyclosingunnecessaryextensions,usinglightweightt

VS代碼和Visual Studio有什麼區別?VS代碼和Visual Studio有什麼區別?Apr 05, 2025 am 12:07 AM

VSCode是輕量級代碼編輯器,適用於多種語言和擴展;VisualStudio是功能強大的IDE,主要用於.NET開發。 1.VSCode基於Electron,支持跨平台,使用Monaco編輯器。 2.VisualStudio使用微軟自主技術棧,集成調試和編譯器。 3.VSCode適合簡單任務,VisualStudio適合大型項目。

哪個代碼編輯器可以在Windows 7上運行?哪個代碼編輯器可以在Windows 7上運行?Apr 03, 2025 am 12:01 AM

在Windows7上可以運行的代碼編輯器有Notepad 、SublimeText和Atom。 1.Notepad :輕量級,啟動快,適合老系統。 2.SublimeText:功能強大,需付費。 3.Atom:可定制性強,但啟動慢。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器