Realm Functions importing dependencies: Cannot find module 'module-name'

Hello :wave:

I have been working with functions and have set up a dependecies archive as specified here: https://docs.mongodb.com/realm/functions/upload-external-dependencies/

I followed the instructions to import them from here:https://docs.mongodb.com/realm/functions/import-external-dependencies/
For some reason, the .tar file did not work so I had to use .zip.
The modules show up on the UI, however importing them yields the error Cannot find module 'module-name'.

I have tried both the UI upload and through realm-cli.

Here are some screenshots:

16-02-2021 08-26-08 a.m.

16-02-2021 08-16-54 a.m.

1 Like

I just tested it out using this function and it worked for me:

exports = function () {
  const ajv = require("ajv");
  console.log("Made it this far");
  console.log(JSON.stringify(ajv, null, 4));
  
  return "All good";
}

I created the gz file with:

npm install ajv
tar -czf node_modules.tar.gz node_modules

Just to check – did you “REVIEW & DEPLOY” after uploading the modules?

1 Like

I am having the same issue as the original poster.
I create a .zip file, uploaded it manually, and the modules appear in the UI.

When I try to require it I get a ‘not found’ error. Please help.

I am not able to upload a screenshot (permission denied), but yes, the modules exist in the UI, yes the app is deployed.

My code is simply:

exports = async function getTimezones() {

  const moment = require("moment");
  
  console.log('moment found???');
};

with the error:
Cannot find module ‘moment’

trace:
FunctionError: Cannot find module ‘moment’
at require ()
at getTimezones$ (function.js:6:18)
at call ()
at tryCatch (:55:37)
at invoke (:281:22)
at :107:16
at call ()
at tryCatch (:55:37)
at invoke (:145:20)
at :180:11
at :3:6
at callInvokeWithMethodAndArg ()
at enqueue (:202:13)
at :107:16
at :226:9
at getTimezones (function.js:4:11)
at apply ()
at function_wrapper.js:3:1
at :11:1

Update: I followed the exactly how Andrew wrote them, and that seemed to work. This was beyond frustrating – I have a full page of notes I tried that didn’t work.

For future people, the difference between this “working” and not is either:

  • something internal on their side with the tar.gz
  • installing packages with npm (rather than zipping them manually) includes a handful of @ folders (ex. @babel) that might need to be included. I did an npm install --only=prod version.
1 Like

Thanks for letting us know, Eve. Sorry to hear that you had a difficult experience getting function dependencies working. I work on the Realm docs team, and I would be happy to update the existing import docs if you have any other information in your notes. I’d definitely like to keep other users from experiencing this level of frustration in the future!

In particular, I’m interested in hearing more about what the “something internal” that went wrong with your tar.gz was, and why --only=prod seemed to make a difference for you.

i followed the same way but i have same error

npm i chance
npm i nanoid
tar -czf node_modules.tar.gz node_modules

in function

exports = function(arg){
    const { nanoid } = require('nanoid')
    return "work"
};

result:

> ran on Fri Mar 19 2021 01:52:44 GMT+0300 (GMT+03:00)
> took 261.423531ms
> error: 
failed to eval source for module 'nanoid': node_modules/nanoid/index.cjs: Line 9:7 Unexpected identifier (and 16 more errors)
> trace: 
FunctionError: failed to eval source for module 'nanoid': node_modules/nanoid/index.cjs: Line 9:7 Unexpected identifier (and 16 more errors)
    at require (<native code>)
    at exports (function.js:2:24)
    at apply (<native code>)
    at function_wrapper.js:2:13
    at <anonymous>:11:1

I had the same issue when i packaged all the files in node_modules individualy. When i packaged only the root node_modules file it was working.

I have a weirder issue.
When I run the function individually, either from a client SDK or the web its works and the dependency is being imported and used.
When the function runs as part of a Trigger (Auth trigger for example) the dependency is not found and function fails.

From the logs:
Cannot find module ‘myModule’

Note:
The app is released to the Store and was working fine for the past 2-3 months. Something happened this month and it stopped working on with Triggers.

Hi @Georges_Jamous – are you able to share your function and I’ll try it out?

Unfortunately its a bit complex, however its a standard function that Trigger after Signup.

exports = async function({ user }) {
    const builder = require('myPackage');
    const userEmail = user.data.email;
    const userObjectId = BSON.ObjectId(user.id);
    const userProfulePartition = builder.partitionForUserProfile({ userId: user.id })
    ...clipped
    return { ok: 1 };
};
async function myFunction({ ...clipped }) {
    ...clipped
}


Config:

    "can_evaluate": {},
    "name": "afterSignup",
    "private": true
}

Dependencies were uploaded using the UI and compressed using tar -czf node_modules.tar.gz node_modules

I have two packages that are listed in the UI, which is correct.

Hope this helps

@Andrew_Morgan I have also tried something I thought maybe could overcome the issue until the problem is known.

Since by calling the function explicitly without a trigger it works, I thought I would replace the Trigger function with a proxy function that would in turn call my original function.

Like this

exports = async function(input) {
  return await context.functions.execute("afterSignup", input);
};

But no luck, it did not work either.

Try to import package in the proxy function instead of called function.

I just tried running a function with a dependency from a database trigger and it worked.

This is how I built the dependency file:

npm i -s lodash
tar -czf node_modules.tar.gz node_modules

I then uploaded it to my Realm app.

I created the tryDependency function:

exports = function(arg){
   const cloneDeep = require("lodash/cloneDeep");
   var original = { name: "Deep" };
   var copy = cloneDeep(original);
   copy.name = "John";
   console.log(`original: ${original.name}`);
   console.log(`copy: ${copy.name}`);
   return (original != copy);
};

I then register that function against a database trigger and update the collection to make it fire.

I get the correct results written to the logs:

1 Like

@Nemanja_Trivic so that was the initial problem the proxy is trying to solve. Not having the import in the Trigger. Anyhow, I have just tried it. It still not work.

@Andrew_Morgan mmm that is weird. The thing is that I have done the exact steps. And it’s not that it is not working generally. It is, it’s only failing on a Trigger (Auth, don’t know about Database)
Can you think of any reason why it wouldn’t?

From my side. I have provided a quick fix around this issue for now. and I will try to create a fresh App next week to try it like you did – just to cover my bases.

same problem here.

database triggers work well with external libraries.

just auth login and create failing.

im using e-mail/password method on graphql headers request.
POST …/graphql header: {email: yyyy@yyyy.com, password: yyyy}

this is my function code:

exports = function(authEvent) {
  const stripeConfiguration = context.values.get('stripe');
  const stripe = require('stripe')(stripeConfiguration.token);
  
  const customer = stripe.customers.create({
       name: "testing",
       email: "testing@gmail.com",
       metadata: {
         _partition: context.user.id
       }
     });
     
  return;
};

log message: Cannot find module ‘stripe’.

any idea?

@Bob_Dylan @Georges_Jamous I just called my same trigger from a login trigger — and sure enough, I get the dependency error when it runs. I’ll investigate some more.

In the meantime, one workaround would be to have your auth trigger insert a document into a “notifications” collection. There would be a database “insert” trigger on the “notifications” collection which did the actual work (including the use of your dependency) and optionally delete the notification document.

The engineering team has found the bug, and a fix should be deployed early next week.

Thanks to @Bob_Dylan, @Eve_Ragins, @Akifcan_Kara, @Nemanja_Trivic, and @Georges_Jamous for raising this and helping to narrow down the problem!

Cheers, Andrew.

2 Likes