background

Presumably every skilled front-end trendsetter, after skilled business, often will be components out of the common components, can greatly improve the efficiency of development. However, after the removal of common components, the daily development is to create the same folder, modify the router, modify the form properties fields and prop, repeatedly create the same folder, repeatedly modify the file name, repeatedly write router, etc., but as different people in the group, the style is not consistent. So can we not only standardize the code style, but also quickly create templates.

For example, we have common template types

├ ─ componentsName │ ├ ─ API │ │ index. The js │ ├ ─ components │ │ list - table. Vue │ │ list - search. Vue │ │ index. The js │ ├ ─ config │ │ Index.js │ index.vue │ route.jsCopy the code

Vscode plug-in

Through the study of official documentation, we can find the way of vscode plug-in extension, to achieve this function.

  • Environmental installation
NPM I -g yo generator-codeCopy the code

Following the steps we chose to create a New Extension

You can choose your preferred language, Javascript, or TypeScript

Again, let’s start with the international convention Hello World and select the appropriate configuration

The project structure

The project structure is relatively simple, and the main files are package.json and extension.js

{"name": "hello-world", // Plugin name" displayName": "hello world", "description": "hello world", "version": "/ / plug-in version 0.0.1", "engines" : {" vscode ":" ^ 1.63.0 "/ / vscode version}," category ": ["Other"], // extended activationEvents" activationEvents": ["onCommand: hello-world.helloworld "], // entry file "main": "./extension.js", // vscode add-ons most of the functionality configuration is contributed here "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", "the glob" : "^ 7.1.7", "mocha" : "^ 9.1.1 typescript", ""," ^ 4.4.3 ", "@ vscode/test - electron" : "^ 1.6.2"}}Copy the code

The extension.js file contains the following contents

// The module 'vscode' contains the VS Code extensibility API // Import the module and reference it with the alias vscode in your code below const 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 deactivated function deactivate() {} module.exports = { activate, deactivate }Copy the code

1. Understand

  • Main defines the main entry for the entire plugin, so if we look at this, we can create a new SRC folder and place extension.js under the SRC folder.

  • Contributes.contributes.mands registers a command called hello-world.helloworld and implements it in SRC/extend.js.

  • Once you have defined the command, you also need to add onCommand:hello-world.helloWorld to activationEvents.

2. Run debugging

After the completion of the new construction, the project has helped us to configure the debugging parameters

All we need to do is click on Run Extension and a new vscode window will open showing the Extension Development Host

Now press the shortcut key command + Shift + P, enter Hello to see the plug-in we wrote, select our plug-in, you can find the lower right corner of the popup window Hello World from Hello World!

3. Add shortcut keys and right-click menus

In our package.json, add the following code

"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": "helloWorld. HelloWorld ", "group": "navigation", // menu is on top "when": "ExplorerResourceIsFolder" // can only invoke the menu if it is a folder}]}},Copy the code

Right click in the folder area to see our menu commands, as well as the shortcut keys.

At this point, we have completed a simple vscode plug-in.

4. The transformation

Modify the file directory as follows

├─ Node_modules ├─ SRC │ ├─test │ ├.eslintrc.json │ ├.gitignore │.vscodeignore │ jsconfig.json │ package-lock.json │ package.json │ READEME. Md │ vsc-extends-quickstart. mdCopy the code

Modify the package.json file

{ "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", "the glob" : "^ 7.1.7" and "mocha", "^ 9.1.1", "typescript" : "^ 4.4.3", "@ vscode/test - electron" : "^ 1.6.2"}}Copy the code

Modify the SRC /main.js file

// The module 'vscode' contains the VS Code extensibility API // Import the module and reference it with the alias vscode in your code below const 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 deactivated function deactivate() {} module.exports = { activate, deactivate }Copy the code

In the registerCommand method, change the command to be the same as the command in package.json, and then debug our vscode. You can see the popover that jumps out

5. Create a template string

Under SRC /, we create a new template.js file that declares the template we want to create.

  • route.jsThe template

Because you need the route name and title variables, you declare two variables

