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

Nextron项目配置next.config.js后fs读取HTML到变量仍报错

问题根因

这个报错的核心原因是混淆了纯Web端Next.js和Nextron(Electron+Next.js)的运行环境差异,之前参考的纯Web场景解决方案完全不适用于桌面端Electron环境:

  • 纯Web端的Next.js运行在浏览器里,本身没有Node.js运行时,天生不支持fs这类本地系统模块,你之前加的fs: 'empty'配置,本质是打包时给fs塞一个空对象占位,避免打包阶段抛错,但这个空对象没有任何实际文件读写能力,调用时必然报错。
  • Electron架构天然隔离两个运行环境,两者的权限和可用API完全不同:
    • 主进程:具备完整Node.js运行时,原生支持所有Node内置模块(包括fs),拥有本地文件系统的完整读写权限
    • 渲染进程:就是你写Next.js页面代码的运行环境,默认是类Chrome的沙箱环境,出于安全限制默认不注入Node.js API,直接引入fs要么被webpack打包拦截报错,要么拿到你配置的空占位模块,根本无法实现文件读取。
  • 额外的路径问题:你代码里写的fs.readFileSync("./template.html")用了相对路径,Electron中相对路径默认相对于进程启动目录,不是代码文件所在目录,就算fs可用也大概率读不到目标文件。
修复方案

根据项目的安全要求二选一即可:

方案1:主进程处理IO逻辑(官方推荐,安全性最高)

这是Electron生态推荐的标准实践,所有涉及本地系统的操作都放在主进程执行,渲染进程通过IPC通信拿结果,能避免渲染层被攻破时直接拿到系统权限。

  1. 第一步先删除next.config.js里之前添加的config.node = {fs: 'empty'}配置,这个配置在Electron场景下会覆盖真实的fs模块,必须移除。
  2. 在主进程入口文件(通常是main/background.js)中添加IPC处理逻辑,注意读取文件时要拼绝对路径,同时指定字符编码避免返回Buffer类型:
import { ipcMain } from 'electron'
import fs from 'fs'
import path from 'path'

// 监听渲染进程的模板读取请求
ipcMain.handle('load-template-html', () => {
  // 按自己的template.html实际存放位置调整路径,生产打包时如果把模板作为额外资源,要替换为resources目录下的对应路径
  const templateFullPath = path.resolve(process.cwd(), './template.html')
  return fs.readFileSync(templateFullPath, 'utf-8')
})
  1. 在渲染进程的业务代码中,通过IPC向主进程发起请求拿文件内容,不要直接在渲染层引入fs:
const { ipcRenderer } = window.require('electron')

const generatePDF = async () => {
  const templateContent = await ipcRenderer.invoke('load-template-html')
  // 后续拿templateContent做PDF生成逻辑即可
}

方案2:渲染进程直接开启Node集成(仅适合内部工具,不推荐公开分发场景用)

如果做的是无安全风险的内部工具,不想写IPC通信逻辑,可以直接给渲染窗口开启Node权限,直接在渲染层调用fs:

  1. 同样先删除next.config.js里之前加的fs空模块配置。
  2. 修改主进程创建BrowserWindow的参数,开启Node集成、关闭上下文隔离:
const mainWindow = new BrowserWindow({
  // 其他窗口配置保持不变
  webPreferences: {
    nodeIntegration: true,
    contextIsolation: false,
  }
})
  1. 渲染进程代码中用window.require引入Node模块(不要用顶层import,会被Next.js的webpack打包逻辑误处理),同时用绝对路径读取文件:
const fs = window.require('fs')
const path = window.require('path')

const generatePDF = () => {
  const templateFullPath = path.resolve(process.cwd(), './template.html')
  const templateContent = fs.readFileSync(templateFullPath, 'utf-8')
  // 后续业务逻辑
}

注意事项:生产环境打包时,记得把template.html添加到electron-builder的extraResources配置中,否则打包后模板文件不会被带入安装包,会出现找不到文件的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:36:26