Helloïs
Helloïs

Reputation: 152

Failed to loading node_modules in Google Cloud Function (index.js, not on the project root)

So I need to deploy a Google Cloud Function to make a select request on a PostgreSQL database (Cloud SQL). I need to use the pg module, then I install it with: npm i pg. You need to know that my project directories are like that:

project
     \_____ node_modules
     \_____ src
              \_____ index.js

     \_____ package.json
     \_____ package-lock.json

After npm install node_modules is created with package-lock.json, then the package.json dependencies was updated automatically. My package.json file:

{
    "name": "postgre-sql",
    "version": "0.1.0",
    "dependencies": {
        "pg": "^7.12.1"
    }
}

So far, no problem...

Now I write my code and make exports to use my simple code in Google Cloud Platform. I use commande line and I move on my src directory to do the following line:

gcloud functions deploy functionNameInGCP --runtime nodejs10 --trigger-http --entry-point functionNameInIndexJS --region europe-west1

The problem is that the deploying doesn't work.

ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Function failed on loading user code. Error message: Provided module can't be loaded.
Did you list all required modules in the package.json dependencies?
Detailed stack trace: Error: Cannot find module 'pg'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:582:15)
    at Function.Module._load (internal/modules/cjs/loader.js:508:25)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:22:18)
    at Object.<anonymous> (/srv/functions/index.js:3:12)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
    at Module.load (internal/modules/cjs/loader.js:600:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
    at Function.Module._load (internal/modules/cjs/loader.js:531:3)
Could not load the function, shutting down.

I have tried many solution to fix my problem, I know that I can move my index.js in the root directory but I need to keep the src directory. When I move it in the root directory, it works, but I don't know how it works when we the index.js is not on the root.

Here my index.js file:

'use strict'

const pg = require('pg');

exports.select = (request, result) =>
{
    console.log('On exports.select !!!');
    const config =
    {
        host: '/cloudsql/project:region:instanceName',
        user: 'user',
        password: 'password',
        database: 'postgres'
    };

    let pool = new pg.Pool(config);

    pool.query('SELECT 1;', (err, res) =>
    {
        console.log('On query !!!');
        if(err)
        {
            console.error(err);
            result.status(500);
            result.send(err);
        } else
        {
            console.table(res.row);
            result.status(200);
            result.send(JSON.stringify(res));
        }
    });

    pool.end();

    console.log('Export.select is finish !');
}

So, in my project I want to keep the package.json file on the root. Then on src directory I will put many other directories for all my Google Cloud Functions. For example, in src folder I will create a new postgreSQL folder with an index.js inside to do different things. Then I will create a new folder, for example, Redis folder also with index.js inside: like that:

project
     \_____ node_modules
     \_____ src
              \_____ postgreSQL
                         \________ index.js
              \_____ Redis
                         \________ index.js

     \_____ package.json
     \_____ package-lock.json

So, if I specified "main": "./src/index.js" on package.json, it's because I want to have a main. But I don't want that, I want to have a project folder with all my Google Cloud Functions.

Thanks for your time.

Upvotes: 2

Views: 2267

Answers (1)

Stefan G.
Stefan G.

Reputation: 938

I just replicated your issue and found a solution. Thanks for providing all the code you used and such a good description of what you want to achieve, it really helps a lot.

I reproduced your exact file distribution and made the following changes to my package.json:

  "name": "cloudfunctiontest4",
  "version": "1.0.0",
  "description": "",
  "main": "./src/index.js",
  "dependencies": {
    "pg": "^7.12.1"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

If you specify where your index is using main you won't get any problems to deploy having it there. Make sure to execute your gcloud deploy, out of your src/ folder where your package.json is, it uses the main you specified to know what entry-point to use.

I used the following gcloud command:

gcloud functions deploy testfunction4 --runtime nodejs10 --trigger-http --entry-point select --region europe-west1

Let me know if it worked for you.

EDIT:

Have a look at this post, this might fit your use case.

I think that my answer was answering your original question, the development you added might be the case of a new thread/question.

Let me know.

Upvotes: 3

Related Questions