Small knowledge, big challenge! This article is participating in the creation activity of essential knowledge for programmers. This article also participates in the “Diggin Star Project” to win the creation gift package and challenge the creation incentive money

preface

Hi, I’m Brother Fly. Recently, when I was working on a project, the drawing given by the product manager was always large and uncompressed. It’s really tiring to deal with these pictures every day. I wrote this ** “vscode plugin” in a fit of anger. “The core function of the plug-in is to compress and then upload the image.” The compressed website is actually “tinypng” ** this website and then the image is compressed, and then uploaded to the CDN, and then the compressed URL is placed directly on our paste board. Now follow my steps to write and implement it step by step. First look at the renderings:

Demonstrate the GIF figure

The efficiency of contrast

The main purpose of this development is to improve the efficiency of team development, not to show off skills. Look at the picture:

image-20211017224316386

Demand analysis

  1. Parameters required for uploading can be configured in vSCOdDE setting, which can be individually configured according to individual requirements.
  2. 2. During the development process, you can directly select the image in the editor and upload it to Aliyun to fill the image link to the cursor position;

Chinese document

A good document can help us to develop more easily: students who are good at English can directly read the English document of Vscode, where there will be more comprehensive API, so that they can find a more concise scheme to implement functions; However, I still spent a long time to find this relatively complete Chinese document

Set up the project

The development of vscode plug-ins requires global scaffolding installation:

 npm install -g yo generator-code
Copy the code

After the installation is successful, use the corresponding command “Yo code” directly to generate a plug-in project:

Vscode starts the page

This is where the scaffolding page begins, and you can choose your preferred configuration. Enter the corresponding configuration and the corresponding project is created.

Let’s take a look at the project structure:

The plug-in structure

Plug-in run

At this time, we should first test whether my plug-in can run successfully. Pressing F5 in the project root directory and running “vscode extension” will bring up a new vscode window, but one of the problems I encountered here was this:

The plug-in

The dependency of vscode plug-ins is low:

At present is:

The plug-in

This makes it very clear that the vscode extension is specified to be compatible with any version of vscode that is compatible with it. Then change it to 1.60.2, perfect solution

Plug-in run — successful demonstration

Ok, how do you check yourself to see if your plug-in is running successfully, in 3 steps

  1. F5 starts debugging – generates a new debug window
  2. Find the Hello Word in the new window — Command + Shift + P
  3. Click “Run” and see the popup window, it indicates that the popup window runs successfully

Take a look at the GIF below:

GIF demo

Plug-in development – Configure parameters

Configure the plugin’s properties panel, which basically configits parameters in package.json

Configuration parameters

The first parameter, which we’ll talk about later, is the parameter that corresponds to the custom command that you register. The following parameters are the parameters that correspond to the plugin properties panel. You can then access these parameters through vscode’s API

Below are the parameters I configured, you can adjust them according to the plugin’s custom

