Ionic 2 partie 1 : Structure de projet
Ionic est un framework dont la popularité n’est plus à démontrer et qui permet de développer des applications mobiles hybrides rapidement et facilement. Il repose sur différentes technologies comme AngularJS (partie interface) et Cordova (partie matérielle). Une application Ionic peut être déployée sur différents terminaux mobiles (iOS, Android, Windows, Blackberry…) ce qui permet de toucher un grand nombre d’utilisateurs avec un unique développement.
Ionic version 1 repose sur la version 1 du Framework AngularJS et bien sûr Ionic en version 2 repose sur la version 2 d’Angular. La dernière mouture du Framework de Google offrant la possibilité de développer en TypeScript, il en va naturellement de même pour Ionic 2.
Le Framework Ionic2 est, à l’heure où sont écrites ces lignes, toujours en version beta et n’est donc pas « production ready ». Angular 2 est quand à lui en version release candidate depuis peu. Mais il est intéressant de voir les possibilités offertes par cette version 2 d’Ionic, notamment grâce à Angular 2, ce qui constituera le sujet d’un certain nombre d’articles à venir dont celui-ci est le premier.fDans cet article, nous allons donc voir quelle structure mettre en place sur un projet Ionic 2 et quels sont les outils qui facilitent la construction d’une application Ionic 2.
La structure que nous avons mise en place pour notre application mobile est inspirée de la structure officielle Ionic2 mais également de ce starter kit pour Angular 2.
Structure du projet
Sources
Comme source d’exemple, je vais me baser sur un projet que nous avons réalisé, une application mobile dont le but est de lire les informations d’un tag NFC. Les sources du projet, qui sont disponibles sur notre github, sont développées en Angular2/Ionic 2 en version TypeScript.
Notre structure de projet est proche de la structure générée par défaut par la commande ionic start * --v2 à ceci près que nous avons rajouté une configuration pour les tests unitaires, la qualimétrie, la couverture de code, la génération de la documentation TypeScript comme celle faite dans ce starter kit pour Angular 2 et l’usage de webpack a défaut de gulp.
Nom | Description |
---|---|
app | Sources TypeScript du projet |
www | Assets du projet comme les images, css, fonts, i18n ou les tests unitaires. Contient notamment le fichier index.html qui est notre point d’entrée |
hooks | Scripts qui seront exécutés par Cordova lors du build. Utile si vous avez besoin de personnaliser le packaging de l’application. |
typings | Regroupe l’ensemble des typings (définitions de types) pour des modules externes non écrit en TypeScript |
platforms | Contient les différentes plateformes installées via la commande cordova add platform |
reports | Rapports des tests unitaires aux formats junit et html |
coverage | Rapport de couverture de code aux fomats: txt, json, html et cobertura (xml) |
doc | Documentation TypeScript générée par TsDoc |
node_modules | Dépendances npm |
plugins | Liste des plugins cordova installés via la commande cordova add plugin |
ionic.config.js | Fichier de configuration d’Ionic utilisé notamment pour le build |
spec-bundle.js | Fichier de configuration utilisé pour les tests unitaires par webpack |
karma.conf.js | Configuration de Karma |
tslint.json | Configuration de TsLint |
tsconfig.json | Configuration du compilateur TypeScript |
package.json | Scripts et dépendances npm |
config.xml | Fichier de configuration utilisé par Cordova pour le packaging de l’application |
resources | Ressources icônes et splash pour chacune de plateformes |
webpack.config.js | Configuration utilisée par webpack pour la création d’un bundle à partir des différents modules. |
webpack.test.config.js | Configuration utilisée par webpack pour la création d’un bundle pour le lancement des tests unitaires |
Pour avoir un détail plus précis de la structure, je vous renvoie vers le fichier README.md du projet.
Npm et pas Bower
Si vous êtes développeur JavasScript, cela ne vous aura pas échappé qu’il existe au moins deux acteurs majeurs dans la gestion des dépendances: npm et bower. Quelles différences ?
- Bower est un gestionnaire de dépendances exclusivement orienté frontend.
- Npm est le gestionnaire de dépendances de NodeJS et est donc principalement orienté serveur même s’il possède aussi un nombre conséquent de dépendances frontend.
- Npm possède beaucoup plus de dépendances que bower.
- Npm charge ses dépendances via la méthode require ce qui est problématique coté navigateur puisque cette dernière est inconnue.
- Npm se base sur CommonJS pour le chargement des modules de manière synchrone.
Ionic 2 repose (par défaut) uniquement sur des dépendances NPM décrites via le fichier package.json et vous l’aurez compris les dépendances npm ne sont pas directement transposables dans un navigateur web.
Pour pallier à ce problème, on utilise généralement des outils comme browserify, qui permettent de lire les dépendances npm utilisées, de les concaténer et les minifier dans un fichier de sortie JavaScript rendant ainsi vos dépendances npm accessibles par un navigateur web.
Seulement voilà, Ionic 2 (toujours par défaut) n’utilise pas browserify mais fait appel à webpack.
Webpack et pas Browserify
Webpack est un outil de plus en plus populaire et permet de faire un package pour le web. Il a pour objectif de faciliter la vie du développeur en organisant une application JavaScript en modules. C’est à dire de rendre des modules (et leurs dépendances) en assets statiques. Une dépendance npm qui n’est ainsi pas destinée à être utilisée par un navigateur pourra être chargée par un navigateur grâce à webpack.
Il permet également, grâce à un système de loader, de transformer n’importe quelle ressource css, html, fontes, images, etc. en ressource JavaScript et donc en module. Il gère aussi bien les modules CommonJS (synchrones) et AMD (asynchrones) et il existe un certain nombre de loaders existant et il est bien sur possible d’écrire le sien.
Le build
Mais surtout il est possible de configurer webpack pour obtenir l’équivalent de browserify et cette configuration doit se faire dans un fichier webpack.config.js.
Ainsi on retrouve, dans ce fichier, une configuration qui permet de générer un fichier de sortie (app.bundle.js) à partir des sources
:
1 2 3 4 5 6 7 8 9 10 11 |
entry: [ path.normalize('es6-shim/es6-shim.min'), 'reflect-metadata', path.normalize('zone.js/dist/zone-microtask'), path.resolve('app/app') ], output: { path: path.resolve('www/build/js'), filename: 'app.bundle.js', pathinfo: false // show module paths in the bundle, handy for debugging }, |
Dans notre exemple, le fichier de sortie sera app.bundle.js placé dans le dossier www/build/js et les sources concaténées et minifiées sont celles listées dans la propriété entry. Les dépendances utilisées dans les différentes sources listées dans « entry » seront elles-mêmes résolues et incluses dans le package app.bundle.js.
Les tests
Pour notre application mobile, les tests unitaires sont réalisés grâce à Karma, Jasmine, PhantomJS et webpack. Webpack permet de charger les fichiers et modules indispensables pour que les tests fonctionnent correctement. Je ne vais pas détailler ici comment fonctionnent les tests car cela fera l’objet d’un prochain article mais retenez simplement que Karma repose sur un fichier de configuration webpack. Ce fichier est évidement différent du fichier de configuration de build car les fichiers à charger sont différents puisqu’il faut (entre autres) ajouter les tests.
Vous pouvez trouver un exemple dans le fichier webpack.test.config.js lui-même chargé par le fichier karma.conf.js utilisé par Karma au lancement des tests unitaires.
Les tests unitaires sont exécutés dans Travis grâce au fichier de configuration .travis.yml.
Les exports de tests
Nous utilisons des reporters Karma pour générer les résultats des tests sous différents formats et dont la configuration est faite dans le fichier karma.conf.js :
- Export HTML: karma-html-reporter
- Export Junit: karma-junit-reporter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
junitReporter: { outputDir: 'reports/junit', outputFile: 'test-results.xml', useBrowserName: false }, htmlReporter: { outputDir: 'reports/html', // where to put the reports templatePath: null, // set if you moved jasmine_template.html focusOnFailures: true, // reports show failures on start namedFiles: false, // name files instead of creating sub-directories pageTitle: null, // page title for reports; browser info by default urlFriendlyName: false, // simply replaces spaces with _ for files/dirs reportName: 'html_report', // report summary filename; browser info by default // experimental preserveDescribeNesting: false, // folded suites stay folded foldAll: false // reports start folded (only with preserveDescribeNesting) }, |
karma-html-reporter et karma-junit-reporter sont tous deux des dépendances npm référencées dans le fichier package.json.
Npm scripts : Pas de Grunt ou Gulp
Pas de grunt ou de gulp signifie pas de tâche, ce qui n’est pas forcément un problème en soi. Les scripts npm peuvent généralement répondre à la plupart des besoins surtout avec l’aide, comme c’est le cas dans ce projet, de webpack. Ainsi dans le fichier package.json, nous avons ajouté dans l’entrée scripts des commandes permettant de lancer les tests, de générer la documentation TypeScript ou encore de vérifier la qualimétrie à l’aide de tslint.
Documentation
Typedoc est un module npm qui permet de générer de la documentation TypeScript sous forme d’export Html. Cela est très pratique pour pouvoir visualiser les différentes classes, interfaces, méthodes et attributs de votre code. La configuration se fait via un fichier typedoc.json dans lequel on retrouve les informations nécessaires à la génération de la documentation. Bien entendu cela nécessite d’ajouter la dépendance typedoc dans votre fichier package.json ou de l’installer globalement.
Qualimétrie
A l’image de JavaScript et de JsLint il est possible de faire de la qualimétrie sur du code TypeScript avec TsLint. Ce dernier va analyser votre code TypeScript et remonter toutes violations aux règles décrites dans le fichier tslint.json. La dépendance tslint doit être ajoutée dans le fichier package.json ou installée globalement.
Couverture de code
La couverture de code est réalisée grâce au module karma-coverage dont la configuration est faite dans le fichier karma.conf.js. Le module karma-coverage nous permet de faire des exports sous différents formats parmi lesquels :
1 2 3 4 5 6 7 8 9 10 |
coverageReporter: { dir : 'coverage/', reporters: [ { type: 'text-summary', subdir: 'report-text' }, { type: 'json', subdir: 'report-json' }, { type: 'html', subdir: 'report-html' }, { type: 'cobertura', subdir: 'report-cobertura' }, { type: 'lcovonly', subdir: 'report-lcov', file: 'coverage.lcov' } ] }, |
- json
- html
- cobertura
- lcoonly (par exemple pour une intégration sonar)
En résumé
Si l’on résume notre stack, les différents composants de notre stack Ionic 2 / TypeScript sont :
- Npm comme gestionnaire de dépendances
- Wepack pour le packaging
- Karma et Jasmine pour les tests unitaires
- TypeDoc pour la génération de la documentation TypeScript
- TsLint pour la qualimétrie sur le code TypeScript
- Karma coverage pour la couverture de code
- Une intégration travis
Il s’agit ici d’un simple survol des différents éléments et choix concernant notre application mobile NFC mais chacun des points sera détaillé ultérieurement dans des articles dédiés.
Installation
Pour démarrer notre projet ionic 2, quelques commandes suffisent :
Ionic
Tout d’abord il nous faut installer la commande ionic pour pouvoir déployer notre application, lancer le serveur, etc. :
1 |
npm install -g ionic@beta |
Ne pas oublier le « @beta » pour installer la dernière version de la commande.
Cordova
La commande cordova va nous permettre d’installer des plugins:
1 |
npm install -g cordova |
TypeScript Definition manager
TSD va nous permettre de pouvoir rajouter des « typings » (nous y reviendrons plus tard). Il peut être intéressant si vous avez plusieurs projets d’installer la commande globalement :
1 |
npm install -g tsd |
Karma
On ne le présente plus, Karma va nous être utile pour le lancement de nos tests unitaires:
1 |
npm install -g karma |
Si vous avez récupéré les sources du projet github, faites ensuite un npm install pour installer l’ensemble des dépendances décrites dans le fichier package.json.
Plugins cordova
Les plugins suivants doivent être installés via la commande cordova plugin add :
-
cordova plugin add cordova-plugin-barcodescanner
-
cordova plugin add cordova-plugin-statusbar
-
cordova plugin add cordova-plugin-vibration
-
cordova plugin add cordova-plugin-whitelist
-
cordova plugin add phonegap-nfc
Lancement de l’application
Il nous faut d’abord ajouter les plateformes cibles via la commande cordova.
Android
Il faut dans un premier temps installer le SDK d’android que vous trouverez sur le site officiel puis de renseigner la variable d’environnement ANDROID_HOME avec le chemin d’installation du SDK.
Pour lancer l’application sur un device, il vous faut installer les derniers drivers usb et brancher votre terminal à votre pc
IOS
(Prochainement)
Exécution
Pour lancer l’application sur votre smartphone, tapez ionic run android ou ionic run ios, Ionic va alors builder et lancer l’application sur votre terminal. Assurez-vous d’avoir préalablement activé les options développeurs si vous êtes sous Android.