21

Update this solution describes how to effectively use the new Npm system in Meteor.


What is the current method of using NPM packages in Meteor?

As of March 22, 2013, there is no official documentation on this.

There are several questions about this, notably this one, however the solution seems outdated: the engine branch no longer exists, and I haven't been able to find anything on Npm.require in Meteor.

Another solution, posted here, instructs to install into the .meteor/ build folders. As I am installing to Heroku, this doesn't seem like a valid solution, as the buildpack uses meteor bundle to bundle the program before running it. Thus, the temporary build folders don't seem like a valid option.

What has happened to Npm in meteor? What's the latest way of using Npm packages?

On a related note, I'm trying to use the Amazon SDK (for s3) - would it be better to just package it as a Meteorite package instead?

Community
  • 1
  • 1
Christian Stewart
  • 15,217
  • 20
  • 82
  • 139
  • This might be perfect for you: http://www.youtube.com/watch?v=kA-QB9rQCq8&feature=youtu.be Its already on the devel branch of meteor if you're using meteorite you could use it & itll be up in the next version of meteor – Tarang Mar 23 '13 at 05:29
  • Btw the engine branch & devel branch have been merged as of sometime in the past 2 weeks – Tarang Mar 23 '13 at 07:51
  • @Akshat is there a stable version of devel with this working? – Christian Stewart Mar 24 '13 at 02:06
  • @Akshat I found this: https://github.com/possibilities/meteor-awssum - should do what I need for now – Christian Stewart Mar 24 '13 at 02:08
  • possible duplicate of [How do we or can we use node modules via npm with Meteor?](http://stackoverflow.com/questions/10165978/how-do-we-or-can-we-use-node-modules-via-npm-with-meteor) – Dan Dascalescu Dec 17 '14 at 05:44
  • @DanDascalescu Bro, this question is very old. – Christian Stewart Dec 17 '14 at 06:54
  • So what? It shows up in SERPs and makes people spend extra time until the reach the current state of affairs. How do you think I ended up here? :) – Dan Dascalescu Dec 17 '14 at 06:58

5 Answers5

22

Arunoda has created an NPM Atmosphere package that allows you to use any NPM module like you're used to. It's very simple.

First, mrt add npm.

You can also install the package by using meteor-npm command from npm install -g meteor-npm.

Next, make a packages.json file in your root project directory, with the package names and versions:

{
    "foobar": "0.3.5",
    "loremipsum": "2.1.4"
}

Finally, use them with Meteor.require, like this: var FooBar = Meteor.require('foobar');

Christian Stewart
  • 15,217
  • 20
  • 82
  • 139
BenjaminRH
  • 11,974
  • 7
  • 49
  • 76
9

The current way of using NPMs in Meteor

  1. Replace the x's below with the NPM name
  2. Place the files outline below in /meteor-project-root/packages/x/
  3. meteor add x
  4. To use it just call X in your code (X.function())

x.js --------

X = Npm.require('x');

package.js --------

Package.describe({
  summary: "Meteor smart package for x node.js package"
});

Npm.depends({
  "x": "0.1.1"
});

Package.on_use(function (api) {
  api.add_files("x.js", ["client", "server"]);
});

Note: some packages will only work on client or server, if you are having issues, try only include the side you are going to use it on.

Pent
  • 1,049
  • 15
  • 17
  • You don't need to place files in `/meteor-project-root/`, Meteor fetches required packages automatically. – Christian Stewart May 30 '13 at 21:23
  • To clarify, place the two files outlined in the steps – Pent May 31 '13 at 00:44
  • Ah, I see. The issue is if you github this to somebody it won't work (collaboration). The best thing to do is wrap it up and post it to atmosphere, which is easy and quick and you give the entire community access to the package – Christian Stewart May 31 '13 at 04:30
  • 1
    This will definitely work properly if it's included in a github meteor project and someone clones it for local use. Meteor will automatically fetch the packages because they will be included in .meteor/packages – Pent May 31 '13 at 14:05
  • My bad, I thought you meant your meteor installation on your computer. What about deployment? Does this work the same? – Christian Stewart Jun 03 '13 at 17:19
  • yes, it works with deploy using bundle, I haven't used the meteor servers for it yet – Pent Jun 04 '13 at 04:36
  • I am getting a cannot find module error when I run meteor. And meteor add 'packagename' says packagename is already running! – cggaurav Jun 13 '13 at 15:45
  • or NPM is not defined in x.js! – cggaurav Jun 13 '13 at 15:48
