Moment-recur crashes at startup: "Can't find moment" (SOLVED)

I’m doing a Meteor project that requires recurring events, and I’m having a problem getting the moment-recur package to work (gilbertwat:moment-recur). If I create a new project, and then add momentjs:moment and gilbertwat:moment-recur, then the recur package throws an error at startup saying that it can’t find moment. Moment is working correctly both in my app and in the console. I did some googling and there seems to be some issue with local vs global installations of moment when the moment-recur is installed as an NPM. Honestly, I’m not familiar enough with Meteor packages to know if this has anything to do with it or not. Anybody have any ideas? I’m stuck. Thanks.

Here’s the error at the command line when I try to start Meteor:

=> Started proxy.
=> Started MongoDB.
=> Exited with code: 8
W20160202-09:23:22.927(-8)? (STDERR)
W20160202-09:23:22.927(-8)? (STDERR) C:\Users\Jerimiah\AppData\Local.meteor\packages\meteor-tool\1.1.10\mt-os.windows.x86_32\dev_bundle\ser
ver-lib\node_modules\fibers\future.js:245
W20160202-09:23:22.927(-8)? (STDERR) throw(ex);
W20160202-09:23:22.927(-8)? (STDERR) ^
W20160202-09:23:22.927(-8)? (STDERR) Error: Can’t find moment
W20160202-09:23:22.927(-8)? (STDERR) at Error ()
W20160202-09:23:22.927(-8)? (STDERR) at Package (packages/gilbertwat_moment-recur/moment-recur.js:15:1)
W20160202-09:23:22.927(-8)? (STDERR) at hasModule (packages/gilbertwat_moment-recur/moment-recur.js:7:1)
W20160202-09:23:22.927(-8)? (STDERR) at Package (packages/gilbertwat_moment-recur/moment-recur.js:9:1)
W20160202-09:23:22.927(-8)? (STDERR) at C:\Users\Jerimiah\MeteorDev\recur-test.meteor\local\build\programs\server\packages\gilbertwat_m
oment-recur.js:768:4
W20160202-09:23:22.927(-8)? (STDERR) at C:\Users\Jerimiah\MeteorDev\recur-test.meteor\local\build\programs\server\packages\gilbertwat_m
oment-recur.js:775:3
W20160202-09:23:22.927(-8)? (STDERR) at C:\Users\Jerimiah\MeteorDev\recur-test.meteor\local\build\programs\server\boot.js:242:10
W20160202-09:23:22.927(-8)? (STDERR) at Array.forEach (native)
W20160202-09:23:22.927(-8)? (STDERR) at Function..each..forEach (C:\Users\Jerimiah\AppData\Local.meteor\packages\meteor-tool\1.1.10\m
t-os.windows.x86_32\dev_bundle\server-lib\node_modules\underscore\underscore.js:79:11)
W20160202-09:23:22.927(-8)? (STDERR) at C:\Users\Jerimiah\MeteorDev\recur-test.meteor\local\build\programs\server\boot.js:137:5

Hmm - it looks like that package’s module loading code isn’t handling Meteor properly. You can get it working by:

a) Creating a packages directory in the root of your app.

b) Inside the packages directory run: git clone https://github.com/gilbertwat/moment-recur.git

c) Update the packages moment-recur.js file so that instead of just having an else on line 6, you would have:

} else if (typeof Package === 'undefined') {

This will skip line 7 if using Meteor, which will then let your app start.

I tried your workaround, and it worked to an extent - my app no longer crashed at startup. But I still wasn’t able to invoke the .recur() function as an extension of a moment object in either the browser console or in my code.

I did some more digging and it looks like the way the plugin is written is not natively friendly to meteor. For comparison, I installed a different moment plugin from atmosphere called momentjs:twix. The outer wrapper of that code is a lot different than what is in moment-recur.js. Looking more closely at gilbertwats’s repo for the meteor package, I noticed there is actually another branch that fixes this problem by invoking a couple small javascript files when meteor uses and then disposes of a recur instance. I don’t understand the witchcraft behind it, but it works. Here’s the code snippets that make it work, for everyone’s reference:

package.js:
Package.onUse(function(api) {
api.versionsFrom(‘METEOR@0.9.3.1’);
api.use(‘momentjs:moment@2.11.1’);
api.addFiles([
‘meteor/export.js’,
‘moment-recur.js’,
‘meteor/clear.js’
]);

export.js:
//Because the official package delete the this.moment
this.moment = moment;

clear.js:
//Because the official package delete the this.moment
moment = this.moment;
delete this.moment;

I wish I knew enough about javascript to know why this code is necessary, and how it works, but I’ll have to be satisfied with the fact that it is working. :slight_smile: Thanks for the help. It got me unstuck, at least.

-Jerimiah

By the way, I put a repo up with these changes. There is a submodule in there for the original moment-recur package, and I have found out the hard way that cloning with https doesn’t work with submodules, FYI, so use this:

git@github.com:jerimiah797/meteor-moment-recur.git

and don’t forget to ‘git submodule update’. :slight_smile: