Difficile d’être serein quand on déploie une app sans être sûr que l’on sera alerté des erreurs rencontrés par les utilisateurs ! De nombreux services comme Sentry ou Rollbar le permettent, pour ma part j’utilise Bugsnag (question de préférences ou de prix). C’est devenu indispensable pour moi, mais c’est toujours aussi complexe à intégrer au tooling et au processus de déploiement continu, donc voici un retour d’expérience d’une mise en place avec Webpack. Attention je ne parle pas ici de comment intercepter les erreurs dans l’app elle-même !
1️⃣ Installer les plugins
Ajouter les dépendances :
yarn add -D webpack-bugsnag-plugins
Puis les importer dans votre config Webpack :
const { BugsnagBuildReporterPlugin, BugsnagSourceMapUploaderPlugin } = require(‘webpack-bugsnag-plugins’)
2️⃣ Créer une nouvelle release
Pour plus de simplicité, je me base sur le hash du commit courant pour nommer la release, en ajoutant une variable d’environnement temporaire RELEASE
au moment du build (ici en utilisant Nuxt) :
"generate": "RELEASE=$(git rev-parse HEAD) nuxt build"
3️⃣ Rapporter la release à Bugsnag
Utilisons le premier plugin fourni par Bugsnag pour l’informer d’une nouvelle release :
new BugsnagBuildReporterPlugin({
apiKey: 'XXX',
appVersion: process.env.RELEASE,
releaseStage: 'production'
})
Si vous utilisez Webpack tel quel, il suffit d’ajouter ce plugin à la propriété plugins
de votre configuration : https://webpack.js.org/concepts/plugins/#configuration
Si vous utilisez Nuxt, il faut l’ajouter à la propriété build
du fichier nuxt.config.js
: https://nuxtjs.org/api/configuration-build#extend
export default {
build: {
extend (config, { isClient }) {
if (!isDev && isClient) {
config.plugins.push(
new BugsnagBuildReporterPlugin({
apiKey: 'XXX',
appVersion: process.env.RELEASE,
releaseStage: 'production'
})
)
}
}
}
}
Notez aussi que seul les fichiers côté client
sont concernés, puisque Bugsnag est pensé pour gérer les navigateurs et non pas le serveur. Il est probable de pouvoir gérer les deux, mais je n’en ai pas eu l’utilité donc je n’ai pas testé cet aspect.
4️⃣ Générer les sourcemaps
Les rapports d’erreurs seront peu utiles s’ils renvoient vers les lignes des fichiers compilés et illisibles. Les sourcemaps
permettent de lier celles-ci aux lignes de codes correspondantes dans les fichiers source. Webpack les génère automatiquement en ajoutant cette configuration : https://webpack.js.org/configuration/devtool/#devtool
{
"devtool": "#source-map"
}
Avec Nuxt, même principe, on modifie la config
à la volée :
export default {
build: {
extend (config, { isClient }) {
if (!isDev && isClient) {
config.devtool = '#source-map'
}
}
}
}
5️⃣ Transférer les sourcemaps
Ne reste plus qu’à transmettre des fichiers à Bugsnag en utilisant le deuxième plugin fourni :
new BugsnagSourceMapUploaderPlugin({
apiKey: 'XXX',
appVersion: process.env.RELEASE,
releaseStage: 'production',
overwrite: true,
})
La propriété overwrite
permet d’écraser des fichiers au nom identique. Si vous laissez à false
(par défaut), en cas de build identique (si vous déployez deux fois le même commit, ou bien si les fichiers n’ont pas été modifiés), Webpack créera une erreur qui bloquera le processus entier ; donc je conseille de laisser à true
à défaut d’une solution plus élégante.
Si vous utilisez Nuxt, comme d’habitude, on modifie la config
à la volée :
if (!isDev && isClient) {
config.devtool = '#source-map'
config.plugins.push(
new BugsnagSourceMapUploaderPlugin({
apiKey: 'c1e2241fdaa9785ed9f9288526498ae4',
appVersion: process.env.RELEASE,
releaseStage: 'production',
overwrite: true,
})
)
}
6️⃣ Éviter les sourcemaps lisibles en production
Pour que vos sourcemaps ne soient pas déployés en même temps que le reste de l’app et empêcher les curieux de fouiller trop facilement dans vos fichiers sources, il suffit de les supprimer en fin de script :
"generate": "RELEASE=$(git rev-parse HEAD) nuxt generate && rm dist/**/*.map"
⏭ Résumé
Voilà l’ensemble de la configuration nécessaire pour intégrer Bugsnag à vos build Webpack :
⤴️ Aller plus loin ?
LogRocket est un service complémentaire spécialisé dans le suivi du parcours utilisateur avant que l’erreur apparaisse. C’est un plus qui peut paraître superflu, mais si vous utilisez un gestionnaire d’état (Vuex pour Vue, Redux pour React, etc.) LogRocket permet de garder un historique des mutations. Je n’ai pas encore poussé aussi loin, mais le résultat semble prometteur :