iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
Formations
TypeScript · Intermédiaire

Extensions VS Code

Utiliser, créer et publier une extension VS Code en TypeScript : commandes, configuration, vues, webviews, diagnostics, tests, bundling et publication sur le Marketplace et Open VSX.

VS Code APITypeScriptesbuildvsceOpen VSXGitHub Actions
01Utiliser et gérer ses extensions02Générer et lancer sa première extension03Commandes, réglages et activation04Barre d'état, vues et décorations05Webviews : un panneau HTML dans l'éditeur06Diagnostics, corrections rapides et complétion07Tester et bundler l'extension08Publier sur le Marketplace et Open VSX
Chapitre 3·30 min

Commandes, réglages et activation

Une commande accessible uniquement par la palette, c'est un début. Une extension agréable s'intègre là où l'utilisateur travaille : un raccourci, un clic droit, un réglage qu'il ajuste. Tout cela se déclare dans contributes, presque sans code.

Les points de contribution

contributes est la partie déclarative du manifeste. VS Code la lit sans exécuter l'extension : les commandes apparaissent dans la palette, les réglages dans l'écran Settings, les menus sont en place avant même l'activation. Le code ne se charge qu'au premier usage.

Les plus utilisés :

CléCe qu'elle ajoute
commandsCommandes de la palette, avec titre, catégorie et icône
menusEntrées dans les menus contextuels, barres de titre, palette
keybindingsRaccourcis clavier
configurationRéglages visibles dans Settings
views, viewsContainersVues latérales (chapitre 4)
snippets, grammars, languagesSupport d'un langage (chapitre 6)
themes, iconThemesThèmes de couleurs et d'icônes

Déclarer des réglages

TODO Radar doit laisser l'utilisateur choisir ses marqueurs et les dossiers à ignorer.

package.json
"contributes": {
  "configuration": {
    "title": "TODO Radar",
    "properties": {
      "todoRadar.tags": {
        "type": "array",
        "items": { "type": "string" },
        "default": ["TODO", "FIXME", "HACK"],
        "description": "Marqueurs à rechercher dans les commentaires."
      },
      "todoRadar.exclude": {
        "type": "string",
        "default": "**/{node_modules,dist,out,.git}/**",
        "description": "Motif glob des fichiers à ignorer lors du scan du projet."
      },
      "todoRadar.requireTicket": {
        "type": "boolean",
        "default": false,
        "markdownDescription": "Signaler les `TODO` qui ne référencent pas de ticket (`#123` ou `ABC-123`)."
      }
    }
  }
}

Le schéma suit JSON Schema. VS Code en tire l'interface de Settings : une case à cocher pour un booléen, une liste éditable pour un tableau, un menu déroulant si vous ajoutez enum. markdownDescription autorise le code inline et les liens.

Lire un réglage dans le code :

src/config.ts
import * as vscode from 'vscode'
import { DEFAULT_TAGS } from './scanner'
 
export function getConfig() {
  const config = vscode.workspace.getConfiguration('todoRadar')
  return {
    tags: config.get<string[]>('tags', DEFAULT_TAGS),
    exclude: config.get<string>('exclude', '**/node_modules/**'),
    requireTicket: config.get<boolean>('requireTicket', false),
  }
}

Un réglage peut changer pendant que l'extension tourne. On écoute l'événement et on filtre sur sa propre section :

context.subscriptions.push(
  vscode.workspace.onDidChangeConfiguration((event) => {
    if (event.affectsConfiguration('todoRadar')) {
      refreshEverything()
    }
  })
)

Écrire un réglage est possible, mais réservé aux cas où l'utilisateur l'a demandé, par exemple un bouton « Ajouter ce marqueur » :

await vscode.workspace
  .getConfiguration('todoRadar')
  .update('tags', [...tags, 'NOTE'], vscode.ConfigurationTarget.Workspace)

ConfigurationTarget.Global écrit dans les réglages utilisateur, Workspace dans .vscode/settings.json du projet.

Raccourcis clavier

package.json
"keybindings": [
  {
    "command": "todo-radar.countInFile",
    "key": "ctrl+alt+t",
    "mac": "cmd+alt+t",
    "when": "editorTextFocus"
  }
]

Choisissez un raccourci peu exposé : il entrera en concurrence avec ceux de VS Code et des autres extensions. L'utilisateur peut toujours le réassigner dans Keyboard Shortcuts.

Les clauses when

when décide quand une contribution est visible ou active. C'est une expression évaluée sur des clés de contexte maintenues par VS Code :

CléVraie quand
editorTextFocusLe curseur est dans un éditeur de texte
editorLangId == typescriptLe fichier actif est du TypeScript
resourceExtname == .mdLe fichier ciblé a l'extension .md
editorHasSelectionDu texte est sélectionné
view == todoRadar.listL'élément appartient à la vue todoRadar.list
isWorkspaceTrustedLe dossier est marqué de confiance

