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"] }
问题
- 为什么会出现
TypeError: chromium.executablePath is not a function错误? - 对于此类设置,在AWS CDK中是否有特定的Lambda层打包或配置方式?
- 在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正确排除层中依赖,避免打包时将依赖打入函数包引发冲突。
- 避免同时兼容X86和ARM架构,
- 层构建规范:在层的
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
相关产品推荐
相关产品推荐

