How to build a Meteor smart package
Asked Answered
I

5

42

How can one build a Meteor smart package that would show up in meteor list?

Building Atmosphere packages is reasonably well documented, but building Meteor packages isn't.

Integer answered 11/4, 2012 at 21:53 Comment(1)
tks for the notification - updatedInteger
P
21

Meteor now supports a create --package command.

See the meteor docs.

Example (substitute your own meteor developer account for "cunneen"):

meteor create --package cunneen:foo

Output:

cunneen:foo: created in your app

Results:

packages/cunneen:foo/package.js

Package.describe({
  name: 'cunneen:foo',
  version: '0.0.1',
  // Brief, one-line summary of the package.
  summary: '',
  // URL to the Git repository containing the source code for this package.
  git: '',
  // By default, Meteor will default to using README.md for documentation.
  // To avoid submitting documentation, set this field to null.
  documentation: 'README.md'
});

Package.onUse(function(api) {
  api.versionsFrom('1.0.3.1');
  api.addFiles('cunneen:foo.js');
});

Package.onTest(function(api) {
  api.use('tinytest');
  api.use('cunneen:foo');
  api.addFiles('cunneen:foo-tests.js');
});

packages/cunneen:foo/foo.js (empty file)

// Write your package code here!

packages/cunneen:foo/foo-tests.js

// Write your tests here!
// Here is an example.
Tinytest.add('example', function (test) {
  test.equal(true, true);
});

packages/cunneen:foo/README.md (empty file)

# cunneen:foo package

For a good (VERY comprehensive) example, take a look at iron-router.

Ptyalin answered 30/5, 2014 at 8:33 Comment(1)
mrt create-package seems outdated. Use meteor create --package package-nameBeene
A
14

See cobberboy's answer below

Below is outdated information:

See info about the new meteor packaging system: https://meteorhacks.com/meteor-weekly-meteor-09-rc-meteor-new-logo-underscore-in-templates.html

** older information **

There is updated information about writing your own package and about repackaging existing 3rd party libraries. The API wont be stable till 1.0 though, so be prepared to make many changes.

I have included boiler plate to help w/ making it both a node and a meteor usable library at once. This took me quite some time to figure out, open to suggestions.

package: /lib/my.js

if (typeof Meteor === 'undefined) {
    // Not Running In Meteor (nodejs code)
    // example NPM/Node Dependencies that we'll use
    var async = require('async');
    var debug = require('debug')('my:package');
    var mongodb = require('mongodb');

    var http = require('http');  
} else {
    // Running as Meteor Package
    var async = Npm.require('async');
    var debug = Npm.require('debug')('my:package');
    var mongodb = Npm.require('mongodb');

    // node core module 'http'
    // use Npm.require to require node core modules
    // but doesnt need Npm.depends in the package.js file
    var http = Npm.require('http');
}

var constructor = function(property1) {
    this.property1 = property1; // or whatever in your constructor.
};

if (typeof Meteor === 'undefined') {
   // Export it node style
   My = exports = module.exports = constructor; // Limit scope to this nodejs file
} else {
   // Export it meteor style
   My = constructor; // Make it a global
}

// Proceed defining methods / properties as usual.
My.prototype.doStuff = function() { console.log('hello world'); }

package: /package.js

Package.describe({
  summary: "My Meteor Package"
});

/**
 * Ex: Some NPM Dependencies
 */
Npm.depends({
  'async': '0.2.9',
  'debug': '0.7.2',
  'mongodb': '1.3.18'
});

/**
 * On use we'll add files and export our tool
 */
Package.on_use(function (api) {
  /**
   * Add all the files, in the order of their dependence (eg, if A.js depends on B.js, B.js must be before A.js)
   */
  api.add_files([
    'lib/my.js' // <-- include all the necessary files in the package
    ],
    'server'); // Can be 'server', 'client' , ['client','server']

  /**
   * Only expose the My constructor, only export if meteor > 0.6.5
   */
  api.export && api.export(['My'], 'server'); // 1st arg can be array of exported constructors/objects, 2nd can be 'server', 'client', ['client', 'server']
});

