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

在Electron中通过Angular读写本地JSON文件及CRUD实现方案咨询

哈哈,我太懂这种每次启动项目还要额外开个服务的麻烦了!给你几个实用的解决方案,既能摆脱手动启动json-server的繁琐,又能搞定fs相关的问题:

方案1:在Electron启动时自动拉起json-server

这个方案完美适配你之前的使用习惯,不用手动开服务,代码里集成自动启动:

首先确保已经安装了json-server:

npm install json-server --save-dev

然后在Electron的主进程(比如main.js)里添加启动逻辑:

const { app } = require('electron');
const childProcess = require('child_process');
const path = require('path');

let jsonServerProcess;

app.whenReady().then(() => {
  // 自动启动json-server,指定你的JSON文件路径
  jsonServerProcess = childProcess.spawn('npx', [
    'json-server',
    '--watch',
    path.join(__dirname, 'db.json'), // 替换成你的本地JSON文件路径
    '--port', '3000' // 自定义端口,避免冲突
  ]);

  // 可选:打印服务日志,方便排查问题
  jsonServerProcess.stdout.on('data', (data) => {
    console.log(`json-server日志: ${data}`);
  });

  jsonServerProcess.stderr.on('data', (data) => {
    console.error(`json-server错误: ${data}`);
  });
});

// 关闭Electron时记得杀掉json-server进程,避免残留
app.on('before-quit', () => {
  if (jsonServerProcess) {
    jsonServerProcess.kill();
  }
});

这样启动Electron的同时,json-server就自动跑起来了,完全不用手动操作。

方案2:修复electron-json-storage的fs错误

你遇到的fs问题大概率是路径配置或者Electron安全限制导致的,按以下步骤排查:

  1. 确保渲染进程有Node.js权限
    如果是在渲染进程里调用electron-json-storage,需要在主进程创建窗口时配置webPreferences:

    const { BrowserWindow } = require('electron');
    const path = require('path');
    
    function createWindow() {
      const mainWindow = new BrowserWindow({
        webPreferences: {
          // 推荐用preload脚本(更安全),替代直接开nodeIntegration
          preload: path.join(__dirname, 'preload.js'),
          contextIsolation: true // 保持开启,符合Electron安全规范
        }
      });
    }
    
  2. 通过preload脚本暴露存储API
    在preload.js里封装electron-json-storage的方法,暴露给渲染进程:

    const { contextBridge } = require('electron');
    const storage = require('electron-json-storage');
    
    contextBridge.exposeInMainWorld('electronStorage', {
      get: (key) => storage.get(key),
      set: (key, data) => storage.set(key, data),
      // 手动实现put逻辑:先获取原有数据再合并更新
      put: (key, updateData) => {
        return storage.get(key).then(existingData => {
          const mergedData = { ...existingData, ...updateData };
          return storage.set(key, mergedData);
        });
      }
    });
    

    之后在渲染进程里就可以安全调用:

    window.electronStorage.get('user').then(data => console.log(data));
    
  3. 检查存储路径权限
    electron-json-storage默认存在用户的应用数据目录(比如Windows的C:\Users\[用户名]\AppData\Roaming\[你的应用名]),这个路径是有权限的,如果你自定义了存储路径,要确保路径不是系统保护文件夹。

方案3:直接用Node.js fs模块操作JSON文件

不用第三方库,自己封装get/post/put逻辑,灵活又轻量:

创建一个storage.js工具文件:

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

// 定义JSON文件存储路径,比如项目根目录的data文件夹
const dbPath = path.join(__dirname, 'data', 'db.json');

// 确保存储目录存在
async function ensureDirExists() {
  const dir = path.dirname(dbPath);
  try {
    await fs.access(dir);
  } catch {
    await fs.mkdir(dir, { recursive: true });
  }
}

// Get:读取整个文件或指定键
async function get(key) {
  await ensureDirExists();
  try {
    const rawData = await fs.readFile(dbPath, 'utf8');
    const jsonData = JSON.parse(rawData);
    return key ? jsonData[key] : jsonData;
  } catch {
    // 文件不存在时返回默认值
    return key ? undefined : {};
  }
}

// Post:添加新数据(比如向数组中push)
async function post(key, newItem) {
  await ensureDirExists();
  const currentData = await get();
  if (!Array.isArray(currentData[key])) {
    currentData[key] = [];
  }
  currentData[key].push(newItem);
  await fs.writeFile(dbPath, JSON.stringify(currentData, null, 2));
  return newItem;
}

// Put:更新指定ID的数据
async function put(key, itemId, updatedData) {
  await ensureDirExists();
  const currentData = await get();
  if (!Array.isArray(currentData[key])) {
    throw new Error(`键${key}对应的数据不是数组`);
  }
  const targetIndex = currentData[key].findIndex(item => item.id === itemId);
  if (targetIndex === -1) {
    throw new Error(`ID为${itemId}的数据不存在`);
  }
  currentData[key][targetIndex] = { ...currentData[key][targetIndex], ...updatedData };
  await fs.writeFile(dbPath, JSON.stringify(currentData, null, 2));
  return currentData[key][targetIndex];
}

module.exports = { get, post, put };

之后在主进程或渲染进程(通过preload暴露)里导入使用即可,完全不需要额外服务。

方案4:使用更成熟的electron-store库

这个库比electron-json-storage更活跃,API更简洁,自动处理了路径和权限问题:

首先安装:

npm install electron-store

在主进程里使用:

const Store = require('electron-store');

const store = new Store({
  name: 'my-app-db' // 自定义存储文件名
});

// Get
const user = store.get('user');

// Post(新增或替换)
store.set('user', { name: 'Jim', age: 30 });

// Put(合并更新)
store.set('user', { age: 31 }, { merge: true });

// 复杂场景:更新数组中的指定项
function updateItemInArray(key, itemId, updates) {
  const array = store.get(key, []);
  const targetIndex = array.findIndex(item => item.id === itemId);
  if (targetIndex !== -1) {
    array[targetIndex] = { ...array[targetIndex], ...updates };
    store.set(key, array);
    return array[targetIndex];
  }
  throw new Error('数据不存在');
}

同样可以通过preload脚本暴露给渲染进程使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:41:41