【问题标题】:NestJS and Serverless - handler 'handler' is not a functionNestJS 和无服务器 - 处理程序“处理程序”不是函数
【发布时间】:2021-11-24 20:20:33
【问题描述】:

我正在尝试使用无服务器框架将 NestJS 实现为 AWS 无服务器功能。

我在关注this official documentation,我的代码与文档中的完全一样。但是,当我启动它时,我收到错误 Failure: offline: handler 'handler' in [..] is not a function

如果我进入我编译的main.js 源代码并将exports.handler = handler; 行更改为module.exports.handler = handler;,它就会开始工作。

我也尝试更改 main.ts 中的代码以适应这一点,但这并没有帮助,因为 webpack 以不同的方式编译它。

// main.ts
const handler ...;
module.exports.handler = handler;

这是我的main.ts

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { Callback, Context, Handler } from 'aws-lambda';
import serverlessExpress from '@vendia/serverless-express';
import { AppModule } from './app.module';

let server: Handler;

async function bootstrap(): Promise<Handler> {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
    }),
  );
  await app.init();

  const expressApp = app.getHttpAdapter().getInstance();
  return serverlessExpress({ app: expressApp });
}

export const handler: Handler = async (event: any, context: Context, callback: Callback) => {
  server = server ?? (await bootstrap());
  return server(event, context, callback);
};

这是我的serverless.yml

service:
  name: serverless-example

plugins:
  - serverless-offline

provider:
  name: aws
  runtime: nodejs12.x

functions:
  main:
    handler: dist/main.handler
    events:
      - http:
          method: ANY
          path: /
      - http:
          method: ANY
          path: '{proxy+}'

这是我的 webpack.config.js

return {
  ...options,
  externals: [],
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};

最后是我的 tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false,
    "esModuleInterop": true
  }
}

我是否缺少 webpack 上的一些配置?或者也许改变打字稿配置文件?我不知道,文档说它应该可以工作,但它没有。

理论上,我只需要在我的编译文件中使用module.exports.handler = handler 而不是exports.handler = handler,因为正如我所说,我确实更改了它并且它开始正常工作。

这是我正在使用的临时修复,但显然这是错误的解决方法。

"build": "nest build --webpack && sed -i 's/exports.handler = handler;/module.exports.handler = handler;/g' dist/main.js",

【问题讨论】:

  • 既然exports === module.exports 两者都可以正常工作,对吧?
  • 但事实并非如此。 :\
  • 我对一个全新项目进行了快速测试,但没有遇到此问题。您运行的是哪个版本的 Nest? AFAIK,这是一个相当新的功能,可能需要 Nest8
  • 我遇到了同样的错误。你设法找到解决办法吗? @斯坦
  • 任何人都得到了修复..使用nest8

标签: typescript nestjs serverless-framework serverless


【解决方案1】:

我通过创建确保 webpack 输出具有 libraryTargetcommonjs2 来解决此问题。在项目的根目录中创建(或编辑)一个webpack.config.js 文件,其中包含以下内容,确保我们将libraryTarget 设置为commonjs2

module.exports = (options) => {
  return {
    ...options,
    output: {
      ...options.output,
      libraryTarget: 'commonjs2',
    },
  };
};

在我的serverless.yml 中,我为我的 lambda 函数定义了以下内容:

...

functions:
  example:
    handler: "./dist/apps/example/main.js.handler"
...

请注意,如果您的入口点/功能不同,则应更改 main.js.handler。例如,如果它是entrypoint,这个字符串就是dist/apps/example/main.js.entrypoint

【讨论】:

    猜你喜欢
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    相关资源
    最近更新 更多