Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't use ES modules in Google Cloud Functions

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.

like image 745
enzo Avatar asked Aug 14 '26 09:08

enzo


1 Answers

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.

like image 120
Daniel L Avatar answered Aug 16 '26 00:08

Daniel L