I. Avant-propos

Cette nouvelle série de tutoriels Backbone.jsBackbone.js vous guidera à travers la création d'une application Web monopage qui possède une implémentation personnalisée de Backbone.syncBackbone.sync. J'ai commencé à construire les applications basées sur ces tutoriels en août et ça a fonctionné sans problème depuis quelques mois maintenant alors j'ai pensé qu'ils étaient suffisamment sûrs que pour pouvoir en parler.

Image non disponible

L'application elle-même a été construite pour résoudre un besoin de mes amis : une liste de tâches Google Mail plus facile à utiliser. L'interface Gmail prend à mon sens une mauvaise direction pour ainsi dire. J'ai donc écrit une méthode Backbone.sync qui travaille avec les API de Google et une petite interface BootstrapBootstrap par dessus. Dans le cadre de ces tutoriels, je vais aussi faire quelques suggestions sur la façon de personnaliser Bootstrap.

Les applications que nous allons faire ne possèdent pas l'entièreté des fonctionnalités que Google supporte : je n'ai pas encore ajouté le support pour l'indentation des éléments par exemple. Toutefois, le code actuel rencontre très bien mes besoins alors j'espère que c'est quelque chose que vous voudrez réellement utiliser.

II. Feuille de route

Dans les prochains tutoriels, je vais couvrir les sujets suivants :

  • créer un nouveau projet Node pour la construction de l'application monopage ;
  • utilisation de RequireJS avec Backbone.js ;
  • l'API de Google ;
  • écrire et exécuter des tests ;
  • créer l'application Backbone.js elle-même ;
  • techniques pour personnaliser les données Bootstrap ;
  • déploiement vers Dropbox, Amazon S3 et éventuellement d'autres services.

III. Création d'un environnement de développement

Si vous mettez l'accent sur l'écriture de scripts côté client, je pense que ce sera utile pour vous. Notre objectif est de créer un environnement de développement qui peut effectuer les opérations suivantes :

  • permettre au code côté client d'être écrit sous forme de fichiers distincts ;
  • combiner des fichiers séparés en quelque chose de convenable pour le déploiement ;
  • exécuter l'application localement à l'aide de fichiers distincts (pour rendre le développement et le débogage plus facile) ;
  • gérer les modules complémentaires de Node ;
  • exécuter des tests ;
  • support de Windows et de Unix.

Pour ce faire, nous aurons besoin de quelques outils et bibliothèques :

Assurez-vous que Node est installé sur votre système. Le plus simple consiste à l'installer en utilisant un des packages Node pour votre systèmeTéléchargement de Node.

IV. Étape 1 : installation des modules de Node

Créez un répertoire pour ce projet et créez un nouveau fichier à l'intérieur de ce dernier appelé package.json. Ce fichier doit contenir ce JSON :

 
Sélectionnez
{
  "name": "btask"
, "version": "0.0.1"
, "private": true
, "dependencies": {
    "requirejs": "latest"
  , "connect": "2.7.0"
  }
, "devDependencies": {
    "mocha": "latest"
  , "chai": "latest"
  , "grunt": "latest"
  , "grunt-exec": "latest"
  }
, "scripts": {
    "grunt": "node_modules/.bin/grunt"
  }
}

Exécutez npm install. Ces modules ainsi que leurs dépendances seront installés dans ./node_modules.

La propriété private empêche de réécrire accidentellement et publiquement ce module. Ceci est utile pour les projets commerciaux dont les sources sont protégées ou qui ne sont pas adaptés pour une diffusion au moyen de npm.

Même si vous n'êtes pas un développeur serveur, gérer les dépendances avec npm est utile car il rend plus facile pour les développeurs de travailler sur votre projet. Lorsqu'un nouveau développeur se joint à votre projet, il lui suffit de taper npm install plutôt que de savoir ce qu'il doit télécharger.

V. Étape 2 : serveur Web local

Créez un répertoire nommé app et un fichier nommé app/index.html :

 
Sélectionnez
<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <title>bTask</title>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script type="text/javascript" src="js/lib/require.js"></script>
</head>
<body>
</body>
</html>

