universe

Meteor – NPM Integration

Posted on 09/04/2013 · Posted in Javascript

Since a few weeks, I’m testing MeteorJS and I really like it !

The 0.6 version has been released with NPM Integration. Which means that you can use any Node package without the need to tweak your Meteor Application.

At the time of writing, there is no official documentation about this point, only a github demo with xml2js.
This article is a short how-to about :

  • NPM Integration
  • Invoke functions from client to server
  • Use asynchronous methods on server with Fibers & Future

Let’s try to use freebox-sdk with a newly created Meteor Application.

1
2
3
4
5
$ meteor update #update meteor
$ meteor create freebox #create a new project
$ cd freebox
$ meteor #run your application
=> Meteor server running on: http://localhost:3000/

Meteor should run your newly created Application. Check that you get the Running message without any error. If you got some, just try to fix them 😉

Create the packages directory structure.

1
2
3
$ mkdir packages && cd packages
$ mkdir freebox-sdk && cd freebox-sdk
$ touch package.js freebox-sdk.js
1
2
3
4
5
6
7
8
// file: package.js
Npm.depends({
    'freebox-sdk': '0.3.0'
});

Package.on_use(function(api) {
    api.add_files('freebox-sdk.js', 'server');
});

The package.js contains the dependency definition.
When the package will be available, the freebox-sdk.js file will be added to the server scope.

1
2
3
4
5
6
7
// file: freebox-sdk.js
Freebox = Npm.require("freebox-sdk");
freeboxFacade = {
  get: function(options) {
    return new Freebox(options);
  }
};

Freebox & freeboxFacade are new global variables and are available on your Meteor Application.
For this use case, I have defined a useless Facade for the freebox-sdk package.
Use the var keyword to define variable only attached to this file.

At this point, freebox-sdk is automatically downloaded & attached to Meteor through Freebox & freeboxFacade variables.

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
// file: freebox.js
if (Meteor.isClient) {
    Template.hello.events({
        'click input[name="status"]' : function () {
            Meteor.call('getStatus', jQuery('input[name="password"]').val(), function(error, result) {
                if(_.isString(result)) {
                    console.log('message: ' + result);
                }
                else {
                    console.log('wifi active: ' + result.active);
                }
            });
        }
    });
}

if (Meteor.isServer) {
  Meteor.startup(function () {
    var Future = Npm.require('fibers/future');
   
    Meteor.methods({
        getStatus: function(password) {
            this.unblock();
            var future = new Future();            
            var freebox = new Freebox({password: password});
            freebox.on('connect', function() {
                freebox.wifiStatus(function (status) {
                    future.ret(status);
                });
            });
           
            freebox.on('error', function(message) {
                future.ret(message);
            });

            freebox.connect();

            // Wait for async to finish before returning
            // the result
            return future.wait();
        }
    });
  });
}

The freebox-sdk is composed of asynchronous methods, calls have to be done on server-side. I’m using Fibers to ‘wait’ for async (wifiStatus) to finish before returning the result to the client.

For this example I’m using some Meteor packages : jquery & underscore.

1
2
$ meteor add jquery
$ meteor add underscore

The HTML part is really simple. Just add a new button

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- file: freebox.html -->
<head>
  <title>test</title>
</head>

<body>
  {{> hello}}
</body>

<template name="hello">
  <h1>Hello World!</h1>
  <input type="button" value="get status" name="status" />
</template>

Now,
Run your meteor application, go to http://localhost:3000/ and open a JS Console. Click on the “Click button” and see if your wifi is enable!

×If the NPM module has architecture-specific binary components

If the NPM module has architecture-specific binary components, bundles built with meteor bundle or meteor deploy will contain the components as built for the developer’s platform and may not run on other platforms.