meteor app: some file in the proper client/server context (as defined in package.js)

var my = new My('a property');
my.doStuff(); // console logs 'hello world' on the server

meteor app: smart.json , add your file to the packages list

{
    packages:{
        "node-my": {
            "git": "[email protected]:myAccount/node-my.git"
        }
    }
}

Finally run mrt install on the command line to get it to install the package .. Whew!

Absurdity answered 15/8, 2013 at 19:2 Comment(3)
should be run mrt add node-my before mrtColumbine
I don't see clear documentation of how to create a package at the referenced link. Is there a good reference for the current way to do this somewhere?Pang
see answer by @Ptyalin below. OP please change the accepted answer to the one by cobberboy.Absurdity
N
13

NOTE: Package development is currently undocumented, and the API will change. You've been warned!

That said, it's actually pretty easy to get started:

First, git clone a copy of the meteor repo. Make yourself a new directory in /packages. Put a package.js file in the directory (see other packages for examples). Now you've got a package!

Next, run the meteor script from your checkout (not the one installed by the installer). When run from the checkout, the script will use the local packages directory in the checkout. It will even hot-reload when you change code in your package.

Have a look through the other packages for examples and to get an idea what the API does.

EDIT: much progress has been made in terms of third-party packages. Check out http://oortcloud.github.com/meteorite/ and https://atmosphere.meteor.com/

Ninon answered 11/4, 2012 at 22:52 Comment(3)
That'd be great to have a npm like tool ;) I'm looking for a way to import momentjs.com in my Meteor project. What is the best solution to have access to this library client/server side? Thank for your amazing work!Greenwell
Amazing!! app_root/lib/moment.js and... that's sit?? just... amazing... I didn't find it in doc, no?Greenwell
@Ninon I cloned the repo from github, went to the cloned meteor folder, downloaded a custom jquery build and placed the resulting js file in a new subfolder inside packages. I copy/pasted a package.js file over from the existing jquerypackage and edited it's content to reflect the name of my custom jquerybuild. Next I went up to the root of my cloned meteorfolder and ran ./meteor and I got Installed dependency kit v0.1.4 in dev_bundle.. So far so good. But running meteor list does not show my new package. Thoughts?Uboat
F
6

This was dated Jun 12 2013. It was the correct answer at the time, and is still an alternative solution:

Like n1mmy said. It's undocumented, and you should use meteorite.

If you insist on creating a package with meteor, I found a good unofficial How-to, but you really shouldn't do this. Meteor will be coming out with a way to create packages in an upcoming release.

Bulding a Meteor package: https://coderwall.com/p/ork35q

The way I would do it is with Meteorite

Obviously you have node, and I assume you have node package manager (npm), so your best way to make a meteor package to date, is to make a meteorite smart package.

npm install meteorite

Meteorite smart packages contain 2 key files essential for package creation - package.js - smart.json

Meteorite files are stored under your system logged in user account: ~/.meteorite/
but are symlinked to your current where you created a meteor app: project/.meteor/meteorite/

Sample package.js:

Package.describe({
   summary: "User analytics suite for meteor"
});

Package.on_use(function (api) {
   api.add_files('user_analytics.js', 'client');
});

Sample smart.json

{
   "name": "User analytics",
   "description": "User Analytics",
   "homepage": "http://yourHomepage.com",
   "author": "Eric Leroy",
   "version": "0.1",
   "git": "https://github.com/yipyo",
   "packages" : {}
}

If you need anymore info, you should install a mrt package from the list:

mrt list

then analyze the files under your app/.meteor/meteorite/ directory.

Hope this helps, and keep developing the best language of the future.

Here are some helpful links:

Falk answered 28/5, 2013 at 8:23 Comment(1)
mrt list actually passes the list command through to meteor, so you'l get the smart packages, not "mrt packages" (i.e. those on Atmosphere)Beckett
C
6

There is a good screencast on this topic on EventedMind.

Carminacarminative answered 10/7, 2013 at 21:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.