,

Tour d’horizon du développement Chrome Apps

En Septembre 2013, Google annonçait un nouveau type d’applications Chrome beaucoup plus intégrées et qui agissent comme des applications natives sur l’OS. Ces premières applications ont été mises à disposition pour les versions de Chrome Desktop dans un premier temps, puis annoncée sur plateformes mobiles en Janvier. De quoi entrer dans l’ère des applications natives multi-device.

Developpement de Chrome Apps : tutoriel

Une application Chrome, c’est quoi ?

Une application Chrome (« Chrome App ») est avant tout une application développée avec les technologies du Web : HTML5, JavaScript et CSS. Ces langages vont constituer la base de l’application. On tire ensuite parti des possibilités nouvelles d’HTML5 et des API spécifiques de Chrome pour enrichir l’application. Et c’est surtout sur ce dernier point que Chrome va apporter tout son intérêt car l’API est ouverte et propose un éventail de fonctionnalités permettant d’aller beaucoup plus loin que des applications Web puisqu’il donne l’accès aux routines plus proches de l’OS et du matériel. L’application va donc pouvoir se comporter comme une application de  bureau  tout en tirant parti des facilités de développement en HTML et JS.

Avant d’aller plus loin et éviter les confusions, nous allons d’abord faire un rappel sur la différence entre une application Web, application Chrome, et extension Chrome.

Application Web vs Application Chrome ?

Une application Web est un site « enrichi » en tirant parti de JavaScript et des fonctionnalités d’HTML5 pour offrir une expérience améliorée à l’utilisateur mais s’exécutant dans le navigateur. L’application Web est « connectée » et standard (indépendante du navigateur).

Une Chrome App est une application de bureau et offre une grande immersion à l’utilisateur en tirant parti de l’OS et des capacités matérielles. L’application Chrome est prévue pour fonctionner en mode déconnectée et s’appuie fortement sur les fonctionnalités du navigateur.

Application Chrome ou extension Chrome ?

Quelle différence entre une extension et une application Chrome : la calculetteUne extension est un complément de Chrome, elle n’a pas de fonction propre en dehors de Chrome. Elle permet d’ajouter des fonctionnalités supplémentaires à Chrome (par exemple accessibles via un nouveau bouton dans la barre d’adresse).

Les applications sont, quant à elles, indépendantes et autonomes. Une application s’appuie sur Chrome seulement pour son exécution, mais elle en est indépendante.

Exemple d’application Chrome « Calculette ». Elle utilise le thème natif de l’OS sur lequel elle s’exécute.

Généralité

Avant d’entrer plus en détails, voici quelques généralités des Chrome Apps :

Mode Offline

Une Chrome App est déconnectée par défaut. Cela permet de mettre en avant l’approche offline first et concevoir l’application pour fonctionner non seulement en étant déconnecté, mais surtout pour répondre plus facilement aux cas pour lesquels le réseau est lent, pas fiable, ou si les serveurs sont indisponibles temporairement. L’application Chrome apporte un plus ici car l’intégralité du package de l’application est téléchargée et disponible sans nécessité de connexion ultérieure pour son exécution.

Multi-device, multi-plateforme

Une Chrome App fonctionne sur la plupart des plateformes populaires sur lesquelles Chrome existe : Windows, Mac OS, GNU/Linux, mais aussi Android et IOS.

Immersif

L’application Chrome interagit avec l’OS hôte et avec le matériel (USB, Bluetooth, socket TCP, etc.). L’application est intégrée à l’OS (raccourcis, style de fenêtre adaptée, mode plein-écran)

Distribué

L’application Chrome est distribuée et mise à jour via Chrome Web Store. Cette approche permet également de simplifier la monétisation de l’application mais également des feedbacks rapides et facilités des développeurs.

Cloud

Une application Chrome est « cloud-enabled » par défaut. C’est-à-dire, que l’API propose des accès aux services Google permettant de faciliter le travail du développeur qui n’a rien de plus à coder pour les accès aux données, notamment les services Storage Sync, syncFileSystem, pushMessaging API.

Sécurisé et isolé

Les Chrome Apps implémentent Content Security Policy : en Javascript, pas d’utilisation de eval(), new Function, etc. L’exécution des processus est isolée (principe de Sandboxing) : un plantage d’une application Chrome ne fera pas planter l’application voisine. Même principe de Sandboxing concernant le stockage des données applicatives qui est, lui aussi, isolé. Autre point de sécurité une application Chrome n’a accès qu’aux API Web standard et Chrome Apps, mais ne dispose pas des accès aux API de Chrome Extensions.

