You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SAM部署Lambda时,如何导入Layer中的node_modules并解决Esbuild报错?

问题

我想用SAM本地测试并部署Lambda函数及Layer,目标是在函数代码里导入Layer目录下的node_modules模块,而非函数自身目录内的node_modules。但执行命令cd functions-stack && sam build --beta-feature时,出现了Esbuild Failed: Could not resolve <module name>的错误。

当前目录结构:

functions-stack/
  template.yml
  my-function/
    .aws-sam/
      build/ <- 空目录
    app.ts
    node_modules/
layers-stack/
  template.yml
  nodejs/
    node_modules/
    package.json

函数模板配置(functions-stack/my-function/template.yml):

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: my-function
      CodeUri: ./my-function/
      Handler: app.lambdaHandler
      Runtime: nodejs14.x
      Architectures:
        - x86_64
      Layers:
        - arn:aws:lambda:ap-northeast-1:123456789:layer:NodejsLayer:1
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        Minify: true
        Target: "es2020"
        Sourcemap: true
        EntryPoints: 
        - app.ts

函数代码(functions-stack/my-function/app.ts):

import { APIGatewayProxyEvent } from 'aws-lambda'
// 这个模块安装在layers-stack/node_modules里
// 报错:Esbuild Failed: ✘ [ERROR] Could not resolve "axios"
import axios from 'axios'

export const lambdaHandler = async (event: APIGatewayProxyEvent) => { return }
解决方案

核心原因

SAM构建时,esbuild只会默认查找函数目录下的node_modules,不会自动识别远程Layer或本地Layer的依赖路径,必须手动配置让esbuild定位到Layer里的模块。

1. 本地构建时关联Layer的本地路径

方法一:修改模板引用本地Layer(适合长期本地开发)

在functions-stack/template.yml中新增本地Layer的资源定义,让函数直接引用这个本地Layer:

Resources:
  # 新增本地Layer资源
  NodejsLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: NodejsLayer
      ContentUri: ../layers-stack/nodejs/ # 指向本地Layer的nodejs目录
      CompatibleRuntimes:
        - nodejs14.x
  # 原函数配置
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      # 其他配置不变
      Layers:
        - !Ref NodejsLayer # 替换原来的远程ARN,引用本地Layer
    # 原Metadata配置不变

方法二:构建时临时指定Layer路径(适合临时测试)

无需修改模板,直接在构建命令中加入--layer-source参数关联本地Layer:

cd functions-stack && sam build --beta-feature --layer-source NodejsLayer=../layers-stack/nodejs/

2. 配置Esbuild忽略Layer依赖并指定解析路径

在函数的Metadata.BuildProperties中添加两项配置:

  • External:告诉esbuild不要打包Layer中的模块(运行时由Layer提供)
  • Paths:指定Layer中node_modules的路径,让esbuild能找到对应模块

修改后的模板配置:

Metadata:
  BuildMethod: esbuild
  BuildProperties:
    Minify: true
    Target: "es2020"
    Sourcemap: true
    EntryPoints: 
    - app.ts
    External:
      - axios # 列出所有Layer中的依赖,多个模块直接添加到数组即可
    Paths:
      "*": ../layers-stack/nodejs/node_modules/ # 批量指定所有模块的解析路径

如果只有个别模块,也可以单独指定:

Paths:
  axios: ../layers-stack/nodejs/node_modules/axios

3. 本地测试的注意事项

使用sam local invoke或sam local start-api测试时,若已通过上述方法关联本地Layer,SAM会自动挂载Layer;若仍使用远程ARN,也可在测试命令中临时指定本地Layer路径:

sam local invoke MyFunction --layer-source NodejsLayer=../layers-stack/nodejs/

4. 部署到AWS时的恢复

部署到AWS环境时,记得将函数的Layers引用改回远程ARN,或通过CloudFormation跨栈引用已部署的Layer资源。


内容的提问来源于stack exchange,提问作者kusumoto_teruya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 07:36:20