Une fois que vous avez fait cela, créez un fichier appelé server.js dans le répertoire de niveau supérieur :

 
Sélectionnez
var connect = require('connect')
  , http = require('http')
  , app
  ;

app = connect()
  .use(connect.static('app'))
  .use('/js/lib/', connect.static('node_modules/requirejs/'))
  .use('/node_modules', connect.static('node_modules'))
  ;

http.createServer(app).listen(8080, function() {
  console.log('Running on http://localhost:8080');
});

Ce fichier utilise l'infrastructure middleware Connect pour agir comme un petit serveur Web afin d'utiliser les fichiers contenus dans app/. Vous pouvez lui ajouter des nouveaux chemins en copiant la ligne .use(connect.static('app')) et en changeant app par quelque chose d'autre.

Remarquez comment j'ai relié le chemin d'accès Web pour /js/lib/ vers node_modules/requirejs/ sur le système de fichiers. Au lieu de copier RequireJS à l'emplacement des scripts côté client, nous pouvons le relier à l'aide de Connect. Par la suite les scripts de compilation vont copier node_modules/requirejs/require.js dans build/js/lib et alors le fichier index.html ne devra pas changer. Cela permettra d'exécuter le projet sur un serveur Web approprié ou sur un service d'hébergement pour les sites statiques comme Amazon S3.

Pour exécuter ce serveur Node, tapez npm start (ou node server.js) et contactez l'URL http://localhost:8080. Elle doit afficher une page vide sans erreur côté client.

VI. Étape 3 : configuration de RequireJS

Ce projet comprendra des modules écrits dans le format AMDAMD. Chaque collection de Backbone, modèle, vue et ainsi de suite existera dans son propre fichier avec une liste de dépendances afin que RequireJS puisse les charger au besoin.

Les projets RequireJS qui fonctionnent de cette manière sont généralement structurés autour d'un fichier « main » qui charge les dépendances nécessaires au démarrage de l'application. Créez un fichier nommé app/js/main.js qui contient la configuration suivante de RequireJS :

 
Sélectionnez
requirejs.config({
  baseUrl: 'js',

  paths: {
  },

  shim: {
  }
});

require(['app'],

function(App) {
  window.bTask = new App();
});

