【问题标题】:Can't use ES modules in Google Cloud Functions无法在 Google Cloud Functions 中使用 ES 模块
【发布时间】:2021-05-30 18:25:27
【问题描述】:

我正在尝试使用 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 并将 package.json 中的 "main": "index.js" 更改为 "main": "index.mjs"(错误仍然存​​在)

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

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

  4. index.js 重命名为 index.cjs 并将 package.json 中的 "main": "index.js" 更改为 "main": "index.cjs"(引发 SyntaxError:意外的令牌“导出”)

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

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

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

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

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

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

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

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

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

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

【问题讨论】:

    标签: javascript node.js google-cloud-functions


    【解决方案1】:

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

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

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

    【讨论】:

    【解决方案2】:

    试试这样的:

    const functions = require('firebase-functions');
       
    exports.foobar= functions.https.onRequest((req, res) => {
      res.status(200).send("Hello World!");
    });
    

    【讨论】:

    • 谢谢你的回答,我做了npm install firebase-functions。当我在本地运行它时,它显示警告“FIREBASE_CONFIG 和 GCLOUD_PROJECT 环境变量丢失。初始化 firebase-admin 将失败”。当我使用gcloud 运行它时,the Log Console displayed “错误:找不到模块'firebase-admin”。由于我只使用 Google Cloud Functions,我是否必须设置 Firebase 才能使其正常工作?
    【解决方案3】:

    在 Google Cloud Functions 中执行此代码以了解正在运行的 Node.js 版本。

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

    我认为需要 Google Cloud:节点:'12'(与 Firebase 相同)

    随着 Node 版本 15.3.0 的发布,ES 模块可以在没有实验标志的情况下使用。

    【讨论】:

    • 您好,感谢您的回答。它显示“Hello Node.js v14.17.0!” in the Log Console。我应该降级还是升级它?
    • 使用 ES 模块的最低 Node 版本可以在没有实验标志的情况下使用是 15.3.0。如果 Google Cloud 允许您升级 Node.js 版本,请升级它,如果没有尝试是否可以使用实验标志或不使用 ES 模块
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 2020-08-31
    • 1970-01-01
    • 2018-09-10
    • 2022-12-13
    • 2021-12-26
    • 2019-03-08
    相关资源
    最近更新 更多