forked from DiscoverMeteor/DiscoverMeteor_fr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path09s-creating-a-meteorite-package.md.erb
249 lines (189 loc) · 8.96 KB
/
09s-creating-a-meteorite-package.md.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
---
title: Créer un Package Meteorite
slug: creating-a-meteorite-package
date: 0009/01/02
number: 9.5
points: 10
sidebar: true
photoUrl: http://www.flickr.com/photos/rxb/7779426142/
photoAuthor: Richard
contents: Ecrire un paquet in-app local.|Ecrire des tests pour vos paquets.|Délivrer votre paquet sur Atmosphere.
paragraphs: 22
---
Nous avons construit un pattern réutilisable avec notre travail sur les erreurs, donc pourquoi ne pas l'empaqueter dans un paquet intelligent et le partager avec le reste de la communauté Meteor ?
Premièrement nous avons besoin de créer une structure pour notre paquet. Nous le mettons dans un répertoire nommé `packages/errors/`. Ça crée un paquet personnalisé qui est automatiquement utilisé. (Vous devriez avoir noté que Meteorite installe les paquets via des liens symboliques dans le répertoire `packages/`).
Deuxièmement, nous allons créer `package.js` dans ce répertoire, ce fichier qui informe Meteor de comment le paquet devrait être utilisé, et les symboles qu'il exporte.
~~~js
Package.describe({
summary: "A pattern to display application errors to the user"
});
Package.on_use(function (api, where) {
api.use(['minimongo', 'mongo-livedata', 'templating'], 'client');
api.add_files(['errors.js', 'errors_list.html', 'errors_list.js'], 'client');
if (api.export)
api.export('Errors');
});
~~~
<%= caption "packages/errors/package.js" %>
Ajoutons trois fichiers au paquet. Nous pouvons récupérer ces trois fichiers de Microscope sans trop de changements à part pour certains espaces de noms propres et une API légèrement plus claire :
~~~js
Errors = {
// Collection local (client seulement)
collection: new Meteor.Collection(null),
throw: function(message) {
Errors.collection.insert({message: message, seen: false})
},
clearSeen: function() {
Errors.collection.remove({seen: true});
}
};
~~~
<%= caption "packages/errors/errors.js" %>
~~~html
<template name="meteorErrors">
{{#each errors}}
{{> meteorError}}
{{/each}}
</template>
<template name="meteorError">
<div class="alert alert-error">
<button type="button" class="close" data-dismiss="alert">×</button>
{{message}}
</div>
</template>
~~~
<%= caption "packages/errors/errors_list.html" %>
~~~js
Template.meteorErrors.helpers({
errors: function() {
return Errors.collection.find();
}
});
Template.meteorError.rendered = function() {
var error = this.data;
Meteor.defer(function() {
Errors.collection.update(error._id, {$set: {seen: true}});
});
};
~~~
<%= caption "packages/errors/errors_list.js" %>
### Tester le paquer avec Microscope
Nous allons tester maintenant les choses localement avec Microscope pour nous assurer que notre code modifié fonctionne. Pour relier le paquet dans notre projet, nous exécutons `meteor add errors`. Ensuite, nous avons besoin de supprimer les fichiers existants qui ont été rendu redondants par le nouveau paquet :
~~~bash
$ rm client/helpers/errors.js
$ rm client/views/includes/errors.html
$ rm client/views/includes/errors.js
~~~
<%= caption "Suppression des vieux fichiers via la console bash" %>
Une autre chose que nous avons besoin de faire est d'effectuer quelques mises à jour mineures pour utiliser l'API correctement :
~~~js
Router.before(function() { Errors.clearSeen(); });
~~~
<%= caption "lib/router.js" %>
~~~html
{{> header}}
{{> meteorErrors}}
~~~
<%= caption "client/views/application/layout.html" %>
~~~js
Meteor.call('post', post, function(error, id) {
if (error) {
// afficher l'erreur à l'utilisateur
Errors.throw(error.reason);
~~~
<%= caption "client/views/posts/post_submit.js" %>
~~~js
Posts.update(currentPostId, {$set: postProperties}, function(error) {
if (error) {
// Afficher l'erreur à l'utilisateur
Errors.throw(error.reason);
~~~
<%= caption "client/views/posts/post_edit.js" %>
<%= scommit "9-5-1", "Créer des erreurs basiques et les relier." %>
Une fois que ces changements ont été faits, nous devrions récupérer notre comportement original pré-paquet.
### Ecrire des tests
La première étape quand on développe un paquet est de le tester dans une application, mais la suivante est d'écrire une suite de test qui teste proprement le comportement du paquet. Meteor propose Tinytest (un testeur de paquet intégré), qui rend facile l'exécution de ce type de tests et permet de rester serein quand on partage notre paquet avec les autres.
Créons un fichier de test qui utilise Tinytest pour exécuter des tests sur le code du paquet errors :
~~~js
Tinytest.add("Errors collection works", function(test) {
test.equal(Errors.collection.find({}).count(), 0);
Errors.throw('A new error!');
test.equal(Errors.collection.find({}).count(), 1);
Errors.collection.remove({});
});
Tinytest.addAsync("Errors template works", function(test, done) {
Errors.throw('A new error!');
test.equal(Errors.collection.find({seen: false}).count(), 1);
// rendre le template
OnscreenDiv(Spark.render(function() {
return Template.meteorErrors();
}));
// attendre quelques millisecondes
Meteor.setTimeout(function() {
test.equal(Errors.collection.find({seen: false}).count(), 0);
test.equal(Errors.collection.find({}).count(), 1);
Errors.clearSeen();
test.equal(Errors.collection.find({seen: true}).count(), 0);
done();
}, 500);
});
~~~
<%= caption "packages/errors/errors_tests.js" %>
Dans ces tests nous vérifions que les fonctions basiques `Meteor.Errors` fonctionnent, ainsi qu'une deuxième vérification que le code `rendered` dans le template fonctionne encore.
Nous ne couvrirons pas les spécificités d'écriture des tests de paquets Meteor ici (comme l'API n'est pas encore finalisée et hautement changeante), mais heureusement son fonctionnement est assez bien expliqué.
Pour dire à Meteor comment exécuter les tests dans `package.js`, utilisez le code suivant :
~~~js
Package.on_test(function(api) {
api.use('errors', 'client');
api.use(['tinytest', 'test-helpers'], 'client');
api.add_files('errors_tests.js', 'client');
});
~~~
<%= caption "packages/errors/package.js" %>
<%= scommit "9-5-2", "Ajout des tests du paquet." %>
Puis nous pouvons exécuter les tests avec :
~~~bash
$ meteor test-packages errors
~~~
<%= caption "Terminal" %>
<%= screenshot "s7-1", "Passer tous les tests" %>
### Délivrer le paquet
Maintenant, nous voulons délivrer le paquet et le rendre disponible à tout le monde. Nous faisons ça en le mettant sur Atmosphere.
Premièrement, nous avons besoin d'ajouter un `smart.json`, pour indiquer à Meteorite et Atmosphere les détails importants à propos du paquet :
~~~json
{
"name": "errors",
"description": "A pattern to display application errors to the user",
"homepage": "https://github.com/tmeasday/meteor-errors",
"author": "Tom Coleman <[email protected]>",
"version": "0.1.0",
"git": "https://github.com/tmeasday/meteor-errors.git",
"packages": {
}
}
~~~
<%= caption "packages/errors/smart.json" %>
<%= scommit "9-5-3", "Ajout d'un smart.json" %>
Nous mettons dedans quelques metadonnées basiques pour fournir des informations à propos du paquet, en incluant ce qu'il fait, sa localisation git où nous allons l'héberger, un numéro de version initial. Si notre paquet repose sur d'autres paquets Atmosphere, nous pouvons également utiliser une section `"packages"` pour délimiter ses dépendances.
Une fois tout ça mis en place, délivrer est facile. Nous aurons besoin de créer un dépôt git, pousser vers un serveur git distant quelque part, et indiquer sa localisation dans notre `smart.json`.
Le processus [GitHub](http://github.com) pour faire ça est, premièrement créer un nouveau dépôt, puis suivre la pratique standard de mettre le code du paquet à l'intérieur de ce dépôt. Ensuite, nous utilisons la commande `mrt release` pour le publier :
~~~bash
$ git init
$ git add -A
$ git commit -m "Created Errors Package"
$ git remote add origin https://github.com/tmeasday/meteor-errors.git
$ git push origin master
$ mrt release .
Done!
~~~
<%= caption "Terminal (exécuté depuis `packages/errors`)" %>
Note : les noms de paquets doivent être uniques. Si vous utilisez mot pour mot le même nom de paquet, il y aura un conflit et ça ne fonctionnera pas. Dans le future Atmosphere sera name-spaced (cf espace de noms) par l'auteur, vous pouvez vous attendre à un changement.
Seconde note : Vous aurez besoin de vous authentifier sur http://atmosphere.meteor.com/accounts et créer un nom d'utilisateur et mot de passe que vous entrerez en ligne de commande quand vous appellerez `mrt release .`.
Maintenant que le paquet est délivré, vous pouvez le supprimer du projet et l'ajouter directement en utilisant Meteorite :
~~~bash
$ rm -r packages/errors
$ mrt add errors
~~~
<%= caption "Terminal (exécuté depuis le répertoire de l'application)" %>
<%= scommit "9-5-4", "Suppression du paquet dans l'arborescence de développement." %>
Maintenant nous devrions voir Meteorite télécharger notre paquet pour la toute première fois. Bien joué !