3

I have been using the fantastic "browserify", which works like a charm. This is an alternative to using Arunda's NPM Atmosphere package, or using Npm.require with package.js, that arguably has some advantages:

  1. My code can use plain old "require" instead of Npm.require or Meteor.require. Obviously this is not a huge deal, but if I want to use this code outside Meteor it's nice to feel it's not dependent on Meteor.
  2. I don't have to worry about whether Meteor will once again change the way it thinks about Npm integration again.
  3. It allows me to use local development version of my own npm modules using npm link.

Here's how it works:

  1. I create a separate project for npm dependencies in a hidden .npm folder
  2. I use browserify to create a bundle.js that will be loaded by meteor
  3. I use grunt watch to make sure that every time I install a new npm package, the bundle.js is updated

Here's my directory structure:

my_meteor_project/
    lib/
        bundle.js

    .npm/
        node_modules
        README.md
        Gruntfile.js
        entrypoint.js
        package.json

Here's an example of entrypoint.js (unfortunately I have to use globals so that assert, url, and _ are available in Meteor code)

assert = require('assert');
url = require("url");
_ = require('underscore');

Here's the gruntfile:

module.exports = function(grunt) {
  grunt.initConfig({
    watch: {
      build: {
          files: ['./entrypoint.js', './package.json'],
          tasks: ['browserify2'],
          options: {
          }
      }
    },
    browserify2: {
      compile: {
        entry: './entrypoint.js',
        compile: '../lib/bundle.js'
      }
    },
  });

  grunt.loadNpmTasks('grunt-browserify2');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.registerTask('build', ['browserify2']);
};

I then use grunt watch to watch for changes to entry.js or new NPM installs

$ cd .npm
$ grunt watch:build &
[2] 44617
$ Running "watch:build" (watch) task
Waiting...

And then if I install an npm module, or modify entrypoint.js, bundle.js is updated:

$ npm install url -save
npm http GET https://registry.npmjs.org/punycode
npm http GET https://registry.npmjs.org/querystring
npm http 304 https://registry.npmjs.org/punycode
npm http 304 https://registry.npmjs.org/querystring
url@0.7.9 node_modules/url
├── querystring@0.1.0
└── punycode@1.0.0
$ OK
>> File "package.json" changed.

Running "browserify2:compile" (browserify2) task
File written to: ../lib/bundle.js

Done, without errors.
Completed in 1.256s at Thu Jul 11 2013 11:36:22 GMT-0600 (MDT) - Waiting...
Community
  • 1
  • 1
Jonathan Warden
  • 2,492
  • 1
  • 17
  • 11
  • Thanks for the information. Seems a bit complicated but thanks for adding the info. I recommend you register on Stack Overflow! – Christian Stewart Jul 12 '13 at 01:37
  • Hi I followed your instruction and got grunt to build my bundle.js file. But I have confused, how do I actually use the node module in my meteor project now that I have bundle.js file in lib folder? – Nearpoint Jun 11 '14 at 02:05
  • Ah I just read that you have to make them globals, nevermind my previous question. Everything is working great! The globals part is the only downside but hey I will take it. So with the mrt add npm I can use npm packages on the back end and with browserify (your solution) I can use npm packages on the front end. THis is awesome! THANKS!!! – Nearpoint Jun 11 '14 at 02:34
1

You can use https://atmospherejs.com/meteorhacks/npm

meteor add meteorhacks:npm

And then you can setup your package.json file:

{
  "redis": "0.8.2",
  "github": "0.1.8"
}

And use these packages:

var GithubApi = Meteor.npmRequire('github');
Peter Ilfrich
  • 3,727
  • 3
  • 31
  • 35
-1

as you are using meteorite, when you install a node module to .meteor/local/build/server/ you actually install to

~/.meteorite/meteors/meteor/meteor/f07715dc70de16a7aab84e56ab0c6cbd9c1f9dc6/dev_bundle/lib/node_modules

when you use mrt bundle to create your deployment bundle, the additional packages get bundled as well.

I have not tried it on Heroku but I checked that the node module gets packaged when using mrt bundle.

Micha Roon
  • 3,957
  • 2
  • 30
  • 48