La partie qui lit require(['app'] va charger app/js/app.js. Créez ce fichier avec le contenu suivant :

 
Sélectionnez
define([], function() {
  var App = function() {
  };

  App.prototype = {
  };

  return App;
});

Il s'agit d'un module écrit dans le format AMD. La fonction define est fournie par RequireJS et contiendra à l'avenir toutes les dépendances internes du projet.

Pour terminer cette étape, le main.js doit être chargé. Ajoutez des balises de script appropriées dans le bas de la page app/index.html avant la balise body.

 
Sélectionnez
<script type="text/javascript" src="js/main.js"></script>

Si vous actualisez http://localhost:8080 dans votre navigateur et ouvrez la console JavaScript, vous devriez voir que bTask a été instanciée.

Image non disponible

VII. Étape 4 : test

Tout ce que vous avez appris dans les trois étapes précédentes peut être réutilisé pour créer une suite de tests unitaires. MochaMocha a déjà été installé par npm. Nous allons donc créer un ensemble de tests appropriés.

Créez un nouveau répertoire appelé test/ qui contient un fichier nommé index.html :

 
Sélectionnez
<html>
<head>
  <meta charset="utf-8">
  <title>bTask Tests</title>
  <link rel="stylesheet" href="/node_modules/mocha/mocha.css" />
  <style>
.toast-message, #main { display: none }
  </style>
</head>
<body>
  <div id="mocha"></div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script src="/node_modules/chai/chai.js"></script>
  <script src="/node_modules/mocha/mocha.js"></script>
  <script src="/js/lib/require.js"></script>
  <script src="/js/main.js"></script>
  <script src="setup.js"></script>
  <script src="app.test.js"></script>
  <script>require(['app'], function() { mocha.run(); });</script>
</body>
</html>

Le require près de la fin s'assure que mocha.run s'exécute uniquement lorsque /js/app.js a été chargé.

Créez un autre fichier appelé test/setup.js :

 
Sélectionnez
var assert = chai.assert;

mocha.setup({
  ui: 'tdd'
, globals: ['bTask']
});

Ce fichier donne les assertions de ChaiChai Assert disponibles comme assert qui est la manière que j'utilise d'habitude pour écrire mes tests. J'ai aussi dit à Mocha que bTask est une variable globale attendue.

Tous ces éléments en place, nous pouvons écrire un test rapide. Ce fichier va dans test/app.test.js :

 
Sélectionnez
suite('App', function() {
  test('Should be present', function() {
    assert.ok(window.bTask);
  });
});

Tout ce que ce code fait est de vérifier que window.bTask a été défini. C'est la preuve que RequireJS a chargé l'application.

Redémarrez le serveur Web (à l'étape 2) et contactez l'URL http://localhost:8080/test. Mocha doit afficher qu'un test simple a réussi.

VIII. Étape 5 : compiler

Créez un fichier appelé grunt.js pour notre « fichier grunt » :

 
Sélectionnez
module.exports = function(grunt) {
  grunt.loadNpmTasks('grunt-exec');

  grunt.initConfig({
    exec: {
      build: {
        command: 'node node_modules/requirejs/bin/r.js -o require-config.js'
      }
    }
  });

  grunt.registerTask('copy-require', function() {
    grunt.file.mkdir('build/js/lib');
    grunt.file.copy('node_modules/requirejs/require.js', 'build/js/lib/require.js');
  });

  grunt.registerTask('default', 'exec copy-require');
};

Ce fichier utilise le plugin grunt-execgrunt-exec de Jake Harding pour lancer la commande RequireJS qui génère une compilation de tout ce qui se trouve dans le répertoire app/. Pour préciser à RequireJS ce qu'il faut construire, créez un fichier appelé require-config.js :

 
Sélectionnez
({
  appDir: 'app/'
, baseUrl: 'js'
, paths: {}
, dir: 'build/'
, modules: [{ name: 'main' }]
})

RequireJS minimisera et concaténera les fichiers nécessaires. L'autre tâche de Grunt copie le code côté client de RequireJS vers build/js/lib/require.js parce que notre serveur Connect a été redirigé pour nous. Pourquoi s'embêter ? Eh bien, cela signifie que chaque fois que nous mettons à jour RequireJS via npm, l'application et la compilation auront automatiquement la dernière version.

Pour exécuter Grunt, tapez npm run-script grunt. La commande run-script est utilisée pour appeler des scripts qui ont été ajoutés au fichier package.json. Ce package créé à l'étape 1 contient "grunt": "node_modules/.bin/grunt" qui fait ce travail. Je préfère cela que d'installater Grunt entièrement.

Je n'utilise habituellement pas Grunt pour mes propres projets parce que je préfère les makefiles. En fait, un makefile pour ce qui précède serait très simple. Cependant, cela rend les choses plus difficiles pour les développeurs Windows, c'est pourquoi j'ai inclus Grunt malgré tout pour prendre en charge Windows. En outre, si vous travaillez en général en tant que développeur côté client, vous pourriez trouver Grunt plus facile à comprendre que l'apprentissage de GNU MakeGNU Make ou que d'écrire le code Node équivalent (Node dispose d'un bon module de système de fichiers).

IX. En résumé

Dans ce tutoriel, vous avez créé un environnement de compilation Grunt et RequireJS pour les projets Backbone.js qui utilisent Mocha pour les tests. Vous avez également vu comment utiliser Connect pour fournir un serveur Web local pratique.

Fondamentalement, c'est ainsi que je construis et gère l'ensemble de mes applications Backbone.js Web monopage. Bien que nous n'ayons pas encore écrit beaucoup de code, vous verrez dans les prochains tutoriels que cette approche fonctionne bien pour l'utilisation conjointe de Backbone.js et de RequireJS.

Le code de ce projet se trouve ici : dailyjs-backbone-tutorial (2a8517)Code source.

X. Remerciements

Cet article a été publié avec l'aimable autorisation de Alex Young. L'article original peut être lu sur le site DailyJSDailyJS : Backbone.js Tutorial: Build EnvironmentBackbone.js Tutorial: Build Environment.
Je remercie également ClaudeLELOUP pour sa relecture attentive et assidue.