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

AWS Lambda Node.js 18.x ESM模块导入报错及解决方案咨询

AWS Lambda Node.js 18.x ESM项目中ERR_MODULE_NOT_FOUND错误的原因与解决方法

问题描述

在Node.js 18.x的AWS Lambda ESM项目中,遇到如下错误:

{ 
  "errorType": "Error",
  "errorMessage": "Cannot find module '/var/task/src/storefront/api/checkout/preview' imported from /var/task/src/storefront/api/checkout/index.js",
  "code": "ERR_MODULE_NOT_FOUND",
  // 省略其他堆栈信息
}

错误指向编译后的index.js中的导出代码:

export { preview } from './preview';

手动给路径加上.js后缀后,错误消失:

export { preview } from './preview.js';

项目使用TypeScript自动编译为ESM JavaScript,TS中省略后缀的导入是标准写法,需要明确Lambda出现此问题的原因及解决办法。

项目配置信息:

package.json

{
  "name": "checkout",
  "type": "module",
  "main": "index.js",
  "version": "0.1.0",
  "engines": {
    "node": ">=18.0.0"
  },
  // 省略其他配置
}

tsconfig.json

{
  "compilerOptions": {
    "preserveConstEnums": true,
    "strictNullChecks": true,
    "sourceMap": true,
    "target": "es2022",
    "outDir": ".build",
    "moduleResolution": "node",
    "lib": [
      "es2022"
    ],
    "skipLibCheck": true,
    "rootDir": "./",
    "typeRoots": [
      "./node_modules/@types",
      "./@types"
    ]
  },
  "include": [
    "./src/**/*"
  ],
  "exclude": [   
    "node_modules"
  ]
}

部署方式

使用serverless.yml(runtime: nodejs18.x)和serverless-typescript插件部署。

问题原因

  1. Node.js ESM的严格路径要求:Node.js的ESM模块规范与CommonJS不同,相对导入必须指定完整的文件后缀(如.js),CommonJS允许省略后缀自动查找的逻辑在ESM中不生效。
  2. TypeScript编译的默认行为:当前tsconfig.json中moduleResolution设为node,这是适配CommonJS的解析逻辑,编译时不会给相对导入路径自动添加.js后缀,导致生成的ESM代码不符合Node.js的要求。
  3. serverless-typescript插件的编译流程:插件默认未处理ESM后缀补全的问题,直接使用TS编译后的代码部署到Lambda,引发模块查找失败。

解决方法

方案1:修改TypeScript配置适配ESM规范

调整tsconfig.json的编译选项,让TS按照Node.js ESM的规则处理导入,编译时自动补全.js后缀:

{
  "compilerOptions": {
    // 保留原有配置
    "module": "ESNext", // 指定生成ESM模块
    "moduleResolution": "nodenext", // 适配Node.js的ESM/CJS混合解析规则
    "esModuleInterop": true,
    "resolveJsonModule": true
  }
}

moduleResolution: "nodenext"(或node16)会让TS严格遵循Node.js的模块解析逻辑,编译后自动给相对路径的导入添加.js后缀,生成符合Lambda要求的ESM代码。

方案2:配置serverless-typescript插件的ESBuild选项

如果serverless-typescript插件底层使用ESBuild编译,可在serverless.yml中配置ESBuild的ESM相关选项,确保后缀补全:

service: checkout-service

provider:
  name: aws
  runtime: nodejs18.x
  # 其他provider配置

plugins:
  - serverless-typescript

custom:
  esbuild:
    bundle: true
    format: esm
    target: node18
    outExtension:
      '.js': '.js'

ESBuild默认会处理ESM的后缀问题,将TS代码编译为符合Node.js要求的ESM文件。

方案3:临时补救脚本(不推荐长期使用)

如果以上方案暂时无法生效,可在TS编译后添加一个自定义脚本,批量为JS文件中的相对导入补全.js后缀。比如使用sed命令(仅适用于简单场景):

find .build -name "*.js" -exec sed -i 's/from '\''\.\([^'\'']*\)'\''/from '\''\.\1.js'\''/g' {} +

这种方式属于hack手段,仅作为临时过渡使用,长期建议优先调整TS或构建配置。


内容的提问来源于stack exchange,提问作者Björn Grambow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:17:19