kip2
kip2

Reputation: 6913

Deploying to Firestore Cloud Functions - "Error: cannot find module"

I'm getting this when trying to deploy functions:

Deployment error.
Build failed: npm ERR! code ENOLOCAL
npm ERR! Could not install from "../config/myconfig" as it does not contain a package.json file.

This is after even updating the package.json in my functions directory as suggested by the official docs to look like this:

...
"dependencies": {
    "sms_sender": "file:./",
    "myconfig": "file:../config/myconfig",
    "firebase-admin": "^8.10.0",
    "firebase-functions": "^3.6.1"
  },
...

which is supposed to fix this error as seen in the stacktrace on the GCP logs:

A 2020-08-27T12:43:39.026Z sendMessage Could not load the function, shutting down. sendMessage
A 2020-08-27T12:43:39.020Z sendMessage     at Function.Module._load (internal/modules/cjs/loader.js:585:3) sendMessage
A 2020-08-27T12:43:39.020Z sendMessage     at tryModuleLoad (internal/modules/cjs/loader.js:593:12) sendMessage
A 2020-08-27T12:43:39.020Z sendMessage     at Module.load (internal/modules/cjs/loader.js:653:32) sendMessage
A 2020-08-27T12:43:39.020Z sendMessage     at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10) sendMessage
A 2020-08-27T12:43:39.019Z sendMessage     at Module._compile (internal/modules/cjs/loader.js:778:30) sendMessage
A 2020-08-27T12:43:39.019Z sendMessage     at Object.<anonymous> (/workspace/sms_sender.js:5:16) sendMessage
A 2020-08-27T12:43:39.019Z sendMessage     at require (internal/modules/cjs/helpers.js:25:18) sendMessage
A 2020-08-27T12:43:39.019Z sendMessage     at Module.require (internal/modules/cjs/loader.js:692:17) sendMessage
A 2020-08-27T12:43:39.019Z sendMessage     at Function.Module._load (internal/modules/cjs/loader.js:562:25) sendMessage
A 2020-08-27T12:43:39.019Z sendMessage     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15) sendMessage
A 2020-08-27T12:43:39.019Z sendMessage Detailed stack trace: Error: Cannot find module '../config/myconfig' sendMessage
A 2020-08-27T12:43:39.019Z sendMessage Did you list all required modules in the package.json dependencies? sendMessage
A 2020-08-27T12:43:39.019Z sendMessage Provided module can't be loaded. sendMessage

sendMessage is my background function in index.js which imports the 'sms_sender' module:

exports.sendMessage = functions.https.onRequest(async (req, res) => {
  ...
  // send the sendMessage
  sms_sender.sendMsg("+123567890", "hello, my friend!");
  ...
}

sms_sender.js:

const config = require('../config/myconfig');

module.exports = {
  sendMsg: async function(recipientNum, message) {
    ...
  }
}

project structure:

/project-root
    /config
        myconfig.js
    /functions
        index.js
        sms_sender.js
        package.json
    /tests
    ...
    package.json

I looked at this related post but it was talking about an external dependency.

How should I tell Node/npm that 'myconfig' is just a local file and not really a module per se? I tried putting in a stub 'package.json' file to /config but I still get the same Could not install from "../config/myconfig" as it does not contain a package.json file. error

Upvotes: 1

Views: 3098

Answers (3)

Abraham
Abraham

Reputation: 15830

Make sure you installed the package form the functions directory instead of the project directory. It works locally and creates error when you deploy it. so,

cd functions
npm install [your package]

and it will work fine

Upvotes: 2

kip2
kip2

Reputation: 6913

This related discussion on the Firebase tools repo was somewhat helpful but the most popular answer (creating a tarball under the ./functions directory) did not quite work for me.

What worked: create a symbolic link of the root-level ./config folder inside of ./functions:

cd functions
ln -s ../config/ config

This strategy avails all the files in config into functions modules without causing me to re-write all other parts of my app that relay on the described file/folder structure

The only other changes I had to make:

// functions/package.json
...
"dependencies": {
    "sms_sender": "file:./",
    "myconfig": "file:./config/",
    "firebase-admin": "^8.10.0",
    "firebase-functions": "^3.6.1"
  },
...

and

// sms_sender.js
const config = require('./config/myconfig');
... // everything else is as before

Upvotes: 0

Michael Bleigh
Michael Bleigh

Reputation: 26343

You need to include all files you intend to require inside the functions directory, as only those files are packaged up and uploaded to create the source for the Cloud Function.If you move config into the functions directory you should have better luck.

Upvotes: 1

Related Questions