Rumah > alat pembangunan > VSCode > teks badan

vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar)

青灯夜游
Lepaskan: 2021-12-24 18:28:43
ke hadapan
3355 orang telah melayarinya

Artikel ini berkongsi kaedah untuk membangunkan pemalam pintar untuk mengalih keluar pembolehubah yang tidak digunakan dalam vscode digabungkan dengan babel. Saya harap ia akan membantu semua orang!

vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar)

vscode telah menjadi salah satu alat pembangunan yang sangat diperlukan untuk bahagian hadapan. Sebab mengapa vscode digemari oleh pembangun, saya fikir ia mempunyai kaitan dengan "mahakuasa"nya. sistem pemalam. Di tempat kerja, kami boleh menggunakannya untuk membangunkan pemalam 工具型 tulen dan kami juga boleh menggunakannya untuk membangunkan beberapa pemalam berfungsi yang berkaitan dengan 业务相结合 syarikat. Di sini saya berkongsi pemalam babel pintar yang dilaksanakan dengan menggabungkan 移除未使用的变量 saya harap ia akan memberi inspirasi dan membantu semua orang membangunkan pemalam vscode. [Pembelajaran yang disyorkan: "tutorial pengenalan vscode"]

Teks

Hari ini kita akan membiasakan diri terlebih dahulu dengan proses pembinaan projek pemalam vscode

1. Mulakan projek menggunakan perancah rasmi

Pasang perancah

# npm 形式
npm install -g yo generator-code
# yarn 形式
yarn global add yo generator-code
Salin selepas log masuk

Jalankan perancah

# 运行脚手架
yo code
Salin selepas log masuk

Pilih templat, memandangkan sesetengah pembangun tidak berminat dengan saya tidak biasa dengan TypeScript, jadi kami memilih di siniNew 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
Salin selepas log masuk

Ini adalah struktur direktori hasil akhir kami

vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar)

Mari kita jalankan ini dahulu Cuba pemalam

vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar)

Klik butang jalankan di atas, tetingkap vscode baharu akan dibuka, tekan Ctrl Shift Pinput Hello World masuk tetingkap baharu, dan akan terdapat mesej di sudut kanan bawah tetingkap Anda akan melihat kotak gesaan yang menunjukkan bahawa pemalam vscode pertama kami telah berjaya dijalankan.

vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar)

2 Arahan tersuai, kekunci pintasan, menu

Banyak fungsi pemalam vscode dilaksanakan berdasarkan setiap arahan . Kita boleh menyesuaikan beberapa arahan Arahan ini akan muncul dalam senarai arahan selepas menekan Ctrl Shift P Pada masa yang sama, kita boleh mengkonfigurasi kekunci pintasan untuk arahan, mengkonfigurasi menu pengurus sumber, menu tajuk, menu lungsur. menu, dan ikon sudut kanan atas tunggu.

3. Cara menambah senarai arahan

konfigurasi separa pakej.json

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

Penggunaan kekunci pintasan ialah cara yang paling mudah dalam pembangunan, seterusnya kami mengubah suai konfigurasi supaya pemalam menyokong berjalan dengan kekunci pintasan.

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

Mari jalankan sekali lagi dan gunakan kekunci pintasan Ctrl 6 untuk melihat sama ada pemalam kami boleh berjalan seperti biasa. Ya, ia semudah itu pemalam kami sudah boleh menyokong berjalan sebagai kekunci pintasan.

4. Memanggil helloWorld terlalu norak Seterusnya, mari tukar nama arahan

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"
      }
    ]
  }
}
Salin selepas log masuk

Kerana kita. Nama arahan didaftarkan dalam extension.js, jadi ia mesti diubah suai serentak

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

5. Pasang babel perpustakaan berkaitan

Kod ubah suai kami boleh dibahagikan kepada 3 langkah

1. Parse kod ke dalam pokok sintaks AST 2. Lintas dan ubah suai pepohon sintaks AST 3. Hasilkan kod baharu berdasarkan pepohon sintaks AST yang diubah suai

Tiga langkah babel ini mempunyai perpustakaan yang sepadan untuk diproses

  • @babel/parserJana pepohon sintaks AST , alamat dokumen ( https://www.babeljs.cn/docs/babel-parser)

  • @babel/traverseLintas pepohon sintaks AST, alamat dokumen (https://www.babeljs .cn/ docs/babel-traverse)

  • @babel/generatorJana kod berdasarkan pepohon sintaks AST, alamat dokumen (https://www.babeljs.cn/docs/babel-generator)

  • @babel/typesPerpustakaan alat, alamat dokumen (https://www.babeljs.cn/docs/babel-types)

6. Mari kita lihat penggunaan asas perpustakaan ini, seperti melaksanakan fungsi yang menukar fungsi anak panah es6 kepada fungsi biasa

Sebelum penukaran

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

Selepas penukaran

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

Pelaksanaan kod, bahagian kod dikod keras untuk rujukan pembelajaran sahaja

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");
}
*/
Salin selepas log masuk

Ramai pelajar mesti ingin tahu bahawa ungkapan kami agak mudah sekarang, tetapi jika ia rumit, sarang definisi akan menjadi sangat mendalam Dan rumit, bagaimana kita harus tahu nod mana yang hendak diganti pada masa ini? . Malah, anda boleh menggunakan astexplorer.net/ iaitu tapak web untuk menukar AST dalam talian. Kita boleh membuka dua tetingkap, meletakkan kod sebelum penukaran ke tetingkap pertama, dan meletakkan antara muka yang perlu ditukar ke tetingkap kedua. Pada masa ini kami boleh membandingkan perbezaan sebelum dan selepas penukaran untuk melaksanakan kod kami.

vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar)

vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar)

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();
Salin selepas log masuk

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
  );
});
Salin selepas log masuk

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

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

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

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

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

vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar)

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

转换前

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

转换后

var a = 1;
console.log(a);
Salin selepas log masuk
  • 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);
Salin selepas log masuk

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);
Salin selepas log masuk

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"
      }
    ]
  }
}
Salin selepas log masuk

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

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

10、打包发布插件

打包我们可以vsce工具

全局安装 vsce

# npm
npm i vsce -g
# yarn
yarn global add vsce
Salin selepas log masuk

打包插件

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

vsce package
Salin selepas log masuk

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

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

vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar)

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

# 登录账号
vsce login your-publisher-name
# 发布
vsce publish
Salin selepas log masuk

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

vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar)

总结

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

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

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

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

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

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

Atas ialah kandungan terperinci vscode babel membangunkan pemalam yang secara bijak mengalih keluar pembolehubah yang tidak digunakan (pertempuran sebenar). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:juejin.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan