La palabra “scaffold” que se podría traducir como “andamiaje” en español. El desarrollo web el “scaffold” de un proyecto vendría a ser la estructura básica necesaria para arrancar con un tipo de proyecto. En esta linea, heramientas de “scaffold”, son herramientas que generan la estructura básica. Yeoman es una de las herramientas más populares para hacer “scaffolding” de proyectos web.
La documentación de Visual Code acerca de extensiones recomienda utilizar Yeoman y su VS Code Extension Generator para generar la estructura de archivos necesaria para empezar a crear extensiones.
La estructura de archivos que te genera esta herramienta de scaffolding incluye todos lo necesario para debugear, testear, lintear y publicar la extensión. En este articulo crearemos una extensión de Visual Code con esta herramienta y comentaremos la función de los archivos que genera.
Para una primera aproximación al desarrollo de extensiones te recomiendo Creando la extensión más básica para Visual Code donde explico las ideas fundamentales al crear una extensión.
Tabla de Contenidos
- Scaffolding una extension de Visual Code con Yeoman
- Anatomia de una extension
- En resumen
Scaffolding una extension de Visual Code con Yeoman
Para generar una proyecto de partida para tu extension de Visual Code puedes ejecutar lo siguiente desde tu terminal:
npx --package yo --package generator-code -- yo code
Este comando ejecuta directamente Yeoman y lo llama con el generador VS Code Extension Generator. Esto lanza un asistente en la terminal donde a base de responder a las preguntas podemos ir customizando el tipo de proyecto a generar.
⬢ 2024 npx --package yo --package generator-code -- yo code
_-----_ ╭──────────────────────────╮
| | │ Welcome to the Visual │
|--(o)--| │ Studio Code Extension │
`---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? HelloWorld
? What's the identifier of your extension? helloworld
? What's the description of your extension?
? Initialize a git repository? Yes
? Which bundler to use? unbundled
? Which package manager to use? npm
Writing in /Users/juanmanuelgarrido/PROJECTS/2024/helloworld...
create helloworld/.vscode/extensions.json
create helloworld/.vscode/launch.json
create helloworld/.vscode/settings.json
create helloworld/.vscode/tasks.json
create helloworld/package.json
create helloworld/tsconfig.json
create helloworld/.vscodeignore
create helloworld/vsc-extension-quickstart.md
create helloworld/.gitignore
create helloworld/README.md
create helloworld/CHANGELOG.md
create helloworld/src/extension.ts
create helloworld/src/test/extension.test.ts
create helloworld/.vscode-test.mjs
create helloworld/eslint.config.mjs
Changes to package.json were detected.
Running npm install for you to install the required dependencies.
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated glob@8.1.0: Glob versions prior to v9 are no longer supported
added 266 packages, and audited 267 packages in 9s
68 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Your extension helloworld has been created!
To start editing with Visual Studio Code, use the following commands:
code helloworld
Open vsc-extension-quickstart.md inside the new extension for further instructions
on how to modify, test and publish your extension.
For more information, also visit http://code.visualstudio.com and follow us @code.
? Do you want to open the new folder with Visual Studio Code? (Use arrow keys)
❯ Open with `code`
Skip
Rellenando los campos con los valores indicados arriba, esta herramienta genera la carpeta helloworld con el siguiente contenido de archivos y carpetas
.
├── .gitignore
├── .vscode
│ ├── extensions.json
│ ├── launch.json
│ ├── settings.json
│ └── tasks.json
├── .vscode-test.mjs
├── .vscodeignore
├── CHANGELOG.md
├── README.md
├── eslint.config.mjs
├── package-lock.json
├── package.json
├── src
│ ├── extension.ts
│ └── test
│ └── extension.test.ts
├── tsconfig.json
└── vsc-extension-quickstart.md
Estos archivos sirven para diferentes propositos relacionados con la extensión, incluyendo el testeo, el debug, la publicación y más. Veamos en detalle la función de cada archivo.
Algunos de los archivos tienen la extensión .mjs.
Las extensiones de Visual Code se ejecutan en Node.js que por defecto utiliza modulos CommonJS para los archivos .js . La extensión .mjs indica que esos archivos utlizan Modulos ECMAScript, los cuales pueden ser ejecutados en NodeJs bajo algunas condiciones.
Anatomia de una extension
Los archivos generados por VS Code Extension Generator cubren varios aspectos del desarrollo de una extensión, su testeo y su posterior publicación:
- Configuración a nivel de proyecto
- Testing
- Publicación
- Desarrollo en local
- Funcionalidad de la extensión
Configuración a nivel de proyecto
La carpeta .vscode contiene archivos de configuración a nivel de proyecto con lo que podemos compartirlos con cualquiera que trabaje con el proyecto. Los archivos creados para la extension son:
.vscode/extensions.json
Este es el archivo de configuración para recomendar extensiones de Visual Code para el proyecto.
{
"recommendations": [
"dbaeumer.vscode-eslint",
"ms-vscode.extension-test-runner"
]
}
Cuando este proyecto se abra en cualquier Visual Code, si las siguientes extensiones no están instaladas se recomendará su instalación:
– ESLint
– Extension Test Runner


.vscode/launch.json
Este es el archivo de configuración para debug que define como lanzar la extensión en modo debug desde el tab de Debug.
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/out/**/*.js"],
"preLaunchTask": "${defaultBuildTask}"
}
]
}
Este launch.json define la configuración “Run Extension” especifica para depurar extensiones y especifica cosas como:
- Que utilize los archivos en
${workspaceFolder}/out/**/*.jspara la depuración - Que antes de lanzar el debug lanze la tarea predeterminada de “build” (esta tarea está definida en el
tasks.json) - Que el tipo de debug sea
extensionHostque es un entorno especial utilizado por VS Code para ejecutar y depurar extensiones.
Este archivo de configuración utiliza algunas de las variables de sustitución disponibles en Visual code como ${workspaceFolder} o ${defaultBuildTask}. La lista completa de variables disponible está en Variables Reference
.vscode/tasks.json
Este es el archivo de definición de tareas específico para el proyecto. Las tareas definidas en este archivo permiten integrar Visual Code con herramientas externas (scripts definidos en package.json por ejemplo).
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
La configuración de arriba define la tarea de “build” por defecto. Estas tareas se pueden configurar y lanzar a través de comandos en la Paleta de comandos.

.vscode/settings.json
Este es el archivo de configuración de Visual Code específico para el proyecto.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
}
Estos settings a nivel de proyecto tienen prioridad sobre los settings a nivel de usuario. Cualquier cambio hecho a los settings de proyecto (Workspace settings) a traves de la UI de Visual Code queda reflejados en este archivo.
Testing
El scaffolding proporciona también los archivos de partida necesarios para lanzar tests automáticos con la herramienta vscode-test-cli .
El runner de tests vscode-test-cli utiliza Mocha como framework de tests. Mocha ofrece varias interfaces para definir y organizar nuestros tests Las interfaces más relevantes ofrecidas por Mocha son:
- Una interfaz BDD (Behaviour Driven Development) con los metodos
describeoit - una interfaz TDD (Test Driven Development) con los metodos
suiteotest.
@vscode/test-cli tiene su propia extensión (recomendada desde extensions.json) para lanzar los tests desde la UI de Visual Code.

.vscode-test.mjs
Archivo de configuración para el paquete @vscode/test-cli, que sirve para correr los tests de la extensión.
import { defineConfig } from '@vscode/test-cli';
export default defineConfig({
files: 'out/test/**/*.test.js',
});
El archivo .vscode-test.mjs indica, entre otras cosas, la ubicación de lo archivos de test que se han de lanzar.
/src/test/extension.test.ts
Test de ejemplo que es lanzado al ejecutar npm test (o npx vscode-test) desde la raiz del proyecto
import * as assert from 'assert';
// You can import and use all API from the 'vscode' module
// as well as import your extension to test it
import * as vscode from 'vscode';
// import * as myExtension from '../../extension';
suite('Extension Test Suite', () => {
vscode.window.showInformationMessage('Start all tests.');
test('Sample test', () => {
assert.strictEqual(-1, [1, 2, 3].indexOf(5));
assert.strictEqual(-1, [1, 2, 3].indexOf(0));
});
});
En el ejemplo de arriba se utiliza la interfaz TDD de Mocha (funciones suite o test para definir los tests) pero el mismo ejemplo funcionaría igual con la interfaz BDD.
Este ejemplo utiliza también el modulo nativo de NodeJS node:assert para las assertions que son las funciones utilizadas para comparar valores de una manera más semántica.
Publicación
Una vez tenemos la extensión completa podemos publicarla en el Marketplace de Visual Code
.vscodeignore
Este archivo se utiliza para especificar los archivos que deben ser excluidos de la publicación de la extensión.
.vscode/**
.vscode-test/**
src/**
.gitignore
.yarnrc
vsc-extension-quickstart.md
**/tsconfig.json
**/eslint.config.mjs
**/*.map
**/*.ts
**/.vscode-test.*
El archivo .vscodeignore funciona de manera similiar al achivo .gitignore pero es específico de las extensiones Visual Code. Cuando la extensión se publica, los archivos y directorios listados en .vscodeignore no son incluidos en el paquete.
Desarrollo local
eslint.config.mjs
Este es el archivo de configuración de ESLint. La revisión de código del linter se puede lanzar tanto en modo comando (npm run lint o npx eslint src) o en coordinación con el plugin ESLint recomendado para este proyecto.
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import tsParser from "@typescript-eslint/parser";
export default [{
files: ["**/*.ts"],
}, {
plugins: {
"@typescript-eslint": typescriptEslint,
},
languageOptions: {
parser: tsParser,
ecmaVersion: 2022,
sourceType: "module",
},
rules: {
"@typescript-eslint/naming-convention": ["warn", {
selector: "import",
format: ["camelCase", "PascalCase"],
}],
curly: "warn",
eqeqeq: "warn",
"no-throw-literal": "warn",
semi: "warn",
},
}];
Estas reglas de ESLint se aplicaran sobre los archivos Typescript ( *.ts) del proyecto y con el plugin instalado se indicaran cualquier error del linter directamente en el código (mediante un subrayado rojo).
tsconfig.json
Este es el archivo de configuración de la herramienta de compilado tsc (que genera archivos .js a partir de los .ts).
{
"compilerOptions": {
"module": "Node16",
"target": "ES2022",
"outDir": "out",
"lib": [
"ES2022"
],
"sourceMap": true,
"rootDir": "src",
"strict": true
}
}
En este proyecto el compilado a .js desde .ts se puede lanzar tanto desde los scripts del proyecto (npm run compile y npm run watch) como a traves del comando Run Build Task (gracias a la definición que hay en tasks.json)
La propiedad "sourceMap": true habilita la creación de Source Maps que permiten entre otras cosas debugear directamente en los archivos .ts (por ejemplo añadiendo breakpoints)
Funcionalidad de la extensión
Como ya comenté en Creando la extensión más básica para Visual Code la estructura más básica de una extensión se puede reducir a dos archivos: El manifiesto de la extensión (package.json)y el archivo de entrada de la entensión (que en este proyecto es /out/extension.js generado a partir de src/estension.ts)
package.json
Este archivo contiene metadata del proyecto Node combinado con el manifiesto de la extensión.
{
"name": "helloworld",
"displayName": "HelloWorld",
"description": "",
"version": "0.0.1",
"engines": {
"vscode": "^1.94.0"
},
"categories": [
"Other"
],
"activationEvents": [],
"main": "./out/extension.js",
"contributes": {
"commands": [
{
"command": "helloworld.helloWorld",
"title": "Hello World"
}
]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "npm run compile && npm run lint",
"lint": "eslint src",
"test": "vscode-test"
},
"devDependencies": {
"@types/vscode": "^1.94.0",
"@types/mocha": "^10.0.8",
"@types/node": "20.x",
"@typescript-eslint/eslint-plugin": "^8.7.0",
"@typescript-eslint/parser": "^8.7.0",
"eslint": "^9.11.1",
"typescript": "^5.6.2",
"@vscode/test-cli": "^0.0.10",
"@vscode/test-electron": "^2.4.1"
}
}
Como este proyecto utiliza Typescript, requiere de una serie de scripts (compile y watch principalmente) para generar los archivos js finales. Los archivos .js se generan en la carpeta out (tal y como está definido en tsconfig.json) y desde ahi se carga el archivo de entrada de la extensión ("main": "./out/extension.js")
Las dependencías de este proyecto incluyen todos los paquetes necesarios para crear y lanzar los tests, chequeo de código con ESLint y el uso de TypeScript.
src/extension.ts
El archivo origen (en TypesScript) del archivo final de entrada de la extensión ("main": "./out/extension.js")
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "helloworld" is now active!');
const disposable = vscode.commands.registerCommand('helloworld.helloWorld', () => {
vscode.window.showInformationMessage('Hello World from HelloWorld!');
});
context.subscriptions.push(disposable);
}
export function deactivate() {}
En resumen
Con la herramienta de scaffolding Yeoman y el generador VS Code Extension Generator podemos generar una estructura muy completa para desarrollo de extensiones de Visual Code que incluye:
- Configuraciónes a nivel de proyecto para una buena experiencia de desarrollo
- Configuración preparada para lanzar tests y algunos tests de ejemplo
- Configuración preparada para trabajar con Typescript y poder trabajar con los
.jsgenerados - Configuración preparada para una buena calidad de código con ESLint
Leave a Reply