-
Notifications
You must be signed in to change notification settings - Fork 79
/
09s-creating-a-meteor-package.md.erb
214 lines (160 loc) · 7.1 KB
/
09s-creating-a-meteor-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
---
title: 创建 Meteor Package
slug: creating-a-meteor-package
date: 0009/01/02
number: 9.5
points: 10
sidebar: true
photoUrl: http://www.flickr.com/photos/rxb/7779426142/
photoAuthor: Richard
contents: 写一个应用里的内部包。|给你的包添加测试。|发布你的包到Atmosphere。
paragraphs: 22
---
我们在报告错误的工作中已经创建了可重复使用的模式,为什么不把它打包让 Meteor 社区的其他人都可使用呢?
为了开始,我们需要一个 Meteor 开发者账号。你可以从 [meteor.com](meteor.com) 申请,但是很有可能当你注册这本书的时候已经得到了。不管哪种情况,你应该搞清楚你的用户名是什么,因为我们会在本章中大量使用它。
在本章中我们使用用户名 `tmeasday`,当然你也可以换成你自己的。
首先我们需要创建一个结构来存放新的包。使用命令 `meteor create --package tmeasday:errors` 来完成。需要注意的是 Meteor 已经创建了一个名为 `packages/tmeasday:errors/` 的文件夹和一些文件。我们从编辑 `package.js` 开始,这文件会告诉 Meteor 如果使用这个包,有什么对象或函数要导出。
~~~js
Package.describe({
name: "tmeasday:errors",
summary: "A pattern to display application errors to the user",
version: "1.0.0"
});
Package.onUse(function (api, where) {
api.versionsFrom('0.9.0');
api.use(['minimongo', 'mongo-livedata', 'templating'], 'client');
api.addFiles(['errors.js', 'errors_list.html', 'errors_list.js'], 'client');
if (api.export)
api.export('Errors');
});
~~~
<%= caption "packages/tmeasday:errors/package.js" %>
当开发现实使用的 package 时,非常好的习惯就是在 `git` 部分的 `Package.describe` 代码块中,填写你代码库的 Git URL(比如,`https://github.com/tmeasday/meteor-errors.git`)。这样的话,用户可以浏览源代码,并且(假设你使用 GitHub)你的 package 的 readme 会显示在 Atomsphere 上。
让我们添加 3 个文件到 package 中。(我们可以删除 Meteor 自动添加的模板)我们可以从 Microscope 中 pull 这些文件而不用做太多修改,除了一些合适的命名和稍微清晰的 API:
~~~js
Errors = {
// Local (client-only) collection
collection: new Mongo.Collection(null),
throw: function(message) {
Errors.collection.insert({message: message, seen: false})
}
};
~~~
<%= caption "packages/tmeasday:errors/errors.js" %>
~~~html
<template name="meteorErrors">
<div class="errors">
{{#each errors}}
{{> meteorError}}
{{/each}}
</div>
</template>
<template name="meteorError">
<div class="alert alert-danger" role="alert">
<button type="button" class="close" data-dismiss="alert">×</button>
{{message}}
</div>
</template>
~~~
<%= caption "packages/tmeasday:errors/errors_list.html" %>
~~~js
Template.meteorErrors.helpers({
errors: function() {
return Errors.collection.find();
}
});
Template.meteorError.rendered = function() {
var error = this.data;
Meteor.setTimeout(function () {
Errors.collection.remove(error._id);
}, 3000);
};
~~~
<%= caption "packages/tmeasday:errors/errors_list.js" %>
### 在 Microscope 中测试 package
现在我们需要对 Microscope 做本地测试,以确保代码工作正确。为了链接包到项目,我们用命令 `meteor add tmeasday:errors`。然后,需要删除已经变得多余的现有文件:
~~~bash
rm client/helpers/errors.js
rm client/templates/includes/errors.html
rm client/templates/includes/errors.js
~~~
<%= caption "在 bash console 上删除旧文件" %>
我们需要做的另一件事情是做一些小的更新,使用正确的 API:
~~~html
{{> header}}
{{> meteorErrors}}
~~~
<%= caption "client/templates/application/layout.html" %>
~~~js
Meteor.call('postInsert', post, function(error, result) {
if (error) {
// display the error to the user
Errors.throw(error.reason);
~~~
<%= caption "client/templates/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/templates/posts/post_edit.js" %>
<%= scommit "9-5-1", "创建和链接基本的 errors package。" %>
一旦这些修改完成,我们就可恢复原来分包前的行为了。
### 写测试
开发包的第一个步骤是在一个应用程序中测试它,但接下来就是写一个测试套件,正确的测试包的行为。Meteor 本身自带 Tinytest(内置的包测试仪),它可以很容易地运行测试套件,以便与他人分享包时确保正确。
让我们创建一个测试文件,使用 Tinytest 来运行一些对新的包测试:
~~~js
Tinytest.add("Errors - collection", 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", function(test, done) {
Errors.throw('A new error!');
test.equal(Errors.collection.find({}).count(), 1);
// render the template
UI.insert(UI.render(Template.meteorErrors), document.body);
Meteor.setTimeout(function() {
test.equal(Errors.collection.find({}).count(), 0);
done();
}, 3500);
});
~~~
<%= caption "packages/tmeasday:errors/errors_tests.js" %>
在这些测试中,我们检查基本的 `Meteor.Errors` 的功能是否工作,以及再次确认该模板中的 `rendered` 代码是否仍在工作。
我们不会在这里写 Meteor 包测试的所有细节(而且 API 尚未最终确定,很有可能会有变化),但希望它是在一定程度上自我解释其工作原理。
使用下面的代码告诉 Meteor 如何在 `package.js` 中运行测试:
~~~js
Package.onTest(function(api) {
api.use('tmeasday:errors', 'client');
api.use(['tinytest', 'test-helpers'], 'client');
api.addFiles('errors_tests.js', 'client');
});
~~~
<%= caption "packages/tmeasday:errors/package.js" %>
<%= scommit "9-5-2", "为 package 添加测试。" %>
然后我们就可以运行测试:
~~~bash
meteor test-packages tmeasday:errors
~~~
<%= caption "终端 Terminal" %>
<%= screenshot "s7-1", "通过所有测试" %>
### 发布 package
现在我们要发布这个包,把它推送到 Meteor package 服务器,在 Atmosphere 中显示出来,让全世界的人都可使用。
幸运的是这很容易。我们只是 `cd` 到包的目录,运行命令 `meteor publish --create`:
~~~bash
cd packages/tmeasday:errors
meteor publish --create
~~~
<%= caption "终端 Terminal" %>
既然包已经发布,我们可以从项目中删除它,然后直接从 Atmosphere 重新添加它:
~~~bash
rm -r packages/tmeasday:errors
meteor add tmeasday:errors
~~~
<%= caption "终端 Terminal(在应用最高级别运行)" %>
<%= scommit "9-5-4", "从开发 tree 中删除 package。" %>
现在我们应该看到 Meteor 第一次下载了我们的 package。很棒!
和往常的附录章节一样,确保先恢复你所做的改动,然后再进行下一章(或者在阅读本书其他章节时,考虑你所做的改动。)