Le lanceur d’applications Chrome

L’intérêt de toutes ces fonctionnalités est évidemment l’intégration à Chrome OS. Toutes applications de Chrome OS sont des Chrome Apps, mais il est possible d’en tirer parti dès aujourd’hui directement au sein de votre OS habituel.

Lanceur d'applications Chrome

Dès la première installation d’une application Chrome depuis le Web Store, le lanceur d’application Chrome va s’installer. Ce lanceur répertorie toutes les Chrome Apps et constitue un point central pour le lancement des applications, sans avoir à lancer le navigateur Chrome.

Il permet également de créer des raccourcis directement sur le bureau ou la barre des tâches pour faciliter d’avantage l’accès aux applications.

Maintenant que l’on connaît les généralités sur les applications Chrome, voyons en détail comment elles sont constituées et comment en programmer une.

Comment créer une application avec Chrome

 

Organisation des sources du projet

Une Chrome App est organisée comme un projet Web classique (index.html, assets) et comporte plusieurs fichiers complémentaires : le Manifest, le background page et les icônes :

assets/
       images/
       scripts/
       css/ 
 manifest.json
 main.js
 index.html
 icon16.png
 icon48.png
 icon128.png

Le Manifest

Le Manifest (manifest.json) est un fichier important nécessaire à l’application Chrome. Il décrit son point d’entrée, ses ressources, ses autorisations d’accès. Il est décrit au format JSON. Les informations minimales sont le nom et la version. Ainsi, une version minimale pourrait être définie comme :

{
  "manifest_version": 2,
  "name": "My App",
  "version": "versionString",
  "default_locale": "en",
  "description": "A plain text description",
  "icons": {...},
  "app": {
    "background": {
            "scripts": ["background.js"]
    },
  },
  "permissions": ["<all_urls>"]
}

On retrouve ces principales informations :

  • Le descriptif de l’application : nom, version, description, locale (langue)
  • Le fichier « point d’entrée » de l’application (background)
  • Les icônes associées (icons)
  • Les permissions (permissions)
  • Informations et paramétrages spécifiques aux API (storage, webviews, usb, bluetooth), au système de mise à jour, version minimale de Chrome (sur lesquels on ne va pas s’étendre dans cet article).

En savoir plus sur le contenu du manifest.

Revenons plus en détails sur les permissions, icônes et point d’entrée dans les 3 prochains chapitres.

Les permissions

