服务端如何用puppeteer-core实现50MB内URL转PDF功能
服务端puppeteer-core实现URL转PDF的轻量部署方案
可行方案选型
直接选用@sparticuz/chromium搭配puppeteer-core即可满足所有要求:
- 整体部署包压缩后体积在35-42MB区间,远低于50MB限制
- 完全本地运行,不依赖任何第三方外部API
- 不需要自定义HTML模板,传入目标URL即可直接生成PDF
- 是目前Serverless环境下最稳定的精简Chromium实现,替代已停止维护的chrome-aws-lambda,兼容所有主流Node.js服务端运行环境、Lambda类Serverless环境。
这个精简版Chromium专门裁剪了非网页渲染、PDF生成必需的组件:移除了DevTools、多余语言包、冗余音视频编解码器、GPU渲染相关模块,静态编译了所有系统依赖,不需要在服务端额外安装Chrome相关的系统库。
实现步骤
- 安装匹配版本的依赖
注意两个包的大版本需要对应,比如puppeteer-core@22.x对应@sparticuz/chromium@122.x,避免版本不兼容导致启动失败:
npm install puppeteer-core @sparticuz/chromium
- 核心功能代码
直接复用以下代码即可,默认配置适配无GUI服务端环境:
const puppeteer = require('puppeteer-core'); const chromium = require('@sparticuz/chromium'); /** * 传入URL生成PDF * @param {string} targetUrl 要转PDF的目标URL * @param {object} customPdfOptions 自定义PDF配置,和puppeteer原生pdf方法参数一致 * @returns {Promise<Buffer>} PDF文件buffer */ async function urlToPdf(targetUrl, customPdfOptions = {}) { const browser = await puppeteer.launch({ args: chromium.args, executablePath: await chromium.executablePath(), headless: chromium.headless, ignoreHTTPSErrors: true }); try { const page = await browser.newPage(); // 等待页面网络空闲后再渲染,避免动态内容加载不全 await page.goto(targetUrl, { waitUntil: 'networkidle2', timeout: 30000 }); // 默认生成A4尺寸、保留网页背景、带常规边距的PDF const defaultPdfOptions = { format: 'A4', printBackground: true, margin: { top: '20px', right: '20px', bottom: '20px', left: '20px' } }; return await page.pdf({ ...defaultPdfOptions, ...customPdfOptions }); } finally { await browser.close(); } } // 调用示例:生成example.com的PDF存到本地 // urlToPdf('https://example.com').then(pdfBuffer => { // require('fs').writeFileSync('result.pdf', pdfBuffer); // });
部署优化提示
- 打包部署时排除node_modules下的
*.md文档、test测试目录、example示例目录,可进一步把包体积压缩到38MB以内 - 如果是部署到内存限制较小的Serverless环境,可在启动参数中追加
--disable-dev-shm-usage,避免大页面渲染时内存不足 - 不需要额外配置系统依赖,该Chromium版本已静态编译所有运行必需的库,在纯精简版Linux服务端镜像(比如alpine、slim版本Node镜像)中也可直接运行
内容的提问来源于stack exchange,提问作者Jonah
相关产品推荐
相关产品推荐

