Node.js:将源文件放入其他文件夹时出现“无法找到模块”错误

问题描述

我正在使用 AWS Lambda、API 网关、RDS (MysqL) 开发 REST API。我为此使用了 Node.js。

下面是我的 lambda 函数

const MysqL = require('MysqL');
const PropertiesReader = require('properties-reader');

const prop = PropertiesReader('properties.properties');

const con = MysqL.createConnection({
  host     : prop.get('server.host'),user     : prop.get("server.username"),password : prop.get("server.password"),port     : prop.get("server.port"),database : prop.get("server.dbname")
});

exports.getAllRoles = (event,context,callback) => {
  // allows for using callbacks as finish/error-handlers
  context.callbackWaitsForEmptyEventLoop = false;
  const sql = "select * from role";
  con.query(sql,function (err,result) {
    if (err) throw err;

    var response = {
        "statusCode": 200,"headers": {
            "Content-Type": "application/json"
        },"body": JSON.stringify(result),"isBase64Encoded": false
    };
    callback(null,response)
  });
};

下面是CloudFormation文件

AWstemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  aaaaa-restapi

  Sample SAM Template for aaaa-restapi
  
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 100
    VpcConfig:
        SecurityGroupIds:
          - sg-********
        subnetIds:
          - subnet-*******

Resources:
  
  GetAllRolesFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: aaaaa-restapi/
      Handler: role-getall.getAllRoles
      Runtime: nodejs14.x
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /role/getall
            Method: get

  LambdaRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - ec2:DescribeNetworkInterfaces
                  - ec2:CreateNetworkInterface
                  - ec2:DeleteNetworkInterface
                  - ec2:DescribeInstances
                  - ec2:AttachNetworkInterface
                Resource: '*'

当我的 lambda 函数位于根文件夹中时,我在运行它们时没有问题。但是当我将它们移动到单独的文件夹中时,出现错误

以下是我的文件夹结构。

enter image description here

***-restapi 中的所有文件都可以正常工作。但是,当我尝试在 role-getall.js 文件夹中执行 role 时,出现以下错误

START RequestId: a5f41864-6653-4ce2-9af6-1571f1004eba Version: $LATEST
2021-07-22T16:52:45.866Z        undefined       ERROR   Uncaught Exception      {"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'role-getall'\nRequire stack:\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js","stack":["Runtime.ImportModuleError: Error: Cannot find module 'role-getall'","Require stack:","- /var/runtime/UserFunction.js","- /var/runtime/index.js","    at _loadUserApp (/var/runtime/UserFunction.js:100: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:1085:14)","    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)","    at Module.load (internal/modules/cjs/loader.js:950:32)","    at Function.Module._load (internal/modules/cjs/loader.js:790:14)","    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)","    at internal/main/run_main_module.js:17:47"]}
time="2021-07-22T16:52:45.894" level=panic msg="ReplyStream not available"
2021/07/22 16:52:45 http: panic serving 127.0.0.1:41868: &{0xc0000e4000 map[] 2021-07-22 16:52:45.8944429 +0000 UTC m=+0.294772201 panic <nil> ReplyStream not available <nil> <nil> }
goroutine 23 [running]:
net/http.(*conn).serve.func1(0xc0000b2aa0)
        /usr/local/go/src/net/http/server.go:1800 +0x139
panic(0x866640,0xc0000e4150)
        /usr/local/go/src/runtime/panic.go:975 +0x3e3
github.com/sirupsen/logrus.Entry.log(0xc0000e4000,0xc000087410,0x0,...)
        /go/pkg/mod/github.com/sirupsen/logrus@v1.6.0/entry.go:259 +0x335
github.com/sirupsen/logrus.(*Entry).Log(0xc0000e40e0,0xc000000000,0xc000133588,0x1,0x1)
        /go/pkg/mod/github.com/sirupsen/logrus@v1.6.0/entry.go:287 +0xeb
github.com/sirupsen/logrus.(*Logger).Log(0xc0000e4000,0x1)
        /go/pkg/mod/github.com/sirupsen/logrus@v1.6.0/logger.go:193 +0x7d
github.com/sirupsen/logrus.(*Logger).Panic(...)
        /go/pkg/mod/github.com/sirupsen/logrus@v1.6.0/logger.go:234
github.com/sirupsen/logrus.Panic(...)
        /go/pkg/mod/github.com/sirupsen/logrus@v1.6.0/exported.go:129
go.amzn.com/lambda/rapi/rendering.RenderInteropError(0x9097c0,0xc0001000e0,0xc0000e6400,0x902b60,0xc000085020)
        /LambdaRuntimeLocal/lambda/rapi/rendering/rendering.go:292 +0x9a