Les opérateurs &&, ||, !, ==, !=, =~ (expression régulière) et in se combinent librement. La commande Developer: Inspect Context Keys affiche toutes les clés à l'instant T, indispensable quand un menu refuse d'apparaître.

Une extension peut créer ses propres clés :

await vscode.commands.executeCommand('setContext', 'todoRadar.hasTodos', matches.length > 0)

La clé todoRadar.hasTodos devient utilisable dans n'importe quelle clause when du manifeste.

Menus

Ajoutons la commande au clic droit dans l'éditeur, et ne la proposons dans la palette que lorsqu'un fichier est ouvert :

package.json
"menus": {
  "editor/context": [
    {
      "command": "todo-radar.countInFile",
      "group": "navigation@10"
    }
  ],
  "commandPalette": [
    {
      "command": "todo-radar.countInFile",
      "when": "editorIsOpen"
    }
  ]
}

Pour une commande purement interne, appelée seulement depuis un bouton ou par une autre commande, "when": "false" la retire complètement de la palette.

group place l'entrée dans une section du menu ; navigation est la section du haut, @10 règle l'ordre à l'intérieur. Les emplacements les plus courants sont editor/context, editor/title, explorer/context, view/title et view/item/context.

Choisir le bon événement d'activation

Depuis VS Code 1.74, les commandes, vues et langages déclarés dans contributes génèrent leurs propres événements d'activation. Pour une extension qui ne réagit qu'aux commandes, activationEvents reste vide.

TODO Radar doit pourtant compter les marqueurs dès qu'un fichier s'ouvre, sans attendre une commande. Plusieurs options :

ÉvénementQuand
onStartupFinishedJuste après le démarrage, sans le ralentir
onLanguage:pythonÀ l'ouverture d'un fichier Python
workspaceContains:**/package.jsonSi le projet contient ce fichier
onView:todoRadar.listÀ l'ouverture de la vue (implicite si la vue est déclarée)
onUriQuand une URL vscode://publisher.extension est ouverte
*Au démarrage. À éviter : ralentit l'ouverture de VS Code pour tout le monde

On retient onStartupFinished :

package.json
"activationEvents": ["onStartupFinished"]

Mémoriser un état

ExtensionContext donne trois stockages persistants :

StockagePortéeUsage
context.globalStateToutes les fenêtresDate du dernier message « quoi de neuf », préférences internes
context.workspaceStateLe projet ouvertDernier filtre appliqué, éléments masqués
context.secretsTrousseau du systèmeJetons d'API, mots de passe
// Afficher un message une seule fois après une mise à jour
const version = context.extension.packageJSON.version as string
if (context.globalState.get('lastVersion') !== version) {
  vscode.window.showInformationMessage(`TODO Radar ${version} : nouvelle vue des statistiques.`)
  await context.globalState.update('lastVersion', version)
}
 
// Stocker un jeton d'API (GitHub, Jira…) dans le trousseau
await context.secrets.store('todoRadar.jiraToken', token)
const saved = await context.secrets.get('todoRadar.jiraToken')

Ne mettez jamais un secret dans globalState ni dans un réglage : les réglages sont synchronisés et souvent commités, globalState est stocké en clair. secrets passe par le trousseau de Windows, macOS ou Linux.

Journaliser proprement

console.log n'est visible que pendant le développement. Pour les utilisateurs, on crée un canal dans le panneau Output :

const log = vscode.window.createOutputChannel('TODO Radar', { log: true })
context.subscriptions.push(log)
 
log.info('Scan démarré')
log.warn('Fichier trop gros ignoré : ' + uri.fsPath)
log.error(err as Error)

Avec { log: true }, chaque ligne est horodatée et le niveau de détail suit le réglage Developer: Set Log Level. Quand un utilisateur ouvre une issue, vous lui demandez le contenu de ce canal.

Workspace Trust

TODO Radar ne fait que lire des fichiers ; elle peut tourner en mode restreint. On le déclare :

package.json
"capabilities": {
  "untrustedWorkspaces": { "supported": true },
  "virtualWorkspaces": true
}

Une extension qui exécute des outils du projet (un linter installé dans node_modules, par exemple) déclare "supported": "limited" et vérifie vscode.workspace.isTrusted avant de lancer quoi que ce soit.


L'extension a des réglages, un raccourci, un menu et s'active au bon moment. Le chapitre suivant lui donne une vraie présence dans l'interface : barre d'état, vue latérale et surlignage.

Précédent
Générer et lancer sa première extension
Suivant
Barre d'état, vues et décorations

Développeur fullstack passionné. J'apprends en construisant et je documente tout — front, back, outils. Le code s'apprend mieux en public.

Naviguer

IndexTous les articlesFormationsProfilOutilsBibliothech

Ailleurs

GitHub RSS

Newsletter

Les articles, libs et découvertes. Une fois par semaine, pas plus.

© 2026 William LoreeConçu & codé à la main