sam sync throws "Build method missing" error on static nodejs modules

0

I am using nodejs and "sam sync". I have a layer with shared js code that doesn't need to be built. I am using ES Modules for imports.

While I have this working, any changes to my shared code module results in a "Build method missing in layer" error making quick iteration difficult.

SAM CLI, version 1.70.0

Directory structure:

layers-test/{template.yaml, samconfig.toml}
layers-test/hello-world/{app.js, package.json}
layers-test/shared-code/tools/{tools.js, package.json}
layers-test/shared-code/util/{util.js, package.json}
layers-test/shared-modules/{package.json, package-lock.json, node_modules/}

hello-world/app.js:

import pick from "lodash.pick";
import { utilFunction } from "/opt/util/util.js";
import { toolsFunction } from "/opt/tools/tools.js";

export const lambdaHandler = async (event, context) => {
    try {
        utilFunction();
        toolsFunction();
        console.log('rez:', pick({ a: 40, b: 30, c: 20 }, ['a', 'b']));
        return {
            'statusCode': 200,
            'body': JSON.stringify({
                message: 'hello world',
            })
        }
    } catch (err) {
        console.log(err);
        return err;
    }
};

shared-modules/package.json:

{
  "name": "shared-modules",
  "version": "1.0.0",
  "description": "",
  "dependencies": {
    "lodash.pick": "^4.4.0"
  }
}

shared-code/util/util.js:

export const utilFunction = () => {
  console.log('running utilFunction');
};

shared-code/util/package.json:

{
  "name": "util",
  "version": "1.0.0",
  "description": "",
  "main": "util.js",
  "type": "module"
}

template.yaml:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  layers-test

  Sample SAM Template for layers-test

Globals:
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs18.x
      Architectures:
        - x86_64
      Layers:
        - !Ref SharedModulesLayer
        - !Ref SharedCodeLayer
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

  SharedModulesLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: layers/shared-modules
      CompatibleRuntimes:
        - nodejs18.x
    Metadata:
      BuildMethod: nodejs18.x
      BuildArchitecture: x86_64
  SharedCodeLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: layers/shared-code
      CompatibleRuntimes:
        - nodejs18.x

All of this code works, but with sam sync active, whenever I make changes to anything in shared-code/ I get the error:

Syncing Layer SharedCodeLayer...
Layer <samcli.lib.providers.sam_function_provider.SamFunctionProvider object at 0x7f19797b81d0> is missing BuildMethod Metadata.
Code sync encountered an error.
Traceback (most recent call last):
  File "samcli/lib/sync/sync_flow_executor.py", line 342, in _sync_flow_execute_wrapper
  File "samcli/lib/sync/sync_flow.py", line 310, in execute
  File "samcli/lib/sync/flows/layer_sync_flow.py", line 224, in gather_resources
  File "samcli/commands/build/build_context.py", line 523, in collect_build_resources
  File "samcli/commands/build/build_context.py", line 611, in _collect_single_buildable_layer
samcli.commands.build.exceptions.MissingBuildMethodException: Build method missing in layer SharedCodeLayer.

If I add:

    Metadata:
      BuildMethod: nodejs18.x
      BuildArchitecture: x86_64

to SharedCodeLayer then the imports no longer work. I get an error like:

Uncaught Exception      {"errorType":"Error","errorMessage":"Cannot find module '/opt/util/util.js' imported from /var/task/app.js","code":"ERR_MODULE_NOT_FOUND","stack":["Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/opt/util/util.js' imported from /var/task/app.js","    at new NodeError (node:internal/errors:393:5)","    at finalizeResolution (node:internal/modules/esm/resolve:328:11)","    at moduleResolve (node:internal/modules/esm/resolve:965:10)","    at moduleResolveWithNodePath (node:internal/modules/esm/resolve:909:12)","    at defaultResolve (node:internal/modules/esm/resolve:1173:79)","    at nextResolve (node:internal/modules/esm/loader:163:28)","    at ESMLoader.resolve (node:internal/modules/esm/loader:841:30)","    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)","    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)","    at link (node:internal/modules/esm/module_job:75:36)"]}

Is there any way to make these imports work while avoiding the "Build method missing in layer" in error?

No Answers

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions