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

OpenPatch

Créer et publier une librairie Vue 3 — composant de patch notes avec mode Vue, composable, mode standalone CDN, personnalisation CSS et publication npm.

Vue 3TypeScriptViteTailwind CSS v4
GitHub
01Setup Vite + Vue 3 + TypeScript02Types TypeScript et structure de données03Le composant OpenPatch.vue04Versioning avec localStorage05Le composable useOpenPatch06Mode standalone CDN07Build dual-mode et publication npm
Chapitre 6·25 min

Mode standalone CDN

Le mode standalone permet d'utiliser OpenPatch sans Vue, sans npm, sans build step — juste deux balises <script> dans n'importe quelle page HTML.

Entry point standalone

src/standalone.ts
import { createApp } from 'vue'
import OpenPatch from './components/OpenPatch.vue'
import { loadConfig } from './utils/configLoader'
import './style.css'
 
async function initOpenPatch() {
  const jsonUrl = window.OpenPatchConfig?.jsonUrl
  const settings = await loadConfig({ jsonUrl })
 
  if (!settings?.projectId || !settings.version || !settings.patchnotes) {
    console.error('[OpenPatch] Configuration incomplète')
    return
  }
 
  // Monter Vue dans un container créé dynamiquement
  const container = document.createElement('div')
  container.id = 'openpatch-widget-container'
  document.body.appendChild(container)
 
  const app = createApp(OpenPatch, {
    projectId: settings.projectId,
    version: settings.version,
    patchnotes: settings.patchnotes,
    title: settings.patchnotes.title,
    closeButtonText: settings.options?.closeButtonText ?? 'Compris !',
    forceShow: settings.options?.forceShow ?? false,
    cssCustomization: settings.css,
  })
 
  const instance = app.mount(container) as any
 
  // Exposer l'API sur window
  window.OpenPatch = {
    show: () => instance.show?.(),
    hide: () => instance.hide?.(),
    reset: () => instance.reset?.(),
  }
}
 
// Attendre le DOM si nécessaire
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', initOpenPatch)
} else {
  initOpenPatch()
}

Vue est bundlé dans ce build — c'est external: [] dans la config Vite standalone. Le fichier produit est autonome (~123 kB avec Vue inclus).

configLoader — fusion JSON + window.Settings

La séparation des responsabilités est le point le plus élégant du projet.

src/utils/configLoader.ts
export async function loadConfig(options: { jsonUrl?: string } = {}): Promise<WindowSettings | null> {
  let jsonConfig: JSONConfig | null = null
 
  // Étape 1 — charger le JSON distant (version + patchnotes seulement)
  if (options.jsonUrl) {
    try {
      const res = await fetch(options.jsonUrl)
      jsonConfig = await res.json() as JSONConfig
    } catch (error) {
      console.error('[OpenPatch] Erreur chargement JSON:', error)
    }
  }
 
  // Étape 2 — fusionner avec window.Settings (projectId + options + css)
  if (jsonConfig && window.Settings) {
    return {
      projectId: window.Settings.projectId,
      version: jsonConfig.version,
      patchnotes: jsonConfig.patchnotes,
      options: window.Settings.options,
      css: window.Settings.css,
    }
  }
 
  // Étape 3 — tout dans window.Settings (config inline)
  if (window.Settings?.projectId && window.Settings.version && window.Settings.patchnotes) {
    return window.Settings as WindowSettings
  }
 
  return null
}

Cas 1 : JSON distant (recommandé)

<script>
  window.OpenPatchConfig = { jsonUrl: '/patchnotes.json' }
  window.Settings = {
    projectId: "mon-app",
    options: { closeButtonText: "OK" },
    css: { primaryColor: "#4CAF50" }
  }
</script>
<script src="openpatch.es.js" type="module"></script>
patchnotes.json
{
  "version": "2.1.0",
  "patchnotes": {
    "title": "Nouveautés",
    "sections": [{ "title": "Features", "items": ["Mode sombre"] }]
  }
}

Avantage clé : pour mettre à jour les patch notes, on modifie uniquement patchnotes.json. Pas de redéploiement de l'application.

Cas 2 : configuration inline

<script>
  window.Settings = {
    projectId: "mon-app",
    version: "2.1.0",
    patchnotes: {
      title: "Nouveautés",
      sections: [{ title: "Features", items: ["Mode sombre"] }]
    },
    options: { closeButtonText: "Compris !" },
    css: { primaryColor: "#0f172a" }
  }
</script>
<script src="openpatch.es.js" type="module"></script>

Tout dans l'HTML — plus simple, mais nécessite un déploiement pour chaque mise à jour.

API window.OpenPatch

Après l'init, le widget est contrôlable depuis n'importe quel script :

// Forcer l'affichage (bouton "Voir les nouveautés")
document.querySelector('#changelog-btn').addEventListener('click', () => {
  window.OpenPatch.show()
})
 
// Réinitialiser pour retester
window.OpenPatch.reset()
Précédent
Le composable useOpenPatch
Suivant
Build dual-mode et publication npm

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