背景
想必每个纯熟的前端弄潮者
,在纯熟业务之后,经常都会将组件进行抽离公共组件,能够大大的进步开发效率。然而抽离公共组件之后,日常的开发便是创立雷同的文件夹,批改router
,批改表单的属性 fields
和 prop
等,反复的创立雷同的文件夹,反复批改文件 name
, 反复的写 router
等,然而作为组内不同的人员,格调又不统一,所以能不能即标准代码的格调,又能疾速的创立模板呢。
比方咱们常见的模板类型
├─componentsName│ ├─api│ │ index.js│ ├─components│ │ list-table.vue│ │ list-search.vue│ │ index.js│ ├─config│ │ index.js│ index.vue│ route.js
vscode插件
通过 官网文档 的学习,咱们能够发现 vscode
插件扩大的形式,去实现这个性能。
- 环境装置
npm i -g yo generator-code // 官网插件开发脚手架yo code // 执行脚手架命令
依据步骤咱们抉择创立 New Extension
能够抉择本人喜爱的语言 Javascript
或者 TypeScript
, 这边笔者选的是 JavaScript
同样,咱们从国际惯例的 Hello World
开始,抉择好相应的配置
我的项目构造
我的项目构造比较简单,次要的文件为 package.json
和 extension.js
这两个文件
{ "name": "hello-world", // 插件名称 "displayName": "Hello World", "description": "hello world", "version": "0.0.1", // 插件版本 "engines": { "vscode": "^1.63.0" // vscode的版本 }, "categories": [ "Other" ], // 扩大的激活事件 "activationEvents": [ "onCommand:hello-world.helloWorld" ], // 入口文件 "main": "./extension.js", // vscode插件大部分性能配置都在这里配置 "contributes": { "commands": [ { "command": "hello-world.helloWorld", "title": "Hello World" } ] }, "scripts": { "lint": "eslint .", "pretest": "npm run lint", "test": "node ./test/runTest.js" }, "devDependencies": { "@types/vscode": "^1.63.0", "@types/glob": "^7.1.4", "@types/mocha": "^9.0.0", "@types/node": "14.x", "eslint": "^7.32.0", "glob": "^7.1.7", "mocha": "^9.1.1", "typescript": "^4.4.3", "@vscode/test-electron": "^1.6.2" }}
extension.js
文件内容如下
// The module 'vscode' contains the VS Code extensibility API// Import the module and reference it with the alias vscode in your code belowconst vscode = require('vscode');// this method is called when your extension is activated// your extension is activated the very first time the command is executed/** * @param {vscode.ExtensionContext} context */function activate(context) { // Use the console to output diagnostic information (console.log) and errors (console.error) // This line of code will only be executed once when your extension is activated console.log('Congratulations, your extension "hello-world" is now active!'); // The command has been defined in the package.json file // Now provide the implementation of the command with registerCommand // The commandId parameter must match the command field in package.json let disposable = vscode.commands.registerCommand('hello-world.helloWorld', function () { // The code you place here will be executed every time your command is executed // Display a message box to the user vscode.window.showInformationMessage('Hello World from Hello World!'); }); context.subscriptions.push(disposable);}// this method is called when your extension is deactivatedfunction deactivate() {}module.exports = { activate, deactivate}
1. 了解
main
定义了整个插件的主入口,所以看到这里,依照咱们的惯性,能够新建src
文件夹,将extension.js
已到src
文件夹上面。contributes.commands
注册了名为hello-world.helloWorld
的命令,并在src/extension.js
实现。- 定义完命令之后,还须要在
activationEvents
上增加onCommand:hello-world.helloWorld
。
2. 运行调试
新建实现之后,工程曾经帮咱们配置好调试参数
咱们只须要点击 Run Extension
即可,此时将关上一个新的vscode
窗口,显示Extension Development Host
此时咱们按下快捷键 command + shift + P
,输出 Hello
即可看到咱们编写的插件了,选中咱们的插件,即可发现右下角的弹窗 Hello World from Hello World!
3. 增加快捷键和右键菜单
在咱们的 package.json
中,增加如下代码
"contributes": { "commands": [ { "command": "hello-world.helloWorld", "title": "Hello World" } ], "keybindings": [ { "command": "hello-world.helloWorld", "key": "ctrl+f10", "mac": "cmd+f10", "when": "editorFocus" } ], "menus": { "explorer/context": [ { "command": "hello-world.helloWorld", "group": "navigation", // 菜单位于最下面 "when": "explorerResourceIsFolder" // 只有是文件夹时能力唤起菜单 } ] } },
在文件夹区域右键,即可看到咱们的菜单命令了, 同时也能够看到快捷键。
至此,咱们曾经实现了一个简略的 vscode
插件。
4. 革新
批改文件目录如下
├─node_modules├─src│ main.js├─test│ .eslintrc.json│ .gitignore│ .vscodeignore│ jsconfig.json│ package-lock.json│ package.json│ READEME.md│ vsc-extension-quickstart.md
批改 package.json
文件
{ "name": "hello-template", "displayName": "hello-template", "description": "hello world", "publisher": "retrychx", "version": "0.0.1", "engines": { "vscode": "^1.63.0" }, "categories": [ "Other" ], "activationEvents": [ "onCommand:hello-template" ], "main": "./src/main.js", "contributes": { "commands": [ { "command": "hello-template", "title": "Hello Template" } ], "keybindings": [ { "command": "hello-template", "key": "ctrl+f10", "mac": "cmd+f10", "when": "editorFocus" } ], "menus": { "explorer/context": [ { "command": "hello-template", "group": "navigation", "when": "explorerResourceIsFolder" } ] } }, "scripts": { "lint": "eslint .", "pretest": "npm run lint", "test": "node ./test/runTest.js" }, "devDependencies": { "@types/vscode": "^1.63.0", "@types/glob": "^7.1.4", "@types/mocha": "^9.0.0", "@types/node": "14.x", "eslint": "^7.32.0", "glob": "^7.1.7", "mocha": "^9.1.1", "typescript": "^4.4.3", "@vscode/test-electron": "^1.6.2" }}
批改 src/main.js
文件
// The module 'vscode' contains the VS Code extensibility API// Import the module and reference it with the alias vscode in your code belowconst vscode = require('vscode');// this method is called when your extension is activated// your extension is activated the very first time the command is executed/** * @param {vscode.ExtensionContext} context */function activate(context) { // Use the console to output diagnostic information (console.log) and errors (console.error) // This line of code will only be executed once when your extension is activated console.log('Congratulations, your extension "hello-world" is now active!'); // The command has been defined in the package.json file // Now provide the implementation of the command with registerCommand // The commandId parameter must match the command field in package.json let disposable = vscode.commands.registerCommand('hello-template', function () { // The code you place here will be executed every time your command is executed // Display a message box to the user vscode.window.showInformationMessage('test'); }); context.subscriptions.push(disposable);}// this method is called when your extension is deactivatedfunction deactivate() {}module.exports = { activate, deactivate}
在 registerCommand
办法处,批改命令,和 package.json
中的 command
中保持一致,而后调试运行咱们的 vscode
,快捷键号召出咱们的插件,能够看到咱们的插件名称 Hello Template
,点击,即可看到跳出的弹窗
5. 新建模板字符串
在 src/
上面,咱们新建 template.js
文件,在外面申明咱们要新建的模板。
route.js
模板
因为须要路由名称和题目两个变量,所以申明了两个变量
const routeTemplate = params => `import List from './index'export default [ { path: '${params.path}', name: '${params.path}', meta: { title: '${params.title}' }, component: List }]`
index.js
入口文件模板
const indexTemplate = `<template> <div></div></template><script>import { ListSearch, ListTable } from './components'import * as API from './api/index'import utils from '@/utils'export default { components: { ListSearch, ListTable }, data() { return { }, } }, mounted() { }, methods: { },}</script><style></style>`
依据封装的组件,所以能够顺次新建不同的模板:configTemplate
、apiTemplate
、comIndexTemplate
、searchTemplate
、tableTemplate
等,导出咱们须要的模板
const config = { routeTemplate: routeTemplate, indexTemplate: indexTemplate, configTemplate: configTemplate, apiTemplate: apiTemplate, comIndexTemplate: comIndexTemplate, searchTemplate: searchTemplate, tableTemplate: tableTemplate}module.exports = config
6. 引入用户变量
因为咱们须要异步解决,所以引入async
let disposable = vscode.commands.registerCommand('hello-template', async url => { // 设置输入框提醒 const options = { prompt: '请输出模板名称', placeHolder: '模板名称' } // 输出模板名称 const templateName = await vscode.window.showInputBox(options) // 设置题目 const optionsTitle = { prompt: '请输出题目名称', placeHolder: '题目名称' } // 输出模板名称 const templateTitle = await vscode.window.showInputBox(optionsTitle) // 设置门路 const optionsRoute = { prompt: '请输出门路名称', placeHolder: '门路名称' } // 输出门路名称 const templateRoute = await vscode.window.showInputBox(optionsRoute) const params = { path: templateRoute, title: templateTitle } });
运行调试,咱们能够看到调用咱们的插件,能够看到呈现了输入框:
通过输出名称,咱们能够拿到本人想要的变量。而后咱们就能够调用 fs
和 path
两个模块就能够写咱们本人的文件了。
因为为了保障,咱们的创立文件和文件夹的程序。
首先咱们用了 existsSync
和 mkdirSync
来创立文件夹;而后咱们再用 existsSync
和 writeFileSync
来创立文件,而后再最初,做个胜利的提醒即可:
vscode.window.showInformationMessage('模板创立胜利')
至此,咱们曾经实现了所有的编码。那么咱们就看一下最初的调试后果。
在文件夹处右键,号召出咱们的插件指令Hello Template
输出对应的名称之后,咱们能够看到在右键的文件夹下,创立了咱们想要的模板。
咱们就能够节俭很多反复的工作了。
7. 引入新性能
因为在开发过程中,后端给的开发文档,提供的接口都是来自mock
的连贯,这个时候就在想能不能解析mock
的接口数据主动引入接口正文。
const request = require('request')const YAPIURL = 'https://mock.shizhuang-inc.com/api/interface/get'const param = 'token' // 集体的tokenfunction getYapi(id) { const url = `${YAPIURL}?id=${id}&token=${param}` return new Promise(async (resolve, reject) => { request(url, function(error, response,body) { debugger if(error) { reject(error) } const bodyToJson = JSON.parse(body) // 接口id不存在 if(!bodyToJson.data) { reject(null) } resolve({ title: bodyToJson.data.title, path: bodyToJson.data.path }) }) })}module.exports = { getYapi}
- 增加右键菜单
在package.json
外面
"menus": { "editor/context": [ { "when": "resourceLangId == javascript", // 当文件为js文件的时候 "command": "erp-addInterface", "group": "navigation" } ] }
在main.js
中,注册command
事件
let addDisposable = vscode.commands.registerCommand('erp-addInterface', async url => { // 设置输入框提醒 const options = { prompt: '请输出接口Id', placeHolder: '接口Id' } // 输出门路名称 const apiTag = await vscode.window.showInputBox(options) if(!+apiTag) { vscode.window.showInformationMessage('输出正确的接口Id') return } try { const res = await api.getYapi(+apiTag) const apiName = res.path ? res.path.split('/').pop() : '' res.name = apiName const interfaceTemplate = config.interfaceTemplate(res) await fs.appendFileSync(url.path, interfaceTemplate, 'utf8') vscode.window.showInformationMessage('接口增加胜利') } catch (error) { if(!error) { vscode.window.showInformationMessage('接口Id不存在') return } vscode.window.showInformationMessage(error) }
- 查看成果
能够生成正文和接口,方便快捷。
打包
无论是本地打包还是公布到利用市场,咱们都要借助vsce
这个工具。
1. 装置
npm install vsce -g
2. 打包
打包成 vsix
文件
vsce package
发现报错如下:
谬误指出咱们要批改 README.md
文件,咱们批改以下文件,再次执行打包。
依照批示命令,一步步的执行,打包胜利,看一下咱们的我的项目目录,能够看到咱们的打包文件。
3. 公布
关上公布市场 官方网站 , 创立本人的公布账号,而后记录下本人的集体 token
, 即可开始公布。
vsce publish
输出本人的账号,和 token
之后就能够公布了。期待几分钟后就能够在网页看到本人的我的项目
例如笔者公布的插件 erp-template
,在插件市场搜寻能够看到,咱们本人的插件了
好了,至此,vscode
插件开发曾经实现了。
总结
这里仅仅是想到的一个开发场景,相对来说,只是提供一个开发思路,在开发过程中,能够多进行思考,做一些乏味的事件。
文/migor
关注得物技术,做最潮技术人!