NodeJS 14.x - 原生 AWS Lambda 导入/导出支持

use*_*997 17 javascript containers amazon-web-services node.js aws-lambda

我希望利用ES6 附带的本机导入/导出

我在 AWS Lambda 中使用无服务器容器。

我有我的Dockerfile看起来像这样:

FROM public.ecr.aws/lambda/nodejs:14

COPY app ./

RUN npm install

CMD [ "app.handler" ]
Run Code Online (Sandbox Code Playgroud)

然后我有一个app包含我的应用程序代码的目录。该app.js代码如下所示:

import { success } from './utils/log';

exports.handler = async () => {
  success('lambda invoked');
  const response = 'Hello World';
  return {
    statusCode: 200,
    body: JSON.stringify(response),
    isBase64Encoded: false,
  };
};
Run Code Online (Sandbox Code Playgroud)

正如您从这一行中看到的,import { success } from './utils/log';我正在使用本机导入。

在我的 package.json 中,我指定了这个:

  "type": "module"
Run Code Online (Sandbox Code Playgroud)

因为我需要告诉我的应用程序这是一个模块,我想本地导入。如果我不指定这一点,我会得到:

{
    "errorType": "Runtime.UserCodeSyntaxError",
    "errorMessage": "SyntaxError: Cannot use import statement outside a module",
    "stack": [
        "Runtime.UserCodeSyntaxError: SyntaxError: Cannot use import statement outside a module",
        "    at _loadUserApp (/var/runtime/UserFunction.js:98:13)",
        "    at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
        "    at Object.<anonymous> (/var/runtime/index.js:43:30)",
        "    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)",
        "    at Function.Module._load (internal/modules/cjs/loader.js:769:14)",
        "    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)",
        "    at internal/main/run_main_module.js:17:47"
    ]
}
Run Code Online (Sandbox Code Playgroud)

所以,我指定它,告诉 Lambda 这是一个模块。但是,对于我的一生,我无法让它工作,我看到了这个错误:

{
    "errorType": "Error",
    "errorMessage": "Must use import to load ES Module: /var/task/app.js\nrequire() of ES modules is not supported.\nrequire() of /var/task/app.js from /var/runtime/UserFunction.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.\nInstead rename app.js to end in .cjs, change the requiring code to use import(), or remove \"type\": \"module\" from /var/task/package.json.\n",
    "code": "ERR_REQUIRE_ESM",
    "stack": [
        "Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /var/task/app.js",
        "require() of ES modules is not supported.",
        "require() of /var/task/app.js from /var/runtime/UserFunction.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 app.js to end in .cjs, change the requiring code to use import(), or remove \"type\": \"module\" from /var/task/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 _tryRequire (/var/runtime/UserFunction.js:75:12)",
        "    at _loadUserApp (/var/runtime/UserFunction.js:95:12)",
        "    at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
        "    at Object.<anonymous> (/var/runtime/index.js:43:30)",
        "    at Module._compile (internal/modules/cjs/loader.js:1063:30)"
    ]
}
Run Code Online (Sandbox Code Playgroud)

看起来/var/runtime/UserFunction.js正在调用我的应用程序处理程序作为一个要求和一个模块。但是,我无法控制/var/runtime/UserFunction.js(我不相信?)。在我的Dockerfile我已经指定了Node14. 我完全不知道我哪里出错了?

我想要做的是在没有 Babel/Transpiler 的情况下运行最新和最好的 Node14(例如导入),而不会“膨胀”我的代码。如果有人能指出我出错的正确方向,我将不胜感激。

use*_*997 40

如果有人看到这一点,就会遇到同样的问题。请参阅以下来自 AWS 官方技术支持的内容:

“您使用 package.json 的说明{ "type": "module" }是正确的,但目前 Lambda Node.js 14 运行时不支持 ECMAScript 模块”。

当我听到有关何时可以获得支持的更多信息时,我将发布此帖子的更新。我把这个问题留在这里,以防其他人遇到同样的问题。

  • @MayNoppadol 根据 https://twitter.com/coderbyheart/status/1486470882008645634 使用 ESM 时当前不支持层中的模块 (3认同)
  • 您可以通过将所有处理程序入口点放入其自己的带有“空”package.json 的文件夹中来解决此问题。如果您希望 ES 模块与处理程序位于同一文件夹中,则可以使用 .mjs 扩展名。有关工作示例,请参阅 https://github.com/makenew/serverless-nodejs/blob/fa148a9dd210c21736c84014c32f6da151176aba/handlers/todo.js (2认同)
  • Lambda Node.js 14 现在支持 ECMAScript 模块!https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/ (2认同)

小智 16

从昨天开始,Node 14 lambda 中终于有了对 ES6 模块语法的本机支持 - 请参阅https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level -await-in-aws-lambda