Créer des applications de bureau avec Electron et Vue
Publié: 2022-03-10JavaScript était autrefois connu comme le langage de création de sites Web et d'applications Web, en particulier avec certains de ses frameworks tels que React, Vue et Angular, mais au fil du temps (dès 2009), il est devenu possible pour JavaScript de s'exécuter en dehors du navigateur avec le émergence de Node.js, un environnement d'exécution JavaScript open source et multiplateforme qui exécute du code JavaScript en dehors d'un navigateur Web. Cela a conduit à la possibilité d'utiliser JavaScript pour bien plus que de simples applications Web, et l'une d'elles consiste à créer des applications de bureau à l'aide d'Electron.js.
Electron vous permet de créer des applications de bureau avec du JavaScript pur en fournissant un environnement d'exécution avec de riches API natives (système d'exploitation). Vous pouvez le voir comme une variante du runtime Node.js qui se concentre sur les applications de bureau au lieu des serveurs Web.
Dans ce tutoriel, nous allons apprendre à créer des applications de bureau à l'aide d'Electron, nous allons également apprendre à utiliser Vuejs pour créer des applications Electron.
Remarque : Une connaissance de base de Vue.js et de Vue CLI est nécessaire pour suivre ce tutoriel. Tout le code utilisé dans ce tutoriel se trouve sur mon GitHub. N'hésitez pas à cloner et à jouer avec !
Que sont les applications de bureau ?
Les applications de bureau sont des applications qui s'exécutent de manière autonome sur des ordinateurs de bureau ou portables. Ce sont des applications qui effectuent des tâches spécifiques et sont installées uniquement à cette fin.
Un exemple d'application de bureau est votre Microsoft Word, qui est utilisé pour créer et taper des documents. D'autres exemples d'applications de bureau courantes sont les navigateurs Web, Visual Studio Code et Adobe Photoshop. Les applications de bureau sont différentes des applications Web car vous devez installer l'application de bureau pour pouvoir y accéder et l'utiliser, et elles n'ont parfois pas besoin d'un accès Internet pour fonctionner. Les applications Web, d'autre part, sont accessibles en visitant simplement l'URL sur laquelle une telle application est hébergée et ont toujours besoin d'un accès Internet avant de pouvoir y accéder.
Voici des exemples de frameworks utilisés dans la création d'applications de bureau :
- Java
Java est un langage de programmation à usage général basé sur les classes, orienté objet et conçu pour avoir le moins de dépendances d'implémentation possible. Il est destiné à permettre aux développeurs d'applications d' écrire une fois, de s'exécuter n'importe où (WORA), ce qui signifie que le code Java compilé peut s'exécuter sur toutes les plates-formes prenant en charge Java sans nécessiter de recompilation. - Effets Java
Selon leur documentation officielle, il s'agit d'une plate-forme d'application cliente open source de nouvelle génération pour les systèmes de bureau, mobiles et embarqués construits sur Java. - C#
C # est un langage de programmation multi-paradigme à usage général englobant les disciplines de programmation à typage fort, à portée lexicale, impérative, déclarative, fonctionnelle, générique, orientée objet et orientée composant. - .RAPPORTER
.NET est une plate-forme de développement gratuite, multiplateforme et open source permettant de créer de nombreux types d'applications différents. Avec .NET, vous pouvez utiliser plusieurs langages, éditeurs et bibliothèques pour créer pour le Web, les appareils mobiles, les ordinateurs de bureau, les jeux et l'IoT.
Qu'est-ce que l'électron ?
Electron est un framework open source pour la création d'applications de bureau. Il était auparavant connu sous le nom de "Atom shell" et est développé et maintenu par GitHub. Il vous permet d'écrire des applications de bureau multiplateformes en utilisant HTML, CSS et JavaScript. Cela signifie que vous pouvez créer des applications de bureau pour Windows, MacOS et d'autres plates-formes en utilisant une seule base de code. Il est basé sur Node.js et Chromium. Des exemples d'applications créées avec Electron incluent le célèbre éditeur Atom, Visual Studio Code, Wordpress pour ordinateur de bureau et Slack.
Installation
Vous pouvez installer Electron dans votre projet en utilisant NPM :
npm install electron --save-dev
Vous pouvez également l'installer globalement si vous allez beaucoup travailler avec des applications électroniques en utilisant cette commande :
npm install electron -g
Création d'applications Vuejs pour ordinateur de bureau avec Electron
Si vous êtes familiarisé avec la création d'applications Web à l'aide de Vuejs, il est possible de créer des applications de bureau à l'aide de Vuejs. Tout ce dont vous avez besoin pour cela est le générateur d'électrons Vue CLI Plugin.
Le générateur d'électrons du plugin Vue CLI
Cet outil vous permet de créer des applications Vue pour ordinateur avec Electron, cela signifie qu'il fait fonctionner votre application Vue comme une application électronique. Cela signifie que votre application Vue, qui est peut-être une application Web, peut être étendue pour fonctionner dans des environnements de bureau sans qu'il soit nécessaire de créer une application de bureau distincte dans un autre cadre. Cela donne aux développeurs Vue la possibilité et le pouvoir d'aller au-delà du Web. À l'avenir, vous pouvez travailler sur cette idée que vous avez et donner aux utilisateurs une option d'application de bureau, qui peut s'exécuter sur Windows, macOS et Linux.
Pour voir cela en action, nous allons créer une application News à l'aide de l'API News. L'application fournira les derniers titres de l'actualité et vous permettra de rechercher des articles provenant de sources d'actualités et de blogs sur tout le Web avec leur API. Tout ce dont vous avez besoin pour commencer avec eux est votre clé API personnelle qui peut être obtenue à partir d'ici.
Nous allons créer une application simple qui offre les éléments suivants :
- Une page qui affiche les titres les plus importants et les plus récents d'un pays sélectionné avec la possibilité de choisir un pays à l'aide de son point de terminaison
/top-headlines
. L'API News fournit des actualités à partir d'une liste de pays pris en charge, trouvez la liste ici. - Nouvelles d'une catégorie sélectionnée en utilisant une combinaison de leur point de terminaison
/everything
et d'un paramètre de requêteq
avec lequel nous spécifierons notre catégorie.
Après avoir obtenu votre clé API, nous pouvons créer notre application à l'aide de Vue CLI. Assurez-vous que la CLI Vue est installée sur votre système, si ce n'est pas le cas, installez-la à l'aide de cette commande :
npm install -g @vue/cli # OR yarn global add @vue/cli
Une fois cela fait, créez votre application News à l'aide de la CLI :
vue create news-app
Nous allons récupérer les données de l'API News en utilisant Axios pour ce didacticiel, mais vous pouvez utiliser n'importe quelle alternative avec laquelle vous êtes plus à l'aise. Vous pouvez installer Axios à l'aide de l'une des commandes suivantes :
//NPM npm install axios // YARN yarn add axios
La prochaine étape consisterait à configurer une instance Axios pour la configuration globale dans notre application. Nous allons créer un dossier plugins dans le dossier src où nous allons créer ce fichier axios.js . Après avoir créé le fichier, ajoutez les lignes de code suivantes :
import axios from "axios"; let baseURL = `https://newsapi.org/v2`; let apiKey = process.env.VUE_APP_APIKEY; const instance = axios.create({ baseURL: baseURL, timeout: 30000, headers: { "X-Api-Key": apiKey, }, }); export default instance;
Ici, nous définissons notre baseURL
et apiKey
que nous avons obtenus de l'API News et les transmettons à une nouvelle instance d'Axios. Cette instance accepte la baseURL
et l' apiKey
avec une propriété timeout
. L'API News vous demande d'ajouter votre clé API lorsque vous faites une demande à leur API et propose 3 façons de l'attacher à votre demande mais ici, nous l'ajoutons à la propriété header X-Api-Key
après quoi nous exportons instance
. Une fois cela fait, nous pouvons maintenant utiliser cette configuration pour toutes nos requêtes Axios dans notre application.
Lorsque cela est fait, vous pouvez ajouter le constructeur Plugin Electron avec la CLI en utilisant cette commande :
vue add electron-builder
Vous serez invité à sélectionner votre version préférée d'Electron, j'ai sélectionné la version 9.0.0
car il s'agit de la dernière version d'Electron (au moment de la rédaction).
Lorsque cela est fait, vous pouvez maintenant servir votre application en utilisant cette commande :
Using Yarn(strongly recommended) yarn electron:serve OR NPM npm run electron:serve
Cela prendra un certain temps pour compiler et servir votre application. Lorsque cela est fait, votre application s'ouvrira sur votre système, cela devrait ressembler à ceci :
Si vous fermez les outils de développement de votre application, cela devrait ressembler à ceci :
Ce plugin électronique est super utile et facile à utiliser car chaque partie du développement de cette application fonctionne de la même manière qu'une application Vue. Cela signifie que vous pouvez avoir une seule base de code pour votre application Web et votre application de bureau. Notre application comportera trois parties :
- Une page de destination qui affiche les principales actualités d'un pays choisi au hasard.
- Une page pour afficher les principales actualités du pays de choix de l'utilisateur.
- Une page qui affiche les principales actualités d'une catégorie de la sélection de l'utilisateur.
Pour cela, nous allons avoir besoin d'un composant d'en-tête pour tous nos liens de navigation. Créons donc un fichier dans le dossier des composants et nommons-le header.vue , puis ajoutons-y les lignes de code suivantes :
<template> <header class="header"> <div class="logo"> <div class="logo__container"> <img src="../assets/logo.png" alt="News app logo" class="logo__image" /> </div> <h1>News App</h1> </div> <nav class="nav"> <h4 class="nav__link"> <router-link to="/home">Home</router-link> </h4> <h4 class="nav__link"> <router-link to="/top-news">Top News</router-link> </h4> <h4 class="nav__link"> <router-link to="/categories">News By Category</router-link> </h4> </nav> </header> </template> <script> export default { name: "app-header", }; </script> <style> .header { display: flex; flex-wrap: wrap; justify-content: space-between; } .logo { display: flex; flex-wrap: nowrap; justify-content: space-between; align-items: center; height: 50px; } .logo__container { width: 50px; height: 50px; } .logo__image { max-width: 100%; max-height: 100%; } .nav { display: flex; flex-wrap: wrap; width: 350px; justify-content: space-between; } </style>
Ici, nous créons un composant d'en-tête contenant le nom et le logo de notre application (l'image peut être trouvée sur mon GitHub) ainsi qu'une section de navigation contenant des liens vers les autres parties de notre application. La prochaine chose serait d'importer cette page sur notre page de mise en page - App.vue afin que nous puissions voir notre en-tête sur chaque page.
<template> <div> <app-header /> <router-view /> </div> </template> <script> import appHeader from "@/components/Header.vue"; export default { name: "layout", components: { appHeader, }, }; </script> <style> @import url("https://fonts.googleapis.com/css2?family=Abel&family=Staatliches&display=swap"); html, #app { min-height: 100vh; } #app { font-family: "Abel", sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; background-color: #fff; } #app h1 { font-family: "Staatliches", cursive; } a { font-weight: bold; color: #2c3e50; text-decoration: none; } a:hover { text-decoration: underline; } a.router-link-exact-active { color: #42b983; } </style>
Ici, nous remplaçons le contenu par défaut dans la section template par notre composant d'en-tête nouvellement créé après l'avoir importé et déclaré dans la section script. Enfin, nous ajoutons un style pour l'ensemble de l'application dans la section style.
Maintenant, si nous essayons de voir notre application, elle devrait ressembler à ceci :
La prochaine étape serait d'ajouter du contenu à notre fichier Home.vue . Cette page hébergerait la première section de notre application ; Top news d'un pays sélectionné au hasard. Mettez à jour votre fichier Home.vue avec les lignes de code suivantes :
<template> <section class="home"> <h1>Welcome to News App</h1> <h4>Displaying Top News from {{ countryInfo.name }}</h4> <div class="articles__div" v-if="articles"> <news-card v-for="(article, index) in articles" :key="index" :article="article" ></news-card> </div> </section> </template> <script> import { mapActions, mapState } from "vuex"; import NewsCard from "../components/NewsCard"; export default { data() { return { articles: "", countryInfo: "", }; }, components: { NewsCard, }, mounted() { this.fetchTopNews(); }, computed: { ...mapState(["countries"]), }, methods: { ...mapActions(["getTopNews"]), async fetchTopNews() { let countriesLength = this.countries.length; let countryIndex = Math.floor( Math.random() * (countriesLength - 1) + 1 ); this.countryInfo = this.countries[countryIndex]; let { data } = await this.getTopNews( this.countries[countryIndex].value ); this.articles = data.articles; }, }, }; </script> <style> .articles__div { display: flex; flex-wrap: wrap; justify-content: center; } </style>
Dans la section script de ce fichier, nous importons mapState
et mapActions
de Vuex, que nous utiliserons plus tard dans ce fichier. Nous importons également un composant NewsCard
(nous le créerons ensuite) qui affichera tous les titres de l'actualité sur cette page. Nous utilisons ensuite la méthode fetchTopNews
pour récupérer les dernières nouvelles d'un pays sélectionné au hasard parmi l'éventail de countries
de notre boutique. Ce pays est transmis à notre action getTopNews
, il serait ajouté à la baseURL
en tant que requête pour un pays comme baseURL/top-news?country=${randomCountry}
. Une fois cela fait, nous parcourons ces données et les transmettons à l'accessoire d' article
de notre composant Newscard
dans la section modèle. Nous avons également un paragraphe qui indique de quel pays proviennent les principales nouvelles.
La prochaine chose serait de configurer notre composant NewsCard
qui affichera ces nouvelles. Créez un nouveau fichier dans votre dossier de composants , nommez-le NewsCard.vue et ajoutez-y les lignes de code suivantes :
<template> <section class="news"> <div class="news__section"> <h1 class="news__title"> <a class="article__link" :href="article.url" target="_blank"> {{ article.title }} </a> </h1> <h3 class="news__author" v-if="article.author">{{ article.author }}</h3> <!-- <p class="article__paragraph">{{ article.description }}</p> --> <h5 class="article__published">{{ new Date(article.publishedAt) }}</h5> </div> <div class="image__container"> <img class="news__img" src="../assets/logo.png" :data-src="article.urlToImage" :alt="article.title" /> </div> </section> </template> <script> export default { name: "news-card", props: { article: Object, }, mounted() { this.lazyLoadImages(); }, methods: { lazyLoadImages() { const images = document.querySelectorAll(".news__img"); const options = { // If the image gets within 50px in the Y axis, start the download. root: null, // Page as root rootMargin: "0px", threshold: 0.1, }; const fetchImage = (url) => { return new Promise((resolve, reject) => { const image = new Image(); image.src = url; image.onload = resolve; image.onerror = reject; }); }; const loadImage = (image) => { const src = image.dataset.src; fetchImage(src).then(() => { image.src = src; }); }; const handleIntersection = (entries) => { entries.forEach((entry) => { if (entry.intersectionRatio > 0) { loadImage(entry.target); } }); }; // The observer for the images on the page const observer = new IntersectionObserver(handleIntersection, options); images.forEach((img) => { observer.observe(img); }); }, }, }; </script> <style> .news { width: 100%; display: flex; flex-direction: row; align-items: flex-start; max-width: 550px; box-shadow: 2px 1px 7px 1px #eee; padding: 20px 5px; box-sizing: border-box; margin: 15px 5px; border-radius: 4px; } .news__section { width: 100%; max-width: 350px; margin-right: 5px; } .news__title { font-size: 15px; text-align: left; margin-top: 0; } .news__author { font-size: 14px; text-align: left; font-weight: normal; } .article__published { text-align: left; } .image__container { width: 100%; max-width: 180px; max-height: 180px; } .news__img { transition: max-width 300ms cubic-bezier(0.4, 0, 1, 1), max-height 300ms cubic-bezier(0.4, 0, 1, 1); max-width: 150px; max-height: 150px; } .news__img:hover { max-width: 180px; max-height: 180px; } .article__link { text-decoration: none; color: inherit; } </style>
Ici, nous affichons les données transmises à ce composant à l'aide de la propriété d'objet article
. Nous avons également une méthode qui charge paresseusement les images attachées à chaque article. Cette méthode parcourt le nombre d'images d'articles que nous avons et les charge paresseusement lorsqu'elles deviennent visibles. Enfin, nous avons des styles ciblés sur ce composant dans la section style.
La prochaine chose sera de mettre en place notre magasin afin que nous puissions commencer à recevoir les dernières nouvelles. Ajoutez les lignes de code suivantes à votre fichier index.js :
import Vue from "vue"; import Vuex from "vuex"; import axios from "../plugins/axios"; Vue.use(Vuex); const store = new Vuex.Store({ state: { countries: [{ name: "United States of America", value: "us", }, { name: "Nigeria", value: "ng", }, { name: "Argentina", value: "ar", }, { name: "Canada", value: "ca", }, { name: "South Africa", value: "za", }, ], categories: [ "entertainment", "general", "health", "science", "business", "sports", "technology", ], }, mutations: {}, actions: { async getTopNews(context, country) { let res = await axios({ url: `/top-headlines?country=${country}`, method: "GET", }); return res; }, }, }); export default store;
Nous ajoutons deux propriétés à notre magasin, l'une de ces propriétés est countries
. Cette propriété contient un tableau d'objets de pays. Nous avons également la propriété categories
; celui-ci contient un tableau de catégories disponibles sur l'API News. Le lecteur aimera la liberté de voir les principales nouvelles de pays et de catégories spécifiques ; cela sera également nécessaire dans plus d'une partie de l'application et c'est pourquoi nous utilisons le magasin. Dans la section actions de notre boutique, nous avons une méthode getTopNews
qui récupère les principales actualités d'un pays (ce pays a été transmis par le composant qui a appelé cette action).
À ce stade, si nous ouvrons notre application, nous devrions voir notre page de destination qui ressemble à ceci :
Le fichier background.js
Ce fichier est le point d'entrée d'Electron dans votre application. Il contrôle tous les paramètres de type application de bureau pour cette application. L'état par défaut de ce fichier peut être trouvé sur mon GitHub.
Dans ce fichier, nous avons des configurations prédéfinies définies pour l'application, telles que la height
et la width
par défaut de votre application. Jetons un coup d'œil à certaines des choses que vous pouvez faire dans ce fichier.
Activation des outils de développement Vuejs
Par défaut, vous avez accès aux outils de développement dans Electron mais ils ne sont pas activés après l'installation. Ceci est le résultat d'un bogue existant sur Windows 10, donc si vous ouvrez votre fichier background.js , vous trouverez du code commenté avec des commentaires qui indiquent pourquoi ils sont commentés :
// Install Vue Devtools // Devtools extensions are broken in Electron 6.0.0 and greater // See https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/378 for more info // Electron will not launch with Devtools extensions installed on Windows 10 with dark mode // If you are not using Windows 10 dark mode, you may uncomment these lines // In addition, if the linked issue is closed, you can upgrade electron and uncomment these lines // try { // await installVueDevtools() // } catch (e) { // console.error('Vue Devtools failed to install:', e.toString()) // }
Donc, si vous n'êtes pas affecté par ce bogue, vous pouvez décommenter le bloc try/catch
et également rechercher installVueDevtools
dans ce même fichier (ligne 5) et également le décommenter. Une fois cela fait, votre application redémarrera automatiquement, et lorsque vous vérifierez vos outils de développement, vous devriez voir les Devtools Vuejs.
Sélection d'une icône personnalisée pour votre application
Par défaut, l'icône Electron est définie comme icône par défaut pour votre application, et la plupart du temps, vous souhaiterez probablement définir votre propre icône personnalisée. Pour ce faire, déplacez votre icône dans votre dossier public et renommez-la en icon.png . La prochaine chose à faire serait d'ajouter la dépendance requise, electron-icon-builder
.
Vous pouvez l'installer à l'aide de l'une des commandes suivantes :
// With Yarn: yarn add --dev electron-icon-builder // or with NPM: npm install --save-dev electron-icon-builder
Une fois cela fait, vous pouvez exécuter cette commande suivante. Il convertira votre icône au format Electron et imprimera ce qui suit dans votre console lorsque cela sera fait.
La prochaine chose serait de définir l'option d'icône dans le fichier background.js . Cette option va à l'intérieur de l'option BrowserWindow
qui est importée d' Electron
. Pour ce faire, mettez à jour BrowserWindow
pour qu'il ressemble à ceci :
// Add this to the top of your file /* global __static */ // import path import path from 'path' // Replace win = new BrowserWindow({ width: 800, height: 600 }) // With win = new BrowserWindow({ width: 800, height: 600, icon: path.join(__static, 'icon.png') })
Maintenant, si nous exécutons yarn run electron:build
et visualisons notre application, nous devrions voir l'icône mise à jour utilisée comme icône de l'application, mais cela ne change pas au cours du développement. Ce problème permet de résoudre un correctif manuel pour celui-ci sur macOS.
Définir le titre de votre application
Vous remarquerez que le titre de votre application est défini sur le nom de l'application (news-app dans ce cas) et nous devrons le modifier. Pour ce faire, nous devons ajouter une propriété title
à la méthode BrowserWindow
dans notre fichier background.js
comme ceci :
win = new BrowserWindow({ width: 600, height: 500, title: "News App", icon: path.join(__static, "icon.png"), webPreferences: { // Use pluginOptions.nodeIntegration, leave this alone // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION, }, });
Ici, nous définissons le titre de notre application sur "News App". Mais si votre fichier index.html a un titre sélectionné ou si votre titre ne change pas, essayez d'ajouter ce code à votre fichier :
win.on("page-title-updated", (event) => event.preventDefault());
Nous sommes à l'écoute d'un événement qui se déclenche lorsque notre title
est mis à jour depuis BrowserWindow
. Lorsque cet événement est déclenché, nous disons à Electron de ne pas mettre à jour le titre avec celui trouvé dans le fichier index.html .
Une autre chose qui pourrait valoir la peine d'être modifiée est le productName
, cela contrôle le nom qui apparaît lorsque vous survolez l'icône de votre application ou ce que votre ordinateur reconnaît comme l'application. À l'heure actuelle, le nom de notre application est Electron
. Pour changer ce nom en production, créez un fichier vue.config.js et ajoutez-y les lignes de code suivantes :
module.exports = { pluginOptions: { electronBuilder: { builderOptions: { productName: "News App", }, }, }, };
Ici, nous définissons productName
comme étant 'News App' de sorte que lorsque nous exécutons la commande de construction pour notre application, le nom passe de 'Electron' à 'News App'.
Construction multiplateforme
Par défaut, lorsque vous exécutez la commande build, l'application créée dépend de la plate-forme sur laquelle elle est exécutée. Cela signifie que si vous exécutez la commande build sous Linux, l'application créée sera une application de bureau Linux. Il en va de même pour les autres plates-formes (macOS et Windows). Mais Electron offre la possibilité de spécifier une plate-forme (ou deux plates-formes) que vous souhaitez générer. Les options disponibles sont :
-
mac
-
win
-
linux
Ainsi, pour créer la version Windows de votre application, exécutez la commande suivante :
// NPM npm electron:build -- --win nsis // YARN yarn electron:build --win nsis
Conclusion
L'application complète peut être trouvée sur mon GitHub. La documentation officielle d'Electron fournit des informations et un guide qui vous aide à personnaliser votre application de bureau comme vous le souhaitez. Certaines des choses que j'ai essayées mais qui ne sont pas incluses dans ce tutoriel sont:
- Personnalisation de votre dock sur macOS — https://www.electronjs.org/docs/tutorial/macos-dock.
- Réglage redimensionnable, maximisable et bien d'autres - https://github.com/electron/electron/blob/master/docs/api/browser-window.md#new-browserwindowoptions.
Donc, si vous cherchez à faire beaucoup plus avec votre application Electron, leur documentation officielle est un bon point de départ.
Ressources associées
- Node.jshttps://en.wikipedia.org/wiki/Node.js
- Java (langage de programmation)https://en.wikipedia.org/wiki/Java_(langage_de_programmation)
- Electron (cadre logiciel)
- JavaFX 14
- electronjs
- Documentation électronique
- Générateur d'électrons du plugin Vue CLI
- Chargement paresseux d'images pour la performance à l'aide d'Intersection Observer par Chris Nwamba
- axios
- Premiers pas avec Axios dans Nuxthttps://www.smashingmagazine.com/2020/05/getting-started-axios-nuxt/) par Timi Omoyeni