go.amzn.com/lambda/rapi/handler.(*initErrorHandler).ServeHTTP(0xc00002c0c0,0x9097c0,0xc0000e6400)
        /LambdaRuntimeLocal/lambda/rapi/handler/initerror.go:52 +0x519
net/http.HandlerFunc.ServeHTTP(0xc00000c3c0,0xc0000e6400)
        /usr/local/go/src/net/http/server.go:2041 +0x44
github.com/go-chi/chi.(*Mux).routeHTTP(0xc00005a180,0xc0000e6400)
        /go/pkg/mod/github.com/go-chi/chi@v4.1.2+incompatible/mux.go:431 +0x278
net/http.HandlerFunc.ServeHTTP(0xc00002c050,0xc0000e6400)
        /usr/local/go/src/net/http/server.go:2041 +0x44
go.amzn.com/lambda/rapi/middleware.RuntimeReleaseMiddleware.func1.1(0x9097c0,0xc0000e6400)
        /LambdaRuntimeLocal/lambda/rapi/middleware/middleware.go:100 +0xea
net/http.HandlerFunc.ServeHTTP(0xc00000c1c0,0xc0000e6400)
        /usr/local/go/src/net/http/server.go:2041 +0x44
go.amzn.com/lambda/rapi/middleware.AccessLogMiddleware.func1.1(0x9097c0,0xc0000e6400)
        /LambdaRuntimeLocal/lambda/rapi/middleware/middleware.go:77 +0x170
net/http.HandlerFunc.ServeHTTP(0xc00000c1e0,0xc0000e6400)
        /usr/local/go/src/net/http/server.go:2041 +0x44
go.amzn.com/lambda/rapi/middleware.AppCtxMiddleware.func1.1(0x9097c0,0xc0000e6300)
        /LambdaRuntimeLocal/lambda/rapi/middleware/middleware.go:66 +0x77
net/http.HandlerFunc.ServeHTTP(0xc00001e300,0xc0000e6300)
        /usr/local/go/src/net/http/server.go:2041 +0x44
github.com/go-chi/chi.(*Mux).ServeHTTP(0xc00005a180,0xc0000e6300)
        /go/pkg/mod/github.com/go-chi/chi@v4.1.2+incompatible/mux.go:70 +0x513
github.com/go-chi/chi.(*Mux).Mount.func1(0x9097c0,0xc0000e6300)
        /go/pkg/mod/github.com/go-chi/chi@v4.1.2+incompatible/mux.go:298 +0x118
net/http.HandlerFunc.ServeHTTP(0xc00000c420,0xc0000e6300)
        /usr/local/go/src/net/http/server.go:2041 +0x44
github.com/go-chi/chi.(*Mux).routeHTTP(0xc00005a120,0xc0000e6300)
        /go/pkg/mod/github.com/go-chi/chi@v4.1.2+incompatible/mux.go:431 +0x278
net/http.HandlerFunc.ServeHTTP(0xc00002c0e0,0xc0000e6300)
        /usr/local/go/src/net/http/server.go:2041 +0x44
github.com/go-chi/chi.(*Mux).ServeHTTP(0xc00005a120,0xc0000e6100)
        /go/pkg/mod/github.com/go-chi/chi@v4.1.2+incompatible/mux.go:86 +0x2b2
net/http.serverHandler.ServeHTTP(0xc00006e000,0xc0000e6100)
        /usr/local/go/src/net/http/server.go:2836 +0xa3
net/http.(*conn).serve(0xc0000b2aa0,0x90a800,0xc0000b04c0)
        /usr/local/go/src/net/http/server.go:1924 +0x86c
created by net/http.(*Server).Serve
        /usr/local/go/src/net/http/server.go:2962 +0x35c
2021-07-22T16:52:45.901Z        undefined       ERROR   Uncaught Exception      {"errorType":"Error","errorMessage":"socket hang up","code":"ECONNRESET","stack":["Error: socket hang up","    at connResetException (internal/errors.js:628:14)","    at Socket.socketonEnd (_http_client.js:499:23)","    at Socket.emit (events.js:387:35)","    at endReadableNT (internal/streams/readable.js:1317:12)","    at processticksAndRejections (internal/process/task_queues.js:82:21)"]}
time="2021-07-22T16:52:45.923" level=error msg="Init Failed" InvokeID= error="Runtime exited with error: exit status 129"
time="2021-07-22T16:52:45.924" level=error msg="INIT DONE Failed: Runtime.ExitError"

如果我将此文件移回根文件夹,则完全没有问题。

由于我将拥有数百个功能,因此将它们组织到文件夹中很重要。但是我怎样才能做到这一点而不会出错?

解决方法

只需在您的处理程序中添加文件夹名称的前缀,例如 [文件夹]/[文件名].[function_name]

以你的例子:

Handler: role/role-getall.getAllRoles