-
Notifications
You must be signed in to change notification settings - Fork 12
/
09s-creating-a-meteorite-package.md.erb
244 lines (184 loc) · 8.46 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
---
title: Creare un pacchetto con Meteorite
slug: creating-a-meteorite-package
date: 0009/01/02
number: 9.5
sidebar: true
contents: Creare un pacchetto per l'appilcazione.|Scrivere dei test per il pacchetto.|Rilasciare il pacchetto su Atmosphere.
paragraphs: 22
---
Dopo che abbiamo creato uno schema riutilizzabile per la gestione dei nostri errori, possiamo creare un pacchetto e condividerlo con gli altri sviluppatori della comunità di Meteor.
Come prima cosa dobbiamo preparare la struttura del pacchetto. Lo inseriamo in una cartella chiamate `packages/errors/`, in questo modo si crea un pacchetto personalizzato che l'applicazione utilizzerà automaticamente. (È possibile che abbiate notato che Meteorite installa i pacchetto tramite symlinks nella cartella `packages/`).
In seguito, creiamo il file `package.js`, nel quale viene detto a Meteor come deve utilizzare il pacchetto e quali simboli vengono esportati, cioè quali oggetti vengono resi disponibili all'applicazione.
~~~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" %>
Aggiungiamo tre file al pacchetto, prendendoli direttamente da Microscope e aggiungendo solo un namespace appropriato e un API leggeremente più chiara:
~~~js
Errors = {
// Local (client-only) collection
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" %>
### Testing the package out with Microscope
Ora testeremo le modifiche localmente per assicurarci che tutto funzioni. Per aggiungere il pacchetto all'applicazione, eseguiamo nel terminale `meteor add errors` ed eliminiamo i file esistenti che ora sono superflui:
~~~bash
$ rm client/helpers/errors.js
$ rm client/views/includes/errors.html
$ rm client/views/includes/errors.js
~~~
<%= caption "removing old files on the bash console" %>
Dobbiamo fare qualche piccola modifica per utilizzare correttamente l'API:
~~~js
Router.onBeforeAction(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) {
// display the error to the user
Errors.throw(error.reason);
~~~
<%= caption "client/views/posts/post_submit.js" %>
~~~js
Posts.update(currentPostId, {$set: postProperties}, function(error) {
if (error) {
// display the error to the user
Errors.throw(error.reason);
~~~
<%= caption "client/views/posts/post_edit.js" %>
<%= commit "9-5-1", "Created basic errors package and linked it in." %>
Una volta terminate queste modifiche, la situazione dovrebbe essere tornata a com'era prima della creazione del pacchetto.
### Come scrivere dei test
Il primo passo nello sviluppo di un pacchetto è quello di testarlo in un'applicazione, ma quello successivo è di scrivere una serie di test per verificarne il corretto funzionamento. Meteor fornisce Tinytest, un sistema di test integrato, che semplifica l'esecuzione di questi test e ci aiuta a stare tranquillo al momento di condividere il nostro pacchetto con altri sviluppatori.
Creiamo ora un file nel quale, utilizzando Tinytest, faremo dei test sul codice creato per gestire gli errori:
~~~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);
// render the template
UI.insert(UI.render(Template.meteorErrors), document.body);
// wait a few milliseconds
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" %>
In questi test stiamo verificando le funzioni di base di `Meteor.Errors` e controllando che il codice renderizzato nel template funzioni ancora.
Non ci dilungheremo nella spiegazione di come scrivere i test per i pacchetti di Meteor (dato che l'API non è ancora definitiva), ma speriamo che si capisca sufficientemente come funziona il codice precedente.
Per dire a Meteor come eseguire i testi, aggiungiamo nel file `package.js` il seguente codice:
~~~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" %>
<%= commit "9-5-2", "Added tests to the package." %>
Possiamo poi eseguirli da terminale con:
~~~bash
$ meteor test-packages errors
~~~
<%= caption "Terminal" %>
<%= screenshot "s7-1", "Passing all tests" %>
### Come rilasciare il pacchetto
Rendiamo ora disponibile in nostro pacchetto al mondo intero attraverso Atmosphere.
Come prima cosa, aggiungiamo un file `smart.json` per passare a Meteorite e Atmosphere i dettagli più importanti del pacchetto:
~~~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" %>
<%= commit "9-5-3", "Added a smart.json" %>
Inseriamo dei metadati per segnalare informazioni sul pacchetto, fra i quali una descrizione per spiegare a cosa è utile, l'indirizzo di dove è posizionata la repository Git e un numero di versione iniziale. Se il nostro pacchetto dipendesse da altri presenti su Atmosphere, possiamo creare una sezione `"packages"` per descrivere le dipendenze.
Una volta sistemato tutto, il rilascio è molto semplice. Dobbiamo creare un repository Git, caricarlo su di un server Git remoto e mettere il link nel file `smart.json`.
Per fare questi passaggi con [GitHub](http://github.com) bisogna creare un nuovo repository e seguire il procedimento standard per caricare il codice del pacchetto in quella repository. Infine utilizzare il comando `mrt release` per pubblicarlo:
~~~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 (run from within `packages/errors`)" %>
Nota: i nomi dei pacchetti devono essere unici. Se avete seguito il procedimento parola per parola e utilizzato lo stesso nome per il pacchetto, verrà segnalato un conflitto e il rilascio non avrà successo. Tuttavia nel prossimo futuro i pacchetti Atmosphere saranno preceduti da quello dell'autore in modo che questo non si verifichi.
Seconda Nota: dovrete crearvi un utente su http://atmosphere.meteor.com, perché all'esecuzione di `mrt release .` vi verranno richiesti username e password.
Ora che abbiamo rilasciato il pacchetto, possiamo eliminarlo dal progetto e installarlo di nuovo usando Meteorite:
~~~bash
$ rm -r packages/errors
$ mrt add errors
~~~
<%= caption "Terminal (run from the top level of the app)" %>
<%= commit "9-5-4", "Removed package from development tree." %>
Meteorite ora dovrebbe scaricare il nostro pacchetto per la prima volta, ottimo lavoro!