7 First Extension

7.1 Project Setup with yo code

Developing VSCode extensions starts with the creation of a standardized project structure. Microsoft provides a generator tool based on Yeoman, which automates the setup of TypeScript projects, build configurations, and debugging environments.

7.2 Prerequisites and Installation

Extension development requires Node.js as a runtime environment. Node.js provides both the npm package manager and the JavaScript runtime needed for TypeScript transpilation and extension hosting.

The required tools are installed globally:

npm install -g yo generator-code

This installation provides two components:

7.3 Project Initialization

The command yo code starts an interactive dialog for project configuration. The selection is made via a menu with various extension types:

For extension development, “New Extension (TypeScript)” is the default choice. The dialog then asks for:

7.4 Generated Project Structure

After completing the configuration, the generator creates the following directory structure:

extension-name/
├── .vscode/
│   ├── launch.json          # Debugger configuration
│   ├── settings.json        # Workspace settings
│   └── tasks.json           # Build tasks
├── src/
│   ├── extension.ts         # Extension entry point
│   └── test/
│       └── extension.test.ts # Unit tests
├── package.json             # Extension manifest
├── tsconfig.json            # TypeScript configuration
├── .gitignore               # Git exclusions
├── .eslintrc.json           # Linting rules
├── README.md                # Documentation
└── CHANGELOG.md             # Version history

7.4.1 Extension Manifest (package.json)

The package.json defines extension metadata and contributions:

{
  "name": "extension-name",
  "displayName": "Extension Name",
  "description": "Extension Description",
  "version": "0.0.1",
  "engines": {
    "vscode": "^1.74.0"
  },
  "categories": ["Other"],
  "activationEvents": [],
  "main": "./out/extension.js",
  "contributes": {
    "commands": [{
      "command": "extension-name.helloWorld",
      "title": "Hello World"
    }]
  },
  "scripts": {
    "vscode:prepublish": "npm run compile",
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./"
  },
  "devDependencies": {
    "@types/vscode": "^1.74.0",
    "@types/node": "16.x",
    "typescript": "^4.9.4"
  }
}

7.4.2 Extension Entry Point (src/extension.ts)

The generated extension.ts contains the required lifecycle functions:

import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
    const disposable = vscode.commands.registerCommand(
        'extension-name.helloWorld', 
        () => {
            vscode.window.showInformationMessage('Hello World from Extension Name!');
        }
    );
    
    context.subscriptions.push(disposable);
}

export function deactivate() {}

7.5 Debugger Configuration

The .vscode/launch.json file defines the debugging environment:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Run Extension",
            "type": "extensionHost",
            "request": "launch",
            "args": [
                "--extensionDevelopmentPath=${workspaceFolder}"
            ],
            "outFiles": [
                "${workspaceFolder}/out/**/*.js"
            ],
            "preLaunchTask": "${workspaceFolder}/npm: watch"
        }
    ]
}

This configuration:

7.6 First Run

Debugging starts via F5 or the debug panel. VSCode opens a new instance titled “[Extension Development Host]”. In this environment, the developed extension is active and available via the command palette (Ctrl+Shift+P).

The generated Hello World command can be executed under the name “Hello World” and displays an information message.

7.7 Build Process

The TypeScript compiler transpiles source files from src/ to out/. The configuration in tsconfig.json defines:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "ES2020",
    "outDir": "out",
    "lib": ["ES2020"],
    "sourceMap": true,
    "rootDir": "src",
    "strict": true
  },
  "exclude": ["node_modules", ".vscode-test"]
}

During development, the compiler can be run in watch mode via npm run watch. Changes are automatically transpiled and become available in the development host instance upon reload (Ctrl+R).

7.8 Extending the Project Structure

The generated project forms the foundation for more complex extensions. Typical extensions include:

The project structure remains consistent and follows the conventions of VSCode extension development.