A few years ago, I discovered the power of Chrome and VSCode extensions in improving productivity. I created my own extension if my desired feature was not available. The extension systems allow me to experiment my wild ideas with less effort thanks to their graceful design.
While they have similarities, there are also some significant differences determined by the nature of each app. In this blog post, I will provide an overview of the extension systems of Chrome and VSCode and share what I have learned from them.
Both extension systems have an entry point - a JSON file. Chrome extension starts from a manifest.json file, while VSCode extensions extend the package.json file, which can sometimes become lengthy and contain too much information. I am worried about conflicts arise from the file.
In the JSON, developer need to provide essential information such as icon for display and script to initialise with. Each parts of a Chrome extension require a script file or a html file, while VSCode only need an entry script.
{
"name": "Broken Background Color",
"version": "1.0",
"description": "Fix an Extension!",
"permissions": ["activeTab", "scripting", "storage"],
"options_page": "options.html",
"background": {
"service_worker": "service-worker.js"
},
"icons": {
"16": "images/icon-16.png"
},
"manifest_version": 3
}
{
"name": "cat-coding",
"description": "Cat Coding - A Webview API Sample",
"version": "0.0.1",
"publisher": "vscode-samples",
"activationEvents": ["*"],
"main": "./out/extension.js",
"contributes": { ... },
"devDependencies": { ... }
}
In addition to these files, Chrome extensions also require careful declaration of browser permissions to enable their APIs. I totally understand the importance and difficulty of guarding browser security, but providing excessive information that can be accessed through automation is unreasonable.
The extension APIs in both Chrome and VSCode are well-categorized based on the functionality of the app. This categorization allows developers to explore the possibilities by following the names of the app modules. For example:
chrome.cookies.get({ url: "<https://example.com>", name: "cookie_name" }, (cookie) => {
if (cookie) {
console.log(cookie.value);
}
});
However, there are possibilities that we have no clues about the name at all 🤦♀️ such as the text decoration in VSCode as mentioned in this blog.
Being a Microsoft product, the coding style of VSCode extensions can sometimes be too OOP style. For instance, to implement a tree view, we must declare a class extends the TreeDataProvider
class and provides methods getTreeItem()
and getChildren()
:
export class DepNodeProvider implements vscode.TreeDataProvider<Dependency> {
private _onDidChangeTreeData: vscode.EventEmitter<Dependency | undefined | void> = new vscode.EventEmitter<Dependency | undefined | void>();
readonly onDidChangeTreeData: vscode.Event<Dependency | undefined | void> = this._onDidChangeTreeData.event;
constructor(private workspaceRoot: string | undefined) {
}
refresh(): void {
this._onDidChangeTreeData.fire();
}
getTreeItem(element: Dependency): vscode.TreeItem {
return element;
}
getChildren(element?: Dependency): Thenable<Dependency[]> {
//...
}
}
Plus the “traps” I mentioned above in Chrome, a well structured and clear document with rich example codes become vital.
There are three ways to trigger our scripts: