Symfony6 Webpack安装google-spreadsheet后因模块缺失构建失败
问题描述
在集成Webpack的全新Symfony 6.0项目中安装google-spreadsheet npm包,包本身可正常安装,但执行构建操作时抛出7个编译错误,具体报错信息如下:
ERROR Failed to compile with 7 errors Module build failed: Module not found: "./node_modules/google-p12-pem/build/src/index.js" contains a reference to the file "fs". This file can not be found, please check it for typos or update it if the file got moved. "./node_modules/google-spreadsheet/node_modules/google-auth-library/build/src/auth/googleauth.js" contains a reference to the file "child_process". This file can not be found, please check it for typos or update it if the file got moved. "./node_modules/google-spreadsheet/node_modules/google-auth-library/build/src/auth/googleauth.js" contains a reference to the file "fs". This file can not be found, please check it for typos or update it if the file got moved. "./node_modules/gtoken/build/src/index.js" contains a reference to the file "fs". This file can not be found, please check it for typos or update it if the file got moved. "./node_modules/https-proxy-agent/dist/agent.js" contains a reference to the file "net". This file can not be found, please check it for typos or update it if the file got moved. "./node_modules/https-proxy-agent/dist/agent.js" contains a reference to the file "tls". This file can not be found, please check it for typos or update it if the file got moved. "./node_modules/node-forge/lib/random.js" contains a reference to the file "jquery". This file can not be found, please check it for typos or update it if the file got moved.
当前使用的webpack.config.js配置如下:
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); const Encore = require('@symfony/webpack-encore'); if (!Encore.isRuntimeEnvironmentConfigured()) { Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev'); } Encore .setOutputPath('public/build/') .setPublicPath('/build') .addEntry('app', './assets/app.js') .enableStimulusBridge('./assets/controllers.json') .splitEntryChunks() .enableSingleRuntimeChunk() .cleanupOutputBeforeBuild() .enableBuildNotifications() .enableSourceMaps(!Encore.isProduction()) .enableVersioning(Encore.isProduction()) .configureBabel((config) => { config.plugins.push('@babel/plugin-proposal-class-properties'); }) .configureBabelPresetEnv((config) => { config.useBuiltIns = 'usage'; config.corejs = 3; }) .autoProvidejQuery() .addPlugin(new NodePolyfillPlugin()) ; module.exports = Encore.getWebpackConfig();
问题根因
报错的核心原因有两点:
google-spreadsheet是面向Node.js服务端环境设计的包,依赖fs、child_process、net、tls等Node.js原生内置模块。Webpack从5版本开始默认不再自动为前端构建注入Node核心模块的浏览器端polyfill,你虽然引入了node-polyfill-webpack-plugin,但child_process、fs这类涉及本地文件操作、进程调用的模块本身就不存在可在浏览器中运行的polyfill实现,插件也无法补全这部分依赖。- 最后一条jquery找不到的报错,是依赖包
node-forge的可选依赖检测逻辑导致的:它的随机数生成模块会尝试探测运行环境中是否存在jquery,这段探测代码被Webpack识别为强制依赖,在未安装jquery的场景下就会抛出模块找不到的错误,并非真的强制依赖jquery才能运行。
额外安全提示:直接在前端代码中引入google-spreadsheet本身就存在严重安全风险,调用Google表格API所需的服务账号密钥、凭证信息会被直接打包到前端静态资源中,任何人都可以通过浏览器开发者工具获取到凭证,进而盗用你的Google云资源权限。
解决方案
推荐方案:将Google表格交互逻辑迁移到后端实现
这是唯一符合生产环境安全要求、功能可完整运行的方案:
- 不要在
assets目录下的前端入口代码中引入google-spreadsheet包 - 在Symfony后端代码中实现和Google表格的交互逻辑(可以直接用PHP生态的Google客户端,也可以起独立的Node服务做中间层)
- 前端仅负责请求你自己服务端封装的接口,完成数据的读写操作
这种方案从根源上避免了把Node专属依赖打包到前端bundle的问题,也不会出现凭证泄露的风险。
临时测试方案:调整Webpack配置跳过无法兼容的模块
如果仅做本地功能测试、不考虑生产安全和功能完整性,可以通过修改Webpack配置跳过无法在浏览器端运行的模块依赖,完成构建:
- 首先安装jquery依赖解决最后一条报错:
npm install jquery
- 修改
webpack.config.js,在Encore配置链中新增Webpack原生配置,将不存在浏览器polyfill的Node模块标记为外部空模块:
// 在已有的Encore配置链中追加以下配置项 .configureWebpack({ resolve: { fallback: { child_process: false, fs: false, net: false, tls: false } } })
修改后重新执行构建即可跳过上述模块找不到的报错。需要注意:这种方式打包出来的前端代码,所有涉及本地文件读取、服务账号p12密钥加载、子进程调用的功能都无法正常运行,仅支持API Key方式访问公开Google表格的场景。
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

