蜀黍CT 2025-06-24 19:48 采纳率: 100%
浏览 22
已结题

Electron+vue 启动web端 error:fs.existsSync 报错

Electron+vue项目中,启动web服务,报错index.js:7 Uncaught TypeError: fs.existsSync is not a function?
背景:接手了一个Electron+vue 的桌面端项目,基本上功能已经开发完毕,我只是处理些bug。

现来了一个需求,需要把这个桌面端项目切换成web网页。
只需要部分需求使用web端,然后领导就想web端和桌面端代码统一管理。

我在package.json里面看到有"serve": "vue-cli-service serve",直接执行命令,报错 getElectronPath 函数触发的,Uncaught TypeError fs.existsSync is not a function,通过报错,直接定位到node_modules,electron包里面的index。
本身web上面也访问不了fs,桌面端代码里面有很多与本地文件交互的,这该如何是好,难道要重新搭建框架吗,想问大家有没有解决办法?

node_modules,electron包里面的index.js:

const fs = require('fs');
const path = require('path');

const pathFile = path.join(__dirname, 'path.txt');

function getElectronPath () {
  if (fs.existsSync(pathFile)) {
    const executablePath = fs.readFileSync(pathFile, 'utf-8');
    if (process.env.ELECTRON_OVERRIDE_DIST_PATH) {
      return path.join(process.env.ELECTRON_OVERRIDE_DIST_PATH, executablePath);
    }
    return path.join(__dirname, 'dist', executablePath);
  } else {
    throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again');
  }
}
console.log(getElectronPath(),"getElectronPath")
module.exports = getElectronPath();

package.json:

{
    "name": "vcloud",
    "version": "2025.5.0",
    "private": true,
    "main": "background.js",
    "scripts": {
        "build1": "node ./plugins/version.js && vue-cli-service electron:build && node ./plugins/buildMd5.js",
        "build": "node ./plugins/version.js && vue-cli-service electron:build",
        "dev": "vue-cli-service electron:serve",
        "build:web": "vue-cli-service build",
        "serve": "vue-cli-service serve",
        "build:icon": "electron-icon-builder --input=./public/icon.png --output=build --flatten",
        "postinstall": "electron-builder install-app-deps",
        "postuninstall": "electron-builder install-app-deps",
        "build:md5": "node ./plugins/buildMd5.js"
    },
    "dependencies": {
        "@better-scroll/core": "^2.0.4",
        "@types/node": "^22.10.5",
        "@vue-office/docx": "^1.3.1",
        "@vue-office/excel": "^1.4.7",
        "@vue-office/pdf": "^1.5.5",
        "assert-strict": "0.0.2",
        "awe-dnd": "^0.3.4",
        "axios": "^0.27.2",
        "browserify": "^17.0.1",
        "bytenode": "^1.1.7",
        "core-js": "^3.6.5",
        "cpy": "^8.1.1",
        "crypto-js": "^4.0.0",
        "del": "^6.0.0",
        "dns": "^0.2.2",
        "docx-preview": "^0.1.20",
        "docx-to-html": "^1.0.1",
        "electron-download": "^4.1.1",
        "element-china-area-data": "^6.1.0",
        "element-ui": "^2.13.2",
        "find-process": "^1.4.3",
        "fs-extra": "^9.0.1",
        "globby": "^11.0.3",
        "got": "^11.8.5",
        "http2": "^3.3.7",
        "iconv-lite": "^0.6.3",
        "js-base64": "^3.6.0",
        "js-file-download": "^0.4.12",
        "jszip": "^3.10.1",
        "log4js": "^6.9.1",
        "md5-file": "^5.0.0",
        "node-7z": "^3.0.0",
        "node-cmd": "^5.0.0",
        "node-rsa": "^1.1.1",
        "phantomjs-prebuilt": "^2.1.16",
        "postcss-px-to-viewport": "^1.1.1",
        "pptxgenjs": "^3.12.0",
        "qiniu-js": "^3.1.2",
        "register-service-worker": "^1.7.1",
        "request": "^2.88.2",
        "request-progress": "^3.0.0",
        "socket.io-client": "^2.0.3",
        "swiper": "^6.8.4",
        "video-player": "^0.0.1",
        "vtip": "^1.0.6",
        "vue": "^2.6.11",
        "vue-awesome-swiper": "^4.1.1",
        "vue-cropper": "^0.5.5",
        "vue-demi": "^0.13.11",
        "vue-office-preview": "^1.0.2",
        "vue-pdf": "^4.3.0",
        "vue-photo-preview": "^1.1.3",
        "vue-qr": "^4.0.9",
        "vue-router": "^3.4.8",
        "vue-uuid": "^2.0.2",
        "vue-video-player": "^5.0.2",
        "vuex": "^3.4.0",
        "vuex-electron": "^1.0.3",
        "xlsx": "^0.18.5"
    },
    "devDependencies": {
        "@vue/cli-plugin-babel": "~4.5.0",
        "@vue/cli-plugin-pwa": "~4.5.0",
        "@vue/cli-plugin-router": "~4.5.0",
        "@vue/cli-plugin-vuex": "~4.5.0",
        "@vue/cli-service": "~4.5.0",
        "chalk": "^4.1.0",
        "css-loader": "^5.0.0",
        "electron": "^12.2.3",
        "electron-debug": "^3.1.0",
        "electron-devtools-installer": "^3.1.1",
        "electron-icon-builder": "^1.0.2",
        "postcss-loader": "^4.0.4",
        "style-loader": "^2.0.0",
        "stylus": "^0.54.8",
        "stylus-loader": "^3.0.2",
        "vue-cli-plugin-electron-builder": "~2.0.0",
        "vue-devtools": "^5.1.4",
        "vue-style-loader": "^4.1.2",
        "vue-template-compiler": "^2.6.11",
        "webpack-bundle-analyzer": "^3.9.0"
    },
    "browserslist": [
        "> 1%",
        "last 2 versions",
        "not dead"
    ],
    "__npminstall_done": false
}



