Как получить относительный пакет. json зависимостей для работы с AWS командой sam build на Windows? - PullRequest
0 голосов
/ 04 марта 2020

Моя цель - поделиться библиотечным кодом между несколькими нашими лямбда-функциями, используя слои и , чтобы иметь возможность локально отлаживать и запускать тесты.

npm может устанавливать зависимости от локальная файловая система. Когда мы меняем код нашей библиотеки, мы хотим, чтобы все пользователи этой библиотеки получали обновленный код, не настраивая выделенный сервер npm. Я могу отладить локально просто отлично, используя относительные пути, но это до того, как я задействую sam build. sam build создает скрытую папку в root хранилища, создает папку и в конечном итоге запускает npm install, однако на этот раз структура папок другая. Относительные пути, используемые в файле package.json, теперь повреждены. Мы не можем использовать явные пути, потому что наши репозитории находятся в наших пользовательских папках, которые, конечно, отличаются от одного разработчика к другому.

Вот что я сделал:

Я создал проект, используя sam init и принял значения по умолчанию (кроме имени sam-app-2) для проекта nodejs 12.x (параметры 1 и 1).

Эта команда создала папку с именем sam-app-2, которая является ссылка на все следующие имена файлов.

Я создал папку dependencies/nodejs.

Я добавил dep.js в эту папку:

exports.x = 'It works!!';

Я также добавил package.json в той же папке:

{
  "name": "dep",
  "version": "1.0.0",
  "description": "",
  "main": "dep.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

В hello-world (папка с функцией лямбда) я добавил следующее в зависимости package.json:

"dep": "file:../dependencies/nodejs"

Я запустил npm install в hello-world, и он скопировал зависимости в node_modules/dep. Обычно вы бы не делали этого здесь. Это просто для того, чтобы я мог работать локально без участия CLI sam. Это просто чистый код nodejs. Я могу запускать тесты, я могу отлаживать, и мне не нужно ждать двадцать секунд или больше, пока sam упаковывает все и вызывает мою функцию. Развиваться в этом состоянии - это круто, потому что это очень быстро. Тем не менее, в конечном итоге он должен работать правильно в дикой природе.

Я редактировал ./hello-world/app.js:

const dep = require('dep');
let response;

exports.lambdaHandler = async (event, context) => {
    try {
        // const ret = await axios(url);
        response = {
            'statusCode': 200,
            'dep.x': dep.x,
            'body': JSON.stringify({
                message: 'Hello, World!!',
                // location: ret.data.trim()
            })
        }
    } catch (err) {
        console.log(err);
        return err;
    }

    return response
};

if(require.main === module){
    (async () => {
        var result = await exports.lambdaHandler(process.argv[1]);
        console.log(result);
    })();
}

Я редактировал template.yml:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app-2

  Sample SAM Template for sam-app-2

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:
    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: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs12.x
      Layers:
        - !Ref DepLayer
      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: /hello
            Method: get

  DepLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
        LayerName: sam-app-dependencies-2
        Description: Dependencies for sam app [temp-units-conv]
        ContentUri: ./dependencies/
        CompatibleRuntimes:
          - nodejs12.x
        LicenseInfo: 'MIT'
        RetentionPolicy: Retain
Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

Запуск его прямо из командной строки работает:

sam-app-2> node hello-world\app.js
{
  statusCode: 200,
  'dep.x': 'It works!!',
  body: '{"message":"Hello, World!!"}'
}

Даже sam deploy работает! Да, он развертывает код в облаке, и когда я вызываю лямбда-функцию в облаке, он дает тот же результат, что и выше.

Однако, когда я запускаю sam build, он завершается неудачно с:

Building resource 'HelloWorldFunction'
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall

Build Failed
Error: NodejsNpmBuilder:NpmInstall - NPM Failed: npm ERR! code ENOLOCAL
npm ERR! Could not install from "..\dependencies\nodejs" as it does not contain a package.json file.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Brandon\AppData\Roaming\npm-cache\_logs\2020-03-04T19_34_01_873Z-debug.log

Когда я пытаюсь вызвать лямбду локально:

sam local invoke "HelloWorldFunction" -e events/event.json
Invoking app.lambdaHandler (nodejs12.x)
DepLayer is a local Layer in the template
Building image...
Requested to skip pulling images ...

Mounting C:\Users\Brandon\source\repos\sam-app-2\hello-world as /var/task:ro,delegated inside runtime container
2020-03-03T19:34:28.824Z        undefined       ERROR   Uncaught Exception      {"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'dep'\nRequire stack:\n- /var/task/app.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js","stack":["Runtime.ImportModuleError: Error: Cannot find module 'dep'","Require stack:","- /var/task/app.js","- /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:955:30)","    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)","    at Module.load (internal/modules/cjs/loader.js:811:32)","    at Function.Module._load (internal/modules/cjs/loader.js:723:14)","    at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)","    at internal/main/run_main_module.js:17:11"]}
?[32mSTART RequestId: b6f39717-746d-1597-9838-3b6472ec8843 Version: $LATEST?[0m
?[32mEND RequestId: b6f39717-746d-1597-9838-3b6472ec8843?[0m
?[32mREPORT RequestId: b6f39717-746d-1597-9838-3b6472ec8843     Init Duration: 237.77 ms        Duration: 3.67 ms       Billed Duration: 100 ms Memory Size: 128 MB     Max Memory Used: 38 MB  ?[0m

{"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'dep'\nRequire stack:\n- /var/task/app.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js"}

Когда я пытаюсь запустить API локально с sam local start-api, происходит сбой с той же ошибкой, что и выше.

Я думаю, что если бы не относительные пути к файлам были отключены во время фазы сборки, я мог бы иметь свой торт (отладка локально очень быстро) и съесть его тоже (запустить sam build, sam local start-api).

Что мне делать?

1 Ответ

0 голосов
/ 07 марта 2020

После большого разочарования и беспокойства, это было произведено: https://github.com/blmille1/aws-sam-layers-template

Наслаждайтесь!

...