Reputation: 11496
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 in gcloud functions deploy
(shows unrecognized arguments: --experimental-modules)
solution 6 but replacing gcloud functions deploy
with gcloud 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.
Upvotes: 5
Views: 6932
Reputation: 39
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
}
Upvotes: 0
Reputation: 540
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.
Upvotes: 2
Reputation: 1375
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.
Upvotes: 0
Reputation: 173
Try something like this:
const functions = require('firebase-functions');
exports.foobar= functions.https.onRequest((req, res) => {
res.status(200).send("Hello World!");
});
Upvotes: 0