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

AWS CDK TypeScript Lambda报错:chromium.executablePath不是函数

AWS Lambda + Puppeteer + @sparticuz/chromium 部署报错排查

环境与配置

层依赖

Lambda层的package.json依赖:

"dependencies": {
  "@sparticuz/chromium": "^106.0.2",
  "puppeteer-core": "^18.0.5"
}

Lambda函数代码

const puppeteer = require("/opt/nodejs/puppeteer-core");
const chromium = require("/opt/nodejs/@sparticuz/chromium");

async function createPdf(fileLinks: Record<string, string>, logoDataUri: string, bucketName: string, key: string): Promise<Buffer> {
  await chromium.font("https://raw.githack.com/googlei18n/noto-emoji/master/fonts/NotoColorEmoji.ttf");

  const browser = await puppeteer.launch({
    args: chromium.args,
    defaultViewport: chromium.defaultViewport,
    executablePath: await chromium.executablePath(),
    headless: chromium.headless,
  });

  // ... 函数剩余部分
}

报错信息

调用Lambda时触发的错误:

{
  "errorType": "TypeError",
  "errorMessage": "chromium.executablePath is not a function",
  "trace": [
    "TypeError: chromium.executablePath is not a function",
    "    at createPdf (/var/task/index.js:70735:36)",
    "    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)",
    "    at async Runtime.handler (/var/task/index.js:70601:21)"
  ]
}

CDK配置

this.chromiumLayer = new LayerVersion(this, "chromiumLayer", {
  code: Code.fromAsset(join(__dirname, "../../src/layers/chromium")),
  compatibleRuntimes: [Runtime.NODEJS_20_X],
  compatibleArchitectures: [Architecture.X86_64, Architecture.ARM_64],
  description: "Chromium layer for Lambda",
});

this.createDownloadPDF = new NodejsFunction(this, "createDownloadPDF", {
  // ... 其他配置
  layers: [this.chromiumLayer],
  bundling: {
    externalModules: ["aws-sdk", "@sparticuz/chromium", "puppeteer-core"],
    // ... 其他打包选项
  },
});

tsconfig路径配置

"paths": {
  "/opt/nodejs/puppeteer-core": ["./src/layers/chromium/nodejs/node_modules/puppeteer-core"],
  "/opt/nodejs/@sparticuz/chromium": ["./src/layers/chromium/nodejs/node_modules/@sparticuz/chromium"]
}

问题

  1. 为什么会出现TypeError: chromium.executablePath is not a function错误?
  2. 对于此类设置,在AWS CDK中是否有特定的Lambda层打包或配置方式?
  3. 在Lambda环境中正确集成@sparticuz/chromium与Puppeteer还需要哪些额外步骤?

解决方案与解答

1. 错误原因分析

核心原因有两点:

  • 版本不兼容:@sparticuz/chromium@106.0.2是旧版本,其API导出结构与代码调用不匹配;同时搭配的puppeteer-core@18.0.5对应Chromium 100左右版本,与Chromium 106版本差过大,导致API不兼容。
  • 层路径结构错误:Lambda层的Node.js依赖必须放在nodejs/目录下,才能被Lambda在/opt/nodejs路径加载。如果层目录结构不符合规范,会导致模块加载异常,导出对象不是预期结构,进而找不到executablePath方法。

2. CDK中层的正确打包与配置

  • 严格遵循层目录结构:层代码必须放在src/layers/chromium/nodejs/下,package.json和node_modules都要在这个nodejs目录内,确保CDK打包后,Lambda能正确读取/opt/nodejs下的依赖。
  • 优化CDK层配置:
    • 避免同时兼容X86和ARM架构,@sparticuz/chromium针对不同架构有不同二进制包,多架构兼容会导致层体积过大,甚至出现二进制不匹配问题,建议只保留当前使用的架构(如Architecture.X86_64)。
    • 确认NodejsFunction的externalModules正确排除层中依赖,避免打包时将依赖打入函数包引发冲突。
  • 层构建规范:在层的nodejs目录下执行npm install --production,确保node_modules只包含生产依赖,再由CDK打包该目录。

3. 正确集成的额外步骤

  • 版本对齐:升级到兼容的版本组合,比如:
    "@sparticuz/chromium": "^120.0.0",
    "puppeteer-core": "^21.0.0"
    
    (@sparticuz/chromium的主版本号与Chromium版本号一致,可据此匹配对应Puppeteer版本)
  • 规范模块导入:改用ES模块导入(推荐),同时调整tsconfig路径映射,避免硬编码/opt/nodejs:
    import puppeteer from 'puppeteer-core';
    import chromium from '@sparticuz/chromium';
    
    "paths": {
      "puppeteer-core": ["./src/layers/chromium/nodejs/node_modules/puppeteer-core"],
      "@sparticuz/chromium": ["./src/layers/chromium/nodejs/node_modules/@sparticuz/chromium"]
    }
    
  • Lambda资源配置:给函数分配至少1GB内存和30秒超时时间,Chromium运行需要较多资源;添加必要的IAM权限(如访问S3的权限,如果PDF生成涉及存储操作)。
  • 字体本地化:将自定义字体文件打包到层中(如src/layers/chromium/nodejs/fonts/),避免远程加载失败:
    await chromium.font('/opt/nodejs/fonts/NotoColorEmoji.ttf');
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:05:24