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:
-
renaming index.js to index.mjs and change
"main": "index.js"
to"main": "index.mjs"
in package.json (the error persists) -
solution 1 plus removing
"type": "module"
from package.json (the error persists) -
removing
"type": "module"
from package.json (raises a SyntaxError: Unexpected token ‘export’) -
renaming index.js to index.cjs and change
"main": "index.js"
to"main": "index.cjs"
in package.json (raises a SyntaxError: Unexpected token ‘export’) -
solution 4 plus removing
"type": "module"
from package.json (raises a SyntaxError: Unexpected token ‘export’) -
adding the
--experimental-modules
flag ingcloud functions deploy
(shows unrecognized arguments: –experimental-modules) -
solution 6 but replacing
gcloud functions deploy
withgcloud beta functions deploy
(shows unrecognized arguments: –experimental-modules) -
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
Try something like this:
Execute this code inside a Google Cloud Functions to know which version of Node.js is running.
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.
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 usingrequire
syntax instead of using theimport
syntax.If someone is struggling to run typescript with ts-node, try this configuration
index.ts