如何创建一个Meteor包

关于Meteor包和Atmosphere

Meteor是底层是基于Nodejs构建的,Meteor本身就提供了对所有Npm包的支持,程序员完全可以像在一般的Node项目中那样使用NPM包。而Atmosphere是一个分享和管理Meteor包的平台,类似于Node的npmjs

每次我们需要在新的工程中新加新的Meteor包时,我们只需要在工程目录下输入:

1
meteor add your_meteor_package

也可以直接编辑工程目录下的/.meteor/packages文件。

之后每次启动程序,Meteor都会为我们检查一遍包的依赖。Meteor的包使用起来和NPM包一样方便。

新建一个包以及包的默认目录结构

当然有的时候我们也可以创建和发布自己的Meteor包,为开源社区做出自己得贡献。首先你需要一个Meteor账号,可以在Meteor官网中注册一个,注意官网中的用户名是唯一不可修改的,用户名将作为第三方包的命名的一部分。

在命令行下创建一个包,并进入该目录。

1
meteor create --package meteor_username:package-name

注意包名的构成,是由meteor账户名加冒号加包名构成的,这种设计极大程度上避免了宝命名的冲突。

我们来看一个实际的例子,假设我们要创建一个hello-world的包,这里以笔者的meteor账户为例(注:这里的例子并没有被发布到Atmosphere上,仅仅作讲解用)。

1
meteor create --package charlesoy:hello-world

进入目录。

1
cd hello-world

查看包的基本结构。

1
README.md       hello-world-tests.js    hello-world.js      package.js

在Meteor的最新版本中(1.4.2.3),一个新的包就包含了这四个最基本的文件。这四个文件的作用也一目了然。

README.md就是文档,当然我们可以在package.js文件中指定具体的README的目录,发布后文档中的内容将显示在Atmosphere中你的包的详情页面中。一个好的有用的包应该提供详细的文档供使用者查阅,建议发布仔细编写README文件。

hello-world-tests.js是测试文件,测试代码在这里编写,当然我们也可以使用多个测试文件。

hello-world.js是我们的包的文件,包的逻辑代码写在这里,我们也可以(一般都)有多个编写逻辑代码的文件。

package.js是用来描述我们包的信息的文件,Meteor会根据该文件的信息组织和构建一个新的包。

package.js详解

接下来我们来详细说明一下package.js包,使用vim或者其他编辑工具打开package.js包。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Package.describe({
name: 'charlesoy:hello-world',
version: '0.0.1',
summary: '',
git: '',
documentation: 'README.md'
});
Package.onUse(function(api) {
api.versionsFrom('1.4.2.3');
api.use('ecmascript');
api.mainModule('hello-world.js');
});
Package.onTest(function(api) {
api.use('ecmascript');
api.use('tinytest');
api.use('charlesoy:hello-world');
api.mainModule('hello-world-tests.js');
});

上面就是Meteor为我们创建的默认的包的组织结构信息。一共包含了三个模块,Package.describe()方法用来描述包的基本信息;Package.onUse()方法用来描述包的一些依赖和执行环境信息;Package.onTest()方法用来描述测试环境信息。

Package.describe()方法

首先我们来看Package.describe()方法。

该方法接收一个对象作为参数,对象必须提供name,version,summary,git,和documentation五个属性。name表示包的名字,version表示包的版本,summary表示包的一句话的精炼总结,git填写该包的github地址,documentation表示包的文档的路径。

一般而言,我们主要需要编写的就是summary和git两个属性,以下是示例。

1
2
3
4
5
6
7
Package.describe({
name: 'charlesoy:hello-world',
version: '0.0.1',
summary: 'A hello world meteor package',
git: 'https://github.com/CharlesOy/helloWolrd', // doesn't exist
documentation: 'README.md'
});

Package.onUse()方法

Package.onUse()方法是我们包的核心。

该方法接收了一个函数作为参数,该函数需要提供一个api的参数。api有一些方法用于描述包依赖和执行环境的信息。

来看一个编写好了的Package.onUse()方法。

1
2
3
4
5
6
7
8
9
10
11
12
Package.onUse(function(api) {
api.versionsFrom('1.4.2.3');
api.use('ecmascript');
api.use([
'meteorhacks:picker',
], [
'server',
]);
api.use('random', 'client');
api.mainModule('server/main.js', 'server');
api.mainModule('client/main.js', 'client');
});

