Symfony Webpack Encore集成Puppeteer构建报错求助
问题解决:Symfony Webpack Encore 打包 Puppeteer 报错
错误原因
Puppeteer 是专为 Node.js 环境设计的库,依赖 fs、path 等 Node.js 核心模块。而 Webpack Encore 默认是构建浏览器端前端资产,浏览器环境不存在这些 Node 核心模块,所以会出现找不到 fs 的错误。另外两个警告是因为部分依赖库使用了动态 require,Webpack 无法静态分析这些依赖。
解决方案
方案一:正确的使用方式(推荐)
把 Puppeteer 的代码从前端资产目录(assets/)移到后端,作为 Node.js 脚本或者 Symfony 命令来执行:
- 在项目根目录新建脚本文件,比如
scripts/screenshot.js,写入 Puppeteer 逻辑:
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://example.com'); await page.screenshot({ path: 'example.png' }); await browser.close(); })();
- 在 Symfony 中可以通过
Process组件调用这个脚本,比如创建一个命令:
// src/Command/ScreenshotCommand.php namespace App\Command; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\Process; class ScreenshotCommand extends Command { protected static $defaultName = 'app:screenshot'; protected function execute(InputInterface $input, OutputInterface $output): int { $process = new Process(['node', __DIR__.'/../../scripts/screenshot.js']); $process->run(); if (!$process->isSuccessful()) { $output->writeln($process->getErrorOutput()); return Command::FAILURE; } $output->writeln('截图已生成'); return Command::SUCCESS; } }
- 直接执行命令或者通过控制器调用这个命令即可,不需要让 Webpack 打包 Puppeteer。
方案二:强行让 Webpack 兼容(不推荐)
如果非要在前端打包 Puppeteer(实际浏览器中无法运行,仅用于特殊场景),需要配置 Webpack 补充 Node 核心模块的 polyfill:
- 安装依赖:
npm install node-polyfill-webpack-plugin --save-dev
- 修改 Webpack Encore 配置:
const Encore = require('@symfony/webpack-encore'); const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); if (!Encore.isRuntimeEnvironmentConfigured()) { Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev'); } Encore .setOutputPath('public/build/') .setPublicPath('/build') .addEntry('app', './assets/app.js') .addEntry('screenshot', './assets/screenshot.js') .splitEntryChunks() .enableSingleRuntimeChunk() .cleanupOutputBeforeBuild() .enableBuildNotifications() .enableSourceMaps(!Encore.isProduction()) .enableVersioning(Encore.isProduction()) .configureBabelPresetEnv((config) => { config.useBuiltIns = 'usage'; config.corejs = '3.23'; }) // 添加以下配置 .addPlugin(new NodePolyfillPlugin()) .configureWebpack((config) => { config.resolve.fallback = { fs: false, // 或者用 'browserify-fs',但可能还是有问题 path: require.resolve('path-browserify'), os: require.resolve('os-browserify/browser'), child_process: false, // Puppeteer 依赖的子进程在浏览器中无法模拟 }; }) ; module.exports = Encore.getWebpackConfig();
注意:即使这样配置,Puppeteer 在浏览器中也无法正常运行,因为它需要启动 Chromium 浏览器实例,浏览器环境没有权限做这件事。
内容的提问来源于stack exchange,提问作者Xubba
相关产品推荐
相关产品推荐

