aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.51k stars 1.17k forks source link

sam build doesn't pack Node.js source code correctly #1100

Closed paoptu023 closed 5 years ago

paoptu023 commented 5 years ago

Description

My project structure is laid out like this:

├── /app/
    ├── lambda.js               # Lambda handler code
    └── server.js
├── package.json
└── template.yaml

In the original template, I set the CodeUri to app/and Handler to lambda.handler.

When I ran sam build -m package.json at the root directory, the generated .aws-sam/build folder is like this:

├── /HelloWorldFunction/
    ├── /app/
    ├── /node_modules/
    └── package.json
└── template.yaml

The built template set CodeUri to HelloWorldFunction, but Handler is still lambda.handler. Then when I ran sam local start-api and visited http://127.0.0.1:3000/, it gave me the following error:

Unable to import module 'lambda': Error
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)

Steps to reproduce

See above.

Observed result

Please provide command output with --debug flag set.

➜  start-right-nodejs-boilerplate git:(tmp) ✗ sam build -m package.json --debug
2019-04-04 13:42:03 Using SAM Template at /Users/qwang/Documents/Workspace/start-right-nodejs-boilerplate/template.yaml
2019-04-04 13:42:03 Changing event name from creating-client-class.iot-data to creating-client-class.iot-data-plane
2019-04-04 13:42:03 Changing event name from before-call.apigateway to before-call.api-gateway
2019-04-04 13:42:03 Changing event name from request-created.machinelearning.Predict to request-created.machine-learning.Predict
2019-04-04 13:42:03 Changing event name from before-parameter-build.autoscaling.CreateLaunchConfiguration to before-parameter-build.auto-scaling.CreateLaunchConfiguration
2019-04-04 13:42:03 Changing event name from before-parameter-build.route53 to before-parameter-build.route-53
2019-04-04 13:42:03 Changing event name from request-created.cloudsearchdomain.Search to request-created.cloudsearch-domain.Search
2019-04-04 13:42:03 Changing event name from docs.*.autoscaling.CreateLaunchConfiguration.complete-section to docs.*.auto-scaling.CreateLaunchConfiguration.complete-section
2019-04-04 13:42:03 Changing event name from before-parameter-build.logs.CreateExportTask to before-parameter-build.cloudwatch-logs.CreateExportTask
2019-04-04 13:42:03 Changing event name from docs.*.logs.CreateExportTask.complete-section to docs.*.cloudwatch-logs.CreateExportTask.complete-section
2019-04-04 13:42:03 Changing event name from before-parameter-build.cloudsearchdomain.Search to before-parameter-build.cloudsearch-domain.Search
2019-04-04 13:42:03 Changing event name from docs.*.cloudsearchdomain.Search.complete-section to docs.*.cloudsearch-domain.Search.complete-section
2019-04-04 13:42:03 Changing event name from creating-client-class.iot-data to creating-client-class.iot-data-plane
2019-04-04 13:42:03 Changing event name from before-call.apigateway to before-call.api-gateway
2019-04-04 13:42:03 Changing event name from request-created.machinelearning.Predict to request-created.machine-learning.Predict
2019-04-04 13:42:03 Changing event name from before-parameter-build.autoscaling.CreateLaunchConfiguration to before-parameter-build.auto-scaling.CreateLaunchConfiguration
2019-04-04 13:42:03 Changing event name from before-parameter-build.route53 to before-parameter-build.route-53
2019-04-04 13:42:03 Changing event name from request-created.cloudsearchdomain.Search to request-created.cloudsearch-domain.Search
2019-04-04 13:42:03 Changing event name from docs.*.autoscaling.CreateLaunchConfiguration.complete-section to docs.*.auto-scaling.CreateLaunchConfiguration.complete-section
2019-04-04 13:42:03 Changing event name from before-parameter-build.logs.CreateExportTask to before-parameter-build.cloudwatch-logs.CreateExportTask
2019-04-04 13:42:03 Changing event name from docs.*.logs.CreateExportTask.complete-section to docs.*.cloudwatch-logs.CreateExportTask.complete-section
2019-04-04 13:42:03 Changing event name from before-parameter-build.cloudsearchdomain.Search to before-parameter-build.cloudsearch-domain.Search
2019-04-04 13:42:03 Changing event name from docs.*.cloudsearchdomain.Search.complete-section to docs.*.cloudsearch-domain.Search.complete-section
2019-04-04 13:42:03 'build' command is called
2019-04-04 13:42:04 No Parameters detected in the template
2019-04-04 13:42:04 2 resources found in the template
2019-04-04 13:42:04 Found Serverless function with name='HelloWorldFunction' and CodeUri='app/'
2019-04-04 13:42:04 Building resource 'HelloWorldFunction'
2019-04-04 13:42:04 Loading workflow module 'aws_lambda_builders.workflows'
2019-04-04 13:42:04 Registering workflow 'PythonPipBuilder' with capability 'Capability(language='python', dependency_manager='pip', application_framework=None)'
2019-04-04 13:42:04 Registering workflow 'NodejsNpmBuilder' with capability 'Capability(language='nodejs', dependency_manager='npm', application_framework=None)'
2019-04-04 13:42:04 Registering workflow 'RubyBundlerBuilder' with capability 'Capability(language='ruby', dependency_manager='bundler', application_framework=None)'
2019-04-04 13:42:04 Registering workflow 'GoDepBuilder' with capability 'Capability(language='go', dependency_manager='dep', application_framework=None)'
2019-04-04 13:42:04 Registering workflow 'GoModulesBuilder' with capability 'Capability(language='go', dependency_manager='modules', application_framework=None)'
2019-04-04 13:42:04 Registering workflow 'JavaGradleWorkflow' with capability 'Capability(language='java', dependency_manager='gradle', application_framework=None)'
2019-04-04 13:42:04 Registering workflow 'JavaMavenWorkflow' with capability 'Capability(language='java', dependency_manager='maven', application_framework=None)'
2019-04-04 13:42:04 Registering workflow 'DotnetCliPackageBuilder' with capability 'Capability(language='dotnet', dependency_manager='cli-package', application_framework=None)'
2019-04-04 13:42:04 Found workflow 'NodejsNpmBuilder' to support capabilities 'Capability(language='nodejs', dependency_manager='npm', application_framework=None)'
2019-04-04 13:42:04 Running workflow 'NodejsNpmBuilder'
2019-04-04 13:42:04 Running NodejsNpmBuilder:NpmPack
2019-04-04 13:42:04 NODEJS packaging file:/Users/qwang/Documents/Workspace/start-right-nodejs-boilerplate to /var/folders/7j/c0_p4kf90t33z2lc82wwm8vhy5h1_r/T/tmpnu1cc1h4
2019-04-04 13:42:04 executing NPM: ['npm', 'pack', '-q', 'file:/Users/qwang/Documents/Workspace/start-right-nodejs-boilerplate']
2019-04-04 13:42:05 NODEJS packed to start-right-nodejs-boilerplate-1.0.0.tgz
2019-04-04 13:42:05 NODEJS extracting to /var/folders/7j/c0_p4kf90t33z2lc82wwm8vhy5h1_r/T/tmpnu1cc1h4/unpacked
2019-04-04 13:42:05 NodejsNpmBuilder:NpmPack succeeded
2019-04-04 13:42:05 Running NodejsNpmBuilder:CopyNpmrc
2019-04-04 13:42:05 NodejsNpmBuilder:CopyNpmrc succeeded
2019-04-04 13:42:05 Running NodejsNpmBuilder:CopySource
2019-04-04 13:42:05 NodejsNpmBuilder:CopySource succeeded
2019-04-04 13:42:05 Running NodejsNpmBuilder:NpmInstall
2019-04-04 13:42:05 NODEJS installing in: /Users/qwang/Documents/Workspace/start-right-nodejs-boilerplate/.aws-sam/build/HelloWorldFunction
2019-04-04 13:42:05 executing NPM: ['npm', 'install', '-q', '--no-audit', '--no-save', '--production']
2019-04-04 13:42:14 NodejsNpmBuilder:NpmInstall succeeded
2019-04-04 13:42:14 Running NodejsNpmBuilder:CleanUpNpmrc
2019-04-04 13:42:14 NodejsNpmBuilder:CleanUpNpmrc succeeded

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Expected result

I'm not sure whether the current behavior is expected or not. It seems that sam build just copies the whole directory where package.json exists regardless of what CodeUri I specify in the template. I think sam build should pack package.json with the CodeUri directory and output the built template accordingly.

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS: macOS Sierra
  2. sam --version: SAM CLI, version 0.14.2
steventen commented 5 years ago

I see the same issue when using 0.15.0

jfuss commented 5 years ago

@paoptu023 and @steventen This is currently by design. NPM will place node_modules in the same folder as package.json. Since you placed the package.json not in the function folder, you will not get the node_modules with your function directly. Based on feedback from the community (when we first built build), the recommendation was to place the manifest files (requirements.txt, package.json, pom.xml, etc) into the function folders. If you follow this practice (how all the init projects are setup), things will work as you expect.

With that said, the way forward is to move the package.json file into the function directories (the CodeUri location).

Closing as this is working as expected.