"properties": { "upload_image.domain": { "type": "string", "default": "", "description": "Upload_image. accessKey": {"type": "string", "default": "", "description": Upload_image.secretkey ": {"type": "string", "default": "", "description": "Upload_image. scope": {"type": "string", "default": "", "description": "Upload_image. gzip": {"type":" Boolean ", "default": "true", "description": "Whether to enable image compression"}}Copy the code

So these are the parameters, and then we’re going to test f5 again and find Settings in a new window and then find the extension, and the Settings item is actually the one that corresponds to our title

Compress the image.

Let’s take a look at the effect:

The effect

Plug-in development – Configuration right-click menu

The function description is basically, you are writing when suddenly want to upload, directly click the right mouse button, and directly select the image. Right is this simple thing, do things need to consider from the user’s point of view, must be cool, can save step is step. Ha ha ha ha

This configuration is essentially a continuation of the previous “package.json” configuration:

"menus": {
    "editor/context": [
      {
        "when": "editorFocus",
        "command": "extension.choosedImage",
        "group": "navigation"
      }
    ]
  }
Copy the code

When: When you’re editing with your mouse

This is the name of the event registered in extension.js

let texteditor = vscode.commands.registerTextEditorCommand(
  'extension.choosedImage', ... )
Copy the code

This is actually the name of the event registered in extension. js. The ** “event name” in this file must correspond to the file in “package.json” otherwise it will not come out. To show you:

The picture

To restart the plugin, press F5 and right click to have our custom right click menu. But the question is do we have to right click to bring up an image selection box wow, otherwise how do we upload?

Open the picture upload dialog box

Powerful vscode supports built-in apis to open:

const uri = await vscode.window.showOpenDialog({
    canSelectFolders: false,
    canSelectMany: false,
    filters: {
      images: ['png', 'jpg','apng','jpeg','gif','webp'],
    },
  }); 
Copy the code

It’s this API that you can filter out the image you want, in the filters, and then spit it out and give us the path of that image.

Let’s take a look at the effect:

Read picture data

In fact, at this time we already have the image path, this time we need to use ** “node.js” ** fs module to read the image buffer, this is actually convenient for us to upload the image to the OSS. The code is as follows:

const uri = await vscode.window.showOpenDialog({
    canSelectFolders: false,
    canSelectMany: false,
    filters: {
      images: ['png', 'jpg','apng','jpeg','gif','webp'],
    },
  }); 
let imgBuffer =  await fs.readFile(uri[0].path);
Copy the code

Here also involves a say: local image name encrypted, can not be uploaded to oss various Chinese what, display we are not professional wow

So I wrote an MD5 conversion here

function md5Name(name) {
 const index = name.lastIndexOf('.')
 const sourceFileName = name.substring(0, index)
 const suffix = name.substring(index)
 const fileName = md5(sourceFileName + Date.now()) + suffix
 return fileName.toLowerCase()
}
Copy the code

Is to make the name fancy appearance, ha ha ha ha ha!

Image compression

After we get the image buffer data, we need to support compression of the image. In fact, there are many solutions in the community, here I still decide to use Tinfiy, which also has the corresponding ** “Node.js” ** the main reason for using it is to see the following picture:

apng

Yes this guy supports ** “APNG”, the rest is not clear. But he is not a free person a month free “500” ** times, thinking about it is ok, we do not need to spicy yao many times finally considered using it to achieve.

The installation

To install the NPM package and add it to your application’s dependencies, you can use the Node.js client:

npm install --save tinify
Copy the code

certification

You must provide your API key to use the API. You can obtain the API key by registering your name and Email address. Please keep the API key in secret.

const tinify = require("tinify");
tinify.key = "YOUR_API_KEY";
Copy the code

This is actually your mailbox to register, and then put your corresponding ** “key” ** to activate in fact it is ok

As shown in figure

It’s actually the following one and you just have to activate your key

Tinify compresses images

You can upload any JPEG or PNG image to the Tinify API for compression. We will automatically detect the image type and optimize accordingly using TinyPNG or TinyJPG engines. Compression starts as soon as you upload a file or provide an image URL.

You can select a local file as the source and write to another file.

const source = tinify.fromFile("unoptimized.webp");
source.toFile("optimized.webp");
Copy the code

You can also upload images from buffers (binary strings) and get data for compressed images.

const fs = require("fs");
fs.readFile("unoptimized.jpg", function(err, sourceData) {
  if (err) throw err;
  tinify.fromBuffer(sourceData).toBuffer(function(err, resultData) {
    if (err) throw err;
    // ...
  });
});
Copy the code

Code implementation

function compressBuffer(sourceData, key = 'xxx') { return new Promise((resolve,reject) => { tinify.key = key; tinify.fromBuffer(sourceData).toBuffer(function(err, resultData) { if(resultData) { resolve(resultData) } if (err) { reject(err); } / /... }); })}Copy the code

Based on the fact that this encapsulates a promise, the ** “fromBuffer” **, to “toBuffer” really works. Ha ha ha very sweet, remember to set the key or promise will report an error directly, set the key method on the above 👆🏻, and then in fact we get compressed picture data.

Upload images to OSS

Here, in fact, some use seven niuyun, and some use Ali Cloud. To upload images, or ajax to upload is actually ok

Generally, it is necessary to obtain token and all kinds of signature information, and then directly upload it, and then you can get a picture address. I’m not going to show you the code, it’s all front-end should understand. Here are some of the problems I encountered

  1. If ** “FormData” ** is used, it will not be found. This method is undefined, and ** “fetch” **, so it is necessary to install the corresponding Node JS package. I’m using “cross-fetch” and “form-data”

The configuration issue here is how you get your configuration parameters in the extension:

"Configuration ": [{"title":" compressed image ", "properties": {"upload_image.secret key ": {"type": "string", "default": }, "upload_image.secrettokenURL ": {"type": "string", "default": ", "description": "set object tokenUrl"}}}]Copy the code

The upload_image in front of each attribute is actually what you can do in the extension:

const imageConfig =  vscode.workspace.getConfiguration('upload_image')
Copy the code

And then you can get the configuration, the upload_image property is actually the key in the object and then you can manipulate it

This is a project-specific thing, so you can configure it for your own project

Plug-in development – Image links are written to the editor

Editor. selection can be used to obtain the position of the cursor and the position of the cursor. Editbuilder. replace replaces the selected content if the cursor is selected, otherwise EditBuilder. insert inserts the image link at the cursor position:

/ / to write image links into the editor function addImageUrlToEditor (url) {let editor is = vscode. Window. ActiveTextEditor if (! editor) { return } const { start, end, Active} = editor.selection if (start.line === end.line && start.character === end.character) {// Insert content const at cursor position activePosition = active editor.edit((editBuilder) => { editBuilder.insert(activePosition, Url)})} else {// Replace content const Selection = editor.Selection editor.edit((editBuilder) => { editBuilder.replace(selection, url) }) } }Copy the code

Plug-in release

At this point, an entire vscode plug-in is ready to be developed, and then we need to package it and release it to the vscode app market

Create account

I am directly github login to create, first we enter the document mentioned in the home page, complete the verification login to create an organization.

Create an organization

Creating a publisher

Enter the following page marketplace.visualstudio.com/manage/publ… ** plugin publisher, let us have a look at my:

The publisher

Packaging releases

First install scaffolding globally

npm install -g vsce
Copy the code

Then CD to the current plug-in directory using the following command

$ cd myExtension
$ vsce package
# myExtension.vsix generated
Copy the code

This package will report some errors:

The first is to add publishers to the plug-in’s package.json

"publisher": "Fly",
Copy the code

To add ICONS to your plugin: Actually create a folder in your project: Image and put the image in it: also configure it in package.json

"icon": "images/dewu.jpeg",
Copy the code

There may be ⚠️, but it doesn’t matter, just keep running, okay

warn

The last word is to write the readme or you won’t publish it.

Packaging upload

All ready: command line input

vsce package 
Copy the code

Then the project will appear:

photo

And then you can drag this thing onto the page the page

Marketplace.visualstudio.com/manage/publ…

upload

Then click upload and you can see your plugin in the vscode plugin store

The plug-in

The last

Follow my public account “front-end graphics” for more fun and interesting graphics knowledge. “If you also love technology and are fascinated by **” Graphics, data visualization, games “📚, please add my personal wechat (wZF582344150) **” and will invite you to join my “Visual communication learning group for Programming for happiness ~” 🦄. “I’m Fly”, currently working in the interactive game group of an e-commerce company. In this era of crazy and rapid iteration of Internet technology, I am glad to grow stronger with you! 😉