img

img

img

  • 写回答

7条回答 默认 最新

  • 檀越@新空间 2025-06-24 19:49
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    在你描述的场景中,你正在将一个 Electron + Vue 的桌面端项目转换为 Web 端,但遇到了 fs.existsSync is not a function 的错误。这个错误是因为你在 Web 环境中使用了 Node.js 的 fs 模块(文件系统模块),而浏览器环境并不支持 fs


    🔍 问题分析

    1. Electron 和 Web 环境的区别

    • Electron 是基于 Node.js 的框架,可以访问 fspath 等 Node.js 模块。
    • Web 环境(如浏览器)不支持 Node.js 的原生模块(如 fschild_process 等)。

    2. 报错来源

    你提到的错误是:

    Uncaught TypeError: fs.existsSync is not a function
    

    这说明你在前端代码中调用了 fs.existsSync,而这在浏览器中是无效的。


    ✅ 解决方案

    🧩 一、区分 Electron 和 Web 环境

    你需要在代码中判断当前运行的是 Electron 还是 Web 环境,并根据不同的环境加载不同的逻辑。

    1. 在入口文件(如 main.jsindex.js)中添加判断:

    // main.js 或 index.js
    
    if (typeof window !== 'undefined') {
      // Web 环境
      console.log('Running in Web environment');
    } else {
      // Electron 环境
      console.log('Running in Electron environment');
    }
    

    2. 使用 process.versions.electron 判断是否是 Electron 环境:

    const isElectron = process.versions && process.versions.electron;
    
    if (isElectron) {
      // 加载 Electron 相关模块
      const fs = require('fs');
      const path = require('path');
    } else {
      // Web 环境,不能使用 fs
    }
    

    🧩 二、分离 Electron 与 Web 代码

    你可以将 Electron 相关的代码单独封装成一个模块,在 Web 环境下忽略或替换这些模块。

    示例结构:

    src/
    ├── main.js        // Electron 主进程入口
    ├── renderer/      // 前端代码(Vue)
    │   ├── App.vue
    │   └── main.js    // Web 入口
    └── electron-utils.js  // Electron 工具函数
    

    electron-utils.js 示例:

    // electron-utils.js
    export default {
      getElectronPath() {
        if (typeof window === 'undefined') {
          const fs = require('fs');
          const path = require('path');
          return path.resolve(__dirname, '..', 'assets');
        } else {
          // Web 环境下无法获取路径,可抛出错误或返回默认值
          throw new Error('Not supported in web environment');
        }
      }
    }
    

    在 Web 环境中,你可以用 import 引入该模块,但在 vue-cli-service serve 启动时,会尝试加载 Electron 模块,导致错误。


    🧩 三、修改 vue.config.js 避免加载 Electron 模块

    如果你在 Vue 项目中引用了 Electron 模块,比如 require('electron'),那么在 Web 环境下就会报错。

    修改 vue.config.js 文件:

    module.exports = {
      configureWebpack: {
        node: {
          fs: 'empty', // 防止在 Web 环境中加载 fs 模块
          child_process: 'empty'
        }
      }
    }
    

    ⚠️ 注意:如果只是部分代码需要 Electron 功能,建议通过条件判断来控制加载。


    🧩 四、使用构建工具区分环境

    你可以使用 webpackvitemode 来区分开发环境,从而动态加载不同模块。

    示例(使用 vite):

    // vite.config.js
    import { defineConfig } from 'vite';
    import vue from '@vitejs/plugin-vue';
    
    export default defineConfig({
      plugins: [vue()],
      define: {
        __APP_ENV__: JSON.stringify(process.env.VITE_APP_ENV),
      },
    });
    

    然后在代码中:

    if (import.meta.env.VITE_APP_ENV === 'electron') {
      // 加载 Electron 相关逻辑
    }
    

    🧩 五、重构部分功能,适配 Web 环境

    如果你的项目中有一些依赖本地文件系统的功能(如读写配置文件、生成 PDF 等),这些在 Web 环境中是不可行的。

    可能的替代方案:

    | 功能 | Electron 实现 | Web 实现 | |------|----------------|----------| | 读取本地文件 | fs.readFileSync() | 使用 <input type="file"> 用户上传 | | 写入本地文件 | fs.writeFileSync() | 不支持,需后端协助或使用 FileSaver.js | | 生成 PDF | pdfmakepuppeteer | jsPDFhtml2canvas | | 存储数据 | localStoragefs | localStorageIndexedDB |


    ✅ 总结

    | 问题 | 解决方案 | |------|----------| | fs.existsSync is not a function | 区分 Electron 和 Web 环境,避免在 Web 中使用 Node.js 模块 | | 代码统一管理 | 使用条件判断加载不同模块,保持代码结构一致 | | 构建错误 | 修改 vue.config.jsvite.config.js,避免加载 Electron 模块 | | 功能适配 | 重构部分功能,使用 Web 技术替代 Node.js 功能 |


    📌 最终建议

    • 不要重写整个项目,而是逐步迁移,保留 Electron 功能的同时,适配 Web 环境。
    • 使用条件编译,例如 #ifdefif (process.versions.electron) 来控制代码执行路径。
    • 使用 Web API 替代 Node.js 功能,如 localStoragefetchFile API 等。

    如有需要,我可以帮你提取 Electron 相关代码,并提供一个兼容 Web 的版本。欢迎继续提问!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

问题事件

  • 系统已结题 7月4日
  • 已采纳回答 6月26日
  • 修改了问题 6月24日
  • 创建了问题 6月24日