skip to Main Content

I’m trying to deploy a very basic Google Cloud serverless application using Node.js, but it keeps showing the following error on Google Cloud Console:

Provided module can't be loaded.
Is there a syntax error in your code?
Detailed stack trace: Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /workspace/index.js
require() of ES modules is not supported.
require() of /workspace/index.js from /layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/loader.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /workspace/package.json.
 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1080:13)
 at Module.load (internal/modules/cjs/loader.js:928:32)
 at Function.Module._load (internal/modules/cjs/loader.js:769:14)
 at Module.require (internal/modules/cjs/loader.js:952:19)
 at require (internal/modules/cjs/helpers.js:88:18)
 at Object.getUserFunction (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/loader.js:29:32)
 at Object.<anonymous> (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/index.js:77:32)
 at Module._compile (internal/modules/cjs/loader.js:1063:30)
 at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
 at Module.load (internal/modules/cjs/loader.js:928:32)
Could not load the function, shutting down.

Here’s my index.js file:

export function foobar(req, res) {
    res.status(200).send("Hello World!");
}

Here’s my package.json file:

{
  ...
  "main": "index.js",
  "type": "module",
  ...
}

I’m running it using

gcloud functions deploy foobar --region europe-west1 --runtime nodejs14 --trigger-http --allow-unauthenticated

I’ve already tried the following:

  1. renaming index.js to index.mjs and change "main": "index.js" to "main": "index.mjs" in package.json (the error persists)

  2. solution 1 plus removing "type": "module" from package.json (the error persists)

  3. removing "type": "module" from package.json (raises a SyntaxError: Unexpected token ‘export’)

  4. renaming index.js to index.cjs and change "main": "index.js" to "main": "index.cjs" in package.json (raises a SyntaxError: Unexpected token ‘export’)

  5. solution 4 plus removing "type": "module" from package.json (raises a SyntaxError: Unexpected token ‘export’)

  6. adding the --experimental-modules flag in gcloud functions deploy (shows unrecognized arguments: –experimental-modules)

  7. solution 6 but replacing gcloud functions deploy with gcloud beta functions deploy (shows unrecognized arguments: –experimental-modules)

  8. uninstalling Google Cloud SDK completely and trying all above solutions again

The only solution that worked was solution 3 plus using

exports.foobar = (req, res) => {
    res.status(200).send("Hello World!");
}

However, I want to use it for a Telegram bot with the node-telegram-bot-api module, but because I removed "type": "module" from package.json, it raises "SyntaxError: Cannot use import statement outside a module" when I import the Telegram API.

The project structure was created using npm init, as shown below.

.
├── index.js
└── package.json

Any thoughts? My Node.js version is v14.17.0 and my Google Cloud SDK version is v342.0.0.

4

Answers


  1. Try something like this:

    const functions = require('firebase-functions');
       
    exports.foobar= functions.https.onRequest((req, res) => {
      res.status(200).send("Hello World!");
    });
    
    Login or Signup to reply.
  2. Execute this code inside a Google Cloud Functions to know which version of Node.js is running.

    console.log(`Hello Node.js v${process.versions.node}!`);
    

    I think Google Cloud required: node: ’12’ (Same that Firebase)

    With the release of Node version 15.3.0, ES modules can be used without an experimental flag.

    Login or Signup to reply.
  3. Google Cloud Functions (and therefore Firebase Functions) does not support ESM modules yet:

    https://github.com/GoogleCloudPlatform/functions-framework-nodejs/issues/233
    https://github.com/firebase/firebase-tools/issues/2994

    Now I think you are conflating using and packaging ES modules. You don’t have to package your functions code as an ES module in order to use node-telegram-bot-api module. Just import it using require syntax instead of using the import syntax.

    Login or Signup to reply.
  4. If someone is struggling to run typescript with ts-node, try this configuration

    {
      "type": "module",
      "scripts": {
        "start": "node --loader ts-node/esm node_modules/@google-cloud/functions-framework/build/src/main.js --target=default"
      },
      "engines": {
        "node": ">=16.0.0"
      },
      "dependencies": {
        "@google-cloud/functions-framework": "^3.1.2",
        "@types/express": "^4.17.13",
        "ts-node": "^10.8.1"
      }
    }
    

    index.ts

    import { Request, Response } from 'express'
    
    export default async (req: Request, res: Response) => {
      // your code
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search