api.versionsFrom()方法表示当前包支持从哪个版本开始的Meteor。

api.use()方法表示的依赖Meteor包的依赖,该方法接收了三个参数,第一个表示依赖的Meteor包名,可以指定具体版本的包名,第二个参数表示需要执行的环境(e.g., ‘server’, ‘client’, ‘web.browser’, ‘web.cordova’),一个或多个环境的情况下参数可以以数组的形式,单个环境可以直接传入,第三个参数描述了一些具体的加载和依赖的行为。详情见API

1
README.md   client      imports     package.js  server      test

我们知道Meteor是一个存在client和server两种不同代码环境的框架,分别在浏览器端和服务器端执行。这里我们把浏览器的代码都放在client文件夹下,服务器的代码都放在server文件夹下,imports文件夹中主要存放通用代码,test文件夹存放测试代码。

很明显我们服务器端的入口在server/main.js,而浏览器的入口在client/main.js下。

Package.onTest()方法

Package.onTest()方法的使用类似Package.onUse()方法,不过该方法用于描述测试环境。

api.mainModule()方法指定了代码的执行入口。

在这里的例子中,为了更好的组织我们的代码,我们创建了四个文件夹这里我们把我们的目录修改了一下,分别是client,imports,server,和test。

Npm.depends()方法

实际上除了上述三个必要的方法,还有一个很重要的可选方法,Npm.depends()方法。

Package.onUse()方法中描述的依赖都是Meteor包的依赖,Npm.depends()方法用于描述Npm的依赖。

假设我们需要依赖lodash包(一个实用的基础工具包)并指定版本,我们可以这样写:

1
2
3
Npm.depends({
lodash: '4.17.2',
});

hello-world包

下面我们来编写我们的hello-world包,一个简单的逻辑,如果引入了该包,我们可以在浏览器中访问当前工程的根目录下的/hello_world路径,并返回Hello World到浏览器。

在上面的依赖中我们添加了依赖meteorhacks:picker,该包用于实现WebHook功能,这里我们完成一个简单地返回Hello World到浏览器的逻辑。

在server/main.js文件下编辑:

1
2
3
4
5
// server/main.js
import {Picker} from 'meteor/meteorhacks:picker';
Picker.route('/hello_world', (params, req, res) => {
res.end('Hello World');
});

为了系统测试,我们需要一个信的Meteor系统,为了将我们的包添加到新的测试工程中,可以将新的包整个目录直接放到新工程的packages目录下,也可以通过建立软链接的方式。

1
ln -s /PATH/TO/hello-world /PATH/TO/YOUR/METEOR/PROJECT/packages/hello-world

然后在工程的根目录下添加包:

1
meteor add charlesoy:hello-world

运行。

1
meteor

访问http://localhost:3000/hello_world。就能看到hello-world。

发布和更新到Atmosphere

在编写并测试完Meteor包之后,下一步就是发布。发布的命令很简单,meteor publish命令用于发布包。

在包的根目录下:

1
meteor publish --create

上述命令用于发布的新的或新的版本的包(比如我们的包已经发布了0.0.2版本了)。

发布完之后就可以在Atmosphere上搜索到我们的新包了。

如果需要更新当前已发布的包的最新版本的一些细微的细节(比如我们只做了一点细微的代码调整,或者只修改了README等,在不想发布新的版本时候),可以:

1
meteor publish --update

这样Atmosphere上最新的版本的包也会被修改。

总结

以上就是开发的Meteor包的需要知道的基本知识点和一般过程。

总结步骤就是:

  1. 初始化;
  2. 编写包的基本信息;
  3. 编写逻辑代码;
  4. 测试工作;
  5. 发布。

注意本文中的charlesoy:hello-world并没有发布到Atmosphere上,有兴趣的读者可以实现并发布更多实用和有意思的包,希望更多的人能为Meteor开源社区做更多的贡献。

参考

  1. Adding an existing project to GitHub using the command line - GitHub
  2. Publish Packages - Atmosphere
  3. Writing a Package - TheMeteorChef
  4. Atmosphere
  5. NPM
  6. Meteor Account