首页 > 解决方案 > 无法在 Google Cloud Functions 中使用 ES 模块

问题描述

我正在尝试使用 Node.js 部署一个非常基本的 Google Cloud 无服务器应用程序,但它一直在 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.

这是我的index.js文件:

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

这是我的package.json文件:

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

我正在使用它运行它

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

我已经尝试过以下方法:

  1. 将index.js重命名为index.mjs并更改"main": "index.js""main": "index.mjs"in package.json(错误仍然存​​在)

  2. 解决方案1加上"type": "module"package.json中删除(错误仍然存​​在)

  3. "type": "module"package.json中删除(引发 SyntaxError: Unexpected token 'export')

  4. 将index.js重命名为index.cjs并更改"main": "index.js""main": "index.cjs"in package.json(引发 SyntaxError: Unexpected token 'export')

  5. 解决方案 4 加上"type": "module"package.json中删除(引发 SyntaxError: Unexpected token 'export')

  6. 添加--experimental-modules标志gcloud functions deploy(显示无法识别的参数:--experimental-modules)

  7. 解决方案 6,但替换gcloud functions deploygcloud beta functions deploy(显示无法识别的参数:--experimental-modules)

  8. 完全卸载 Google Cloud SDK 并再次尝试上述所有解决方案

唯一有效的解决方案是解决方案 3 加上使用

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

但是,我想将它用于带有node-telegram-bot-api模块的 Telegram 机器人,但是因为我"type": "module"package.json中删除了,所以当我导入 Telegram API 时,它会引发“SyntaxError: Cannot use import statement outside a module”。

项目结构是使用 创建的npm init,如下所示。

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

有什么想法吗?我的 Node.js 版本是 v14.17.0,我的 Google Cloud SDK 版本是 v342.0.0。

标签: javascriptnode.jsgoogle-cloud-functions

解决方案


Google Cloud Functions(以及 Firebase Functions)尚不支持 ESM 模块:

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

现在我认为您正在混淆使用和打包 ES 模块。您不必将函数代码打包为 ES 模块即可使用node-telegram-bot-api模块。require只需使用语法而不是使用语法导入它import


推荐阅读