const routeTemplate = params => 
`
import List from './index'

export default [
  {
    path: '${params.path}',
    name: '${params.path}',
    meta: {
      title: '${params.title}'
    },
    component: List
  }
]
`
Copy the code
  • index.jsImport file template
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>
`
Copy the code

Depending on the component, we can create different templates in turn: configTemplate, apiTemplate, comIndexTemplate, searchTemplate, tableTemplate, and so on to export the template we need

const config = {
  routeTemplate: routeTemplate,
  indexTemplate: indexTemplate,
  configTemplate: configTemplate,
  apiTemplate: apiTemplate,
  comIndexTemplate: comIndexTemplate,
  searchTemplate: searchTemplate,
  tableTemplate: tableTemplate
}

module.exports = config
Copy the code

6. Introduce user variables

Since we need asynchronous processing, async is introduced

Let the disposable = vscode.com mands. RegisterCommand (' hello - template, async url = > {/ / set the input box prompts const options = {prompt: 'Please enter template name ', placeHolder: 'template name} / / input template name const templateName = await vscode. Window. ShowInputBox (options) / / set the title const optionsTitle = {prompt: 'Please enter title name ', placeHolder: 'title'} / / input template name const templateTitle = await vscode. Window. ShowInputBox (optionsTitle) / / set the path const optionsRoute = { Prompt: 'Please enter path name ', placeHolder: 'path name} / / input path name const templateRoute = await vscode. Window. ShowInputBox (optionsRoute) const params = {path: templateRoute, title: templateTitle } });Copy the code

Running the debug, we can see that our plug-in is called and we can see that the input box appears:

By typing the name, we can get the variable we want. Then we can call the fs and PATH modules to write our own files.

Because in order to ensure that we create files and folders in the order.

First we use existsSync and mkdirSync to create folders; We then create the file using existsSync and writeFileSync, and finally, a success prompt:

Vscode. Window. ShowInformationMessage (' template to create successful)Copy the code

At this point, we’ve done all the coding. So let’s look at the final debugging result.

Right click on the folder to summon our plug-in directive Hello Template

After entering the corresponding name, we can see that in the right folder, we have created the template we want.

We can save a lot of rework.

7. Introduce new features

Since the interface provided by the backend to the development document is the connection from the mock during development, it is wondered whether the interface data parsing the mock can automatically introduce interface comments.

const request = require('request') const YAPIURL = 'https://mock.shizhuang-inc.com/api/interface/get' const param = Function getYapi(id) {const url = '${YAPIURL}? Id =${id}&token=${param}' return new Promise(async) (resolve, reject) => { request(url, function(error, Parse (body) // The interface id does not exist if(! bodyToJson.data) { reject(null) } resolve({ title: bodyToJson.data.title, path: bodyToJson.data.path }) }) }) } module.exports = { getYapi }Copy the code
  • Add right-click menu

In the package. The json

"Menus ": {"editor/context": [{"when": "resourceLangId == javascript", // When the file is js file "command": "erp-addInterface", "group": "navigation" } ] }Copy the code

In main.js, register the Command event

let addDisposable = vscode.commands.registerCommand('erp-addInterface', Async URL => {const options = {prompt: 'Please input interface Id', placeHolder: placeHolder 'the interface Id} / / input path name const apiTag = await vscode. Window. ShowInputBox (options) if (! + apiTag) {vscode. Window. ShowInformationMessage (' input the correct interface 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 (' interface to add success')} the catch (error) {if (! The error) {vscode. Window. ShowInformationMessage (' interface Id does not exist) return} vscode. Window. ShowInformationMessage (error)}Copy the code
  • See the effect

Comments and interfaces can be generated quickly and easily.

packaging

Whether it’s native packaging or publishing to the app market, we use VSCE as a tool.

1. Install

npm install vsce -g
Copy the code

Pack 2.

Package as a VSIX file

vsce package
Copy the code

The error is as follows:

The error indicates that we want to modify the readme. md file. We modify the following file and perform packaging again.

Follow the instructions and execute step by step to package successfully. Take a look at our project directory and you can see our package file.

Release 3.

Open the official website of the publishing market, create your own publishing account, and then record your own personal token to start publishing.

vsce publish
Copy the code

After entering your account number and token, you can publish. Wait a few minutes and see your project on the page

For example, the author published the plug-in ERP-template, in the plug-in market search, you can see our own plug-in

Ok, so vscode plug-in development is now complete.

conclusion

Here is just a thought of a development scenario, relatively speaking, just provide a development idea, in the development process, you can think more, do some interesting things.

The text/migor

Pay attention to the technology, do the most fashionable technology!