Publishing Visual Studio Code Extension
Hello!
As you might know, we have recently published Salesforce Snippets extension on Visual Studio Marketplace. It is something that can help you with your day-to-day tasks in the Salesforce world. We tried to collect as many useful code snippets as we could, to make it a complete collection.
In this Blog Post, I will explain how to create and publish your extension! I will focus mainly on preparing the package.json
file as well as publishing it. The development paragraph will be based on our experience with snippets extension, as development can be vastly different for each extension. In all cases, package configuration and extension should be pretty similar. Let’s get started!
Prerequisite
Firstly, we need to install the required tools.
Make sure you have installed Node.js, and Git.
After making sure we have Node and Git installed, let’s get Yeoman and VS Code Extension Generator, tools that will be used to generate metadata for the extension.
npm install -g yo generator-code
Setting up a project
The Yeoman package allows the generating of necessary files to start development.
Enter the following inside the console:
yo code
This command initiates a quick wizard which will provide a basic configuration of the new extension. After following it and instantiating a new repository, you should land with a similar file structure:
📦examplesnippets
┣ 📂.git
┣ 📂.vscode
┃ ┗ 📜launch.json
┣ 📂snippets
┃ ┗ 📜snippets.code-snippets
┣ 📜.gitattributes
┣ 📜.gitignore
┣ 📜.vscodeignore
┣ 📜CHANGELOG.md
┣ 📜README.md
┣ 📜package.json
┗ 📜vsc-extension-quickstart.md
Types of files depend on the options selected. I wanted to create Snippets extensions, that’s why I have a snippets subfolder with .json
inside. Now you can check if everything went as expected. Click F5
to open the Extension Development Host window. It is possible thanks to .vscode/launch.js
, if you are missing this file, please try again with the yo code
generator.
Development
And now is the moment, when you can write some code. For different types of extensions, the development will be slightly different. I will be basing this part on Salesforce Snippets extension that we have created. To get further information about other types, please check Extension Guides or ask in the comment section. 🙂
Snippets consist of .json
files, where we define the following objects:
{
"description" {
"prefix": ["prefixes"],
"body": ["body elements"],
"description": "Short summary",
"scope": "list of supported languages"
}
}
An example snippet that we defined:
{
"LWC lightning-button": {
"body": [
"<lightning-button variant='${1|base,neutral,brand,brand-outline,destructive,destructive-text,inverse,success|}' label='${2:label}' title='${3:title}' onclick={${4:handleOnClick}} class='${5:cssClass}'>",
"</lightning-button>"
],
"description": "lightning-button",
"prefix": [
"lightning-button"
],
"scope": "html"
}
}
In the end, it will result in the following behaviour:
After adding your first snippet, you can test the changes in the Extension Development window (press F5
). If you have a test window already open, use the Ctrl + R
shortcut to reload and check the latest changes.
The extension can contain multiple .json
files for multiple languages, which was also in our case. We have defined separate files to contain Apex
JavaScript
HTML
and XML
snippets.
📦snippets
┣ 📜apex.json
┣ 📜lwc-html.json
┣ 📜lwc-js.json
┗ 📜lwc-xml.json
To learn more about creating snippets, check Snippet Guide and User Guide docs on Visual Studio Code page.
Configuring Package
Now you came to the most important step. The package defines how others see the package on the Marketplace and what features it has. I will describe each key and what it is controlling.
Introduction
Let’s start with a generated template. After using Yeoman, you should have the following package.json
:
{
"name": "examplesnippets",
"displayName": "exampleSnippets",
"description": "Just some testings.",
"version": "0.0.1",
"engines": {
"vscode": "^1.72.0"
},
"categories": [
"Snippets"
],
"contributes": {
"snippets": [
{
"language": "apex",
"path": "./snippets/snippets.code-snippets"
}
]
}
}
name | Unique identifier of your extension needs to be in lowercase and without spaces and will be used in URLs. |
---|---|
displayName, description, version | Values to be used on the Marketplace page to inform about your Extension. |
engines | An object which defines the minimum VS Code version your extension is compatible with. |
categories | Array of strings from a predefined list should be automatically prepopulated by the generator, if you want to add more, possible options are: [Programming Languages, Snippets, Linters, Themes, Debuggers, Formatters, Keymaps, SCM Providers, Other, Extension Packs, Language Packs, Data Science, Machine Learning, Visualization, Notebooks, Education, Testing] |
contributes | An actual list of what exactly your extension does, refer to the Contribution Points doc to learn more. |
license, badges, sponsor, icon | Items available to provide additional information on Marketplace Page. |
dependencies, devDependencies | Node.js dependencies your extensions needs. |
scripts | The same as npm’s scripts. |
More possible items and additional information can be found in the Extension Manifest document.
Our use case
In our case, we have added scripts, icons, and repository links. Scripts are used by the pipeline to automatically publish the extension. Additionally, as we have defined Snippets for multiple languages, we have multiple languages dined in the snippets
object:
"repository": "https://github.com/beyond-the-cloud-dev/vsc-salesforce-code-snippets",
"icon": "images/logo.png",
"scripts": {
"deploy": "vsce publish",
"deploy-patch": "vsce publish patch",
"deploy-minor": "vsce publish minor",
"deploy-major": "vsce publish major"
},
"contributes": {
"snippets": [
{
"language": "apex",
"path": "./snippets/apex.json"
},
{
"language": "html",
"path": "./snippets/lwc-html.json"
},
{
"language": "javascript",
"path": "./snippets/lwc-js.json"
},
{
"language": "xml",
"path": "./snippets/lwc-xml.json"
}
]
},
"devDependencies": {
"vsce": "^2.11.0"
}
Publishing
After all the hard work, we can finally share the creation with the world. First, let’s install an additional package, which will make publishing an easier task:
npm install -g vsce
Visual Studio Code Extensions is a command line tool to help with the development of VS Code extensions. It has some additional options that I won’t cover here, please check them out using the GitHub link above!
There are two options in which you can publish an extension.
Using Package
Package and Extension and upload it manually or share it with others without publishing at all. To achieve it, enter the following command:
vsce package
This will result in vsce
packaging your extension into a VSIX
file. Such files can be used to install extensions without Visual Studio Marketplace.
If you have .vsix
file and want to install it, enter:
code --install-extension examplesnippets-0.0.1.vsix
Using vsce to publish
If you want to go straight for publishing, first create a publisher identity and grab your personal access token. Go to management page to create a new publisher. Follow Use personal access tokens article to create new Access Token.
Now you can use your access token to log in:
vsce login <token>
Now publishing is a piece of cake, simply type:
vsce publish
To make Extension available on Visual Studio Marketplace.
Final Thoughts
Now you should be able to create your extension and share it with others! This is a no-where complete guide on creating VS Code extension, but a good starting point. With Visual Studio Code, you can customize it almost as much as you want. Linked documentation is a great place to learn about all types of extensions.
Please take a look at our extension Salesforce Snippets that we have built based on the knowledge I have presented here. Developing it was easier than expected thanks to available documentation and the easy-come API of VS Code.
Thank you and happy coding!
Resources
- Your First Extension
- Extension Guides
- UX Guides
- Language Guides
- Snippet Guide
- Creating your own Snippets
- Extension Manifest
- NPM Scripts
- Create Publisher
- Use personal access tokens to authenticate