Pour utiliser la plupart des API, l’application doit déclarer explicitement ses intentions dans le manifeste. Les permissions sont ensuite affichées à l’utilisateur permettant de savoir quels sont les besoins de l’application. Les permissions aident à limiter les dommages si l’application est compromise par des malwares. Certaines permissions peuvent être facultatives. Les permissions peuvent être affichées à l’utilisateur avant l’installation (ou à tout moment sur la page des extensions chrome://extensions).

Parmi les permissions les plus utiles, le pattern « [scheme]:[host]/* » spécifie les URL vers lesquelles l’application souhaite communiquer. En effet, pour éviter les attaques de types XSS, il est nécessaire d’indiquer explicitement toutes les URL auxquelles on souhaite accéder. Heureusement ici, il est possible de faire du Pattern Matching pour nous faciliter la tâche.
Quelques exemples :

  • http://*/* : toutes les URL qui matchent le protocole http. Par exemple http://www.google.com/
  • file:///foo* : tous les accès aux fichiers locaux dont les fichiers commencent par foo*
  • <all_urls> : matche toutes les URL

Parmi les autres permissions, on retrouve les accès aux alarmes (alarms), notifications (notifications), périphérique USB (usb), synthèse vocale (tts) stockage (storage), video (videoCapture), etc. La liste des permissions complète est disponible à cette adresse : https://developer.chrome.com/apps/declare_permissions. Dans tous les cas, la documentation de l’API de Chrome indiquera toujours quelles permissions accorder pour qu’une API soit utilisable.
Les permissions apparaissent dans le Manifest.

"permissions": [
  "serial",
  "storage",
  "videoCapture"
],

 

Le point d’entrée de l’application

L’Event page est référencée dans le Manifest par le mot-clé « background » et indique un fichier Javascript associé. C’est ce fichier JS qui va constituer le point d’entrée de l’application en agissant sur les évènements systèmes liés à l’application (lancement, redémarrage). Nous préconisons de bien prendre en compte le nouveau modèle de chargement évènementiel Event page dont le détail est expliqué ici. L’ancienne façon de faire, appelée, « Background page », bien qu’elle soit toujours opérationnelle, n’est pas préconisée car moins performante.

Les évènements de pages ne sont lancés qu’en cas de besoin et respectent le cycle de vie applicatif. L’évènement chrome.app.runtime.onLaunched est appelé au lancement de l’application. Nous lui associons une fonction grâce à addListener. Dans la fonction associée, nous créons une nouvelle fenêtre, avec la page « index.html » en indiquant la taille et position de la fenêtre. Le cœur du traitement de l’application est ensuite fait depuis la page « index.html », comme une application web standard.

chrome.app.runtime.onLaunched.addListener(function() {

  chrome.app.window.create('index.html', {
    id: "helloWorldID",
    bounds: {
      width: 500,
      height: 300,
      left: 0,
      top:0
    }
  });
});

Les icônes

Une ou plusieurs icônes représentant l’application sont à fournir. Au moins une : idéalement en format 128×128 pixels. C’est cette icône qui sera utilisée pour représenter l’application sur la page des applications, page de management, barre d’outils, etc. Il est préférable d’utiliser le format PNG car il offre une gestion de la transparence sans perte de qualité. La taille 48 est utilisée sur la page d’administration de l’application (celle qui apparaît sous Chrome://extensions).

"icons": { "16": "icon16.png",
           "48": "icon48.png",
          "128": "icon128.png" }

Attention toutefois, pour la phase de publication sur le Google Web Store, il sera également nécessaire de fournir une autre série d’images, les screenshots. Il est conseillé de mettre au moins la version 128. Chrome ajustera les autres tailles en se basant sur l’image en meilleure résolution s’il ne trouve pas les tailles plus réduites.

Attention à bien respecter les tailles documentées et leurs tailles associées (128×128 pixels pour « 128 », 48×48 pixels pour « 48 ») afin de ne pas avoir de surprise lorsque Chrome tentera de redimensionner ces images.

En savoir plus sur les icônes.

Quelles API ?

Le nombre d’API disponibles pour les Chrome Apps est conséquent : Bluetooth, menu contextuels, système de fichiers, fenêtres sans cadre, plein-écran, géolocalisation, UserMedia (capture de son, vidéo), HID, identité (OAuth2), monétisation in-app, gallerie de média, Google Cloud Messaging, Impression, notifications enrichies, port série, Socket UDP/TCP, stockage, SyncFileSystem, Synthèse vocale, informations systèmes, USB, WebStore, WebView.

Une page d’exemples répertorie des cas types pour un grand nombre de ces API.

A contrario, certaines API Web ont été dépréciées, car elles sont considérées comme des mauvaises pratiques d’interactions, peu performantes ou tout simplement pas adaptées aux applications natives. Ainsi, on ne pourra pas utiliser les window.alert, window.confirm, showModalDialogdocument.cookie, document.close, document.open, document.write, la navigation avec URL ou ancres, Flash, la soumission de formulaire, le local storage, WebSQL ou encore  les requêtes XmlHttpRequest synchrones. On notera aussi que la sélection de texte par l’utilisateur n’est plus possible par défaut. Comment faire alors ? Faire sans ! Une page liste cependant des contournements possibles pour ces cas précis.

Pour l’édition, comme il s’agit de ressources Web, il n’y a pas d’IDE dédié spécifiquement aux sources d’un projet Chrome app, il est préférable cependant d’utiliser un IDE Web avancé tel que Sublime Text, Brackets, ou encore WebStorm.

Exemple d’API : Sync Filesystem

Nous allons nous voir un exemple de  codage en utilisant sur une des API phare : Sync FileSystem. Cette API est utile pour sauver et synchroniser les données vers Google Drive. Elle fournit un stockage spécifique à l’application synchronisable à tout moment, le développeur n’ayant pas à se soucier si l’application est connectée ou non. L’intérêt de ce type de stockage est de partager les données entre plusieurs devices.

L’appel de la fonction syncFileSystem.requestFileSystem retourne un filestystem synchronisable récupérable dans notre fonction de callback onInitFs.

 chrome.syncFileSystem.requestFileSystem(onInitFs); 

L’objet fs est un DOMFileSystem peut être opéré comme n’importe quel fichier distant ou local. Le filesystem ne supporte pas les opérations sur les répertoires : on peut obtenir la liste des fichiers depuis la racine d’un répertoire, mais pas en créer de nouveaux. Dans notre cas, la fonction de callback getEntryCallback()  récupère notre fichier une fois accessible.

function onInitFs(fs) {
    fs.root.getFile('test.txt', {create:true}, getEntryCallback, errorHandler);
}

On récupère l’objet représentant le fichier, puis utilise un FileReader pour lire son contenu. La fonction reader.onloadend est appelée une fois le contenu disponible. Il est disponible via la variable this.result.

Function getEntryCallback(fileEntry) {
    fileEntry.file(function(file) {
       var reader = new FileReader();
       reader.onloadend = function(e) {
         doSomething( this.result);
       };
       reader.readAsText(file);
}

En savoir plus sur l’API fileSystem HTML 5.

Tester son application

Une fois que notre application est correctement organisée et que les principaux fichiers sont présents, elle va pouvoir être chargée pour son exécution. Pendant la phase de développement de l’application, on charge l’application dans Chrome en mode « non-empaquetée ».

Pour charger une application, il faut ouvrir Chrome et se rendre sur la page des extensions (en tapant l’URL chrome://extensions) et cocher l’option « Mode développeur ». Une fois cette option activée, il est maintenant possible de charger l’application en indiquant le répertoire racine de l’application (celui qui contient le manifest.json)

Mode développeur : créer des applications avec Chrome

Dans ce mode, les sources sont chargées à partir de leur emplacement actuel et permet un rechargement des sources, ce qui s’avère beaucoup plus productif en phase de développement. Pour le rechargement des sources, il suffit de se positionner sur la page des extensions et faire Ctrl+R (ou cmd+R sous Mac OS)

Rechargement des sources : créer une application avec Chrome

Pendant la phase de débuggage, la console de développement de Chrome est accessible. Il s’agit bien d’une console propre à notre application et pas celle de Chrome. Pour afficher la console de développement, Clic-droit sur l’application puis « Inspecter l’élément ». Autre point à savoir : la console de développement Web n’est accessible que si l’application est chargée en mode « non-empaquetée ».

Empaqueter l’application.

Bien que les Chrome Apps et Chrome Extensions soient différentes comme on l’a vu précédemment, elles partagent néanmoins le même système d’empaquetage et de distribution. L’application doit être empaquetée pour pouvoir être distribuée. Le packaging est un « zip » accompagné d’un certificat PEM et qui nous constitue au final un package au format CRX.  Le certificat PEM est obligatoire en cas de distribution sur le Google Web Store, mais facultatif en cas de distribution hors Store. S’il n’est pas présent il sera généré automatiquement lors du premier empaquetage. Pour empaqueter l’application, deux approches :

Approche manuelle

Depuis Chrome, aller sur la page des extensions, puis cliquer sur « Empaqueter l’extension ». Sélectionner le répertoire source de la Chrome App et le certificat (si présent) puis « Empaqueter l’extension ».

Empaquetage avec Chrome

L’extension sera empaquetée dans le répertoire parent de l’application.

Empaqueter l'extension avec Chrome

Approche scriptée

Il est possible de scripter l’empaquetage de plusieurs manières. La plus simple est d’utiliser Chrome en ligne de commande. Attention à bien indiquer les chemins complets (avec le c:\…) sinon, l’empaquetage ne fonctionne pas et il n’y a pas de message d’erreur pour nous l’indiquer.

chrome.exe --pack-extension=C:\myapp --pack-extension-key=C:\myapp.pem

L’autre approche est d’utiliser l’outil de scripting de son choix ! Le format CRX est un format ouvert (consulter les spécifications du format CRX). On peut donc très facilement créer son propre script d’empaquetage.

Installer l’application

Une fois le package CRX constitué, l’application peut être installée très facilement : il suffit de glisser-déposer le fichier CRX sur la page des extensions.

Installer une application Chrome en utilisant le déplacement

Chrome propose alors de l’installer. Elle est ensuite disponible automatiquement depuis le lanceur d’applications Chrome (ou ou depuis Chrome via l’URL chrome://apps).

Comment installer une application Chrome

Pour la distribution de l’application et sa mise à disposition sur « Desktop », il faudra, par la suite, la rendre disponible sur le Google Web Store. Nous verrons dans un prochain article comment aller plus loin en ciblant également les plateformes mobiles.

Florent Dupont

Expert Technique Web, mobilité et industrialisation

0 commentaires

votre commentaire

Se joindre à la discussion ?
Vous êtes libre de contribuer !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Inscription newsletter

Ne manquez plus nos derniers articles !