如何用 Electron 构建 GrapesJS 桌面应用(2026 年完整指南)

在Electron桌面应用中运行GrapesJS:挂载到渲染器中,通过IPC保存项目到磁盘,导出HTML/CSS。

DevFuture Development
DevFuture Development
2026年6月10日18 天前
阅读约 4 分钟10 次浏览

为什么GrapesJS适合Electron

Electron 在桌面窗口中渲染网页,GrapesJS 是一个浏览器编辑器, 所以它在渲染器里运行,没有任何修改。桌面的创新是存储:而是 通过Electron的IPC将项目保存到磁盘。本指南安装 编辑器,安全保存到磁盘,并导出HTML/CSS——完全离线。

1. 从预加载中暴露一个安全的保存/加载API

继续 contextIsolation ,只接你需要的部分 preload.js

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('store', {
  load: () => ipcRenderer.invoke('page:load'),
  save: (data) => ipcRenderer.invoke('page:save', data),
});

2. 在主进程中处理磁盘I/O

const { app, ipcMain } = require('electron');
const fs = require('fs/promises');
const path = require('path');

const file = path.join(app.getPath('userData'), 'page.json');

ipcMain.handle('page:load', async () => {
  try { return JSON.parse(await fs.readFile(file, 'utf8')); }
  catch { return {}; }
});

ipcMain.handle('page:save', async (_e, data) => {
  await fs.writeFile(file, JSON.stringify(data));
  return { status: 'ok' };
});

3. 渲染器中的葡萄山JS

import grapesjs from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';

const editor = grapesjs.init({
  container: '#gjs',
  height: '100vh',
  fromElement: true,
  storageManager: false,
});

// Load saved project on start, save on demand.
window.store.load().then((p) => p.project && editor.loadProjectData(p.project));

document.getElementById('save').onclick = () =>
  window.store.save({
    project: editor.getProjectData(),
    html: editor.getHtml(),
    css: editor.getCss(),
  });

安全提示

Colourful code on a dark screen
保持 contextIsolation 状态,并开放一个微小的显式 API。

桌面编辑器仍然应当保持严格的安全防护。保持contextIsolation: true和,且绝不在渲染器中启用nodeIntegration——只通过预加载脚本暴露最小的 loadsave API 或 API contextBridge sandbox: true。在写入磁盘前,先在主进程验证有效载荷(大小、形状),因为渲染器会加载远程的GrapesJS代码。写入app.getPath('userData')时,文件会落在操作系统合适的位置,考虑原子写入(临时文件 + 重命名),这样存档中途崩溃时项目不会损坏。

前提条件

你需要Node.js 18+和Electron。编辑器像任何网页一样运行在渲染器中 佩奇;桌面的特点是存储——你通过Electron的IPC保存到磁盘 属于一个HTTP服务器。熟悉主渲染/渲染器分割、预加载脚本和IPC 就够了。

向编辑器添加自定义方块

在渲染器中用块管理器注册可拖拽的块:grapesjs.init

editor.BlockManager.add('hero', {
  label: 'Hero section',
  category: 'Sections',
  content: '<section class="hero"><h1>Headline</h1><p>Copy</p></section>',
});

从GJS拉取现成的块库和预设。市场要买更丰富的套装。

磁盘上的原子写入

把项目写成临时文件,然后重新命名,这样保存过程中就不会崩溃 文件会损坏:

ipcMain.handle('page:save', async (_e, data) => {
  const tmp = file + '.tmp';
  await fs.writeFile(tmp, JSON.stringify(data));
  await fs.rename(tmp, file);     // atomic on most filesystems
  return { status: 'ok' };
});

表演技巧

把GrapesJS捆绑在你的渲染器上(通过Vite或Webpack),这样它就能从本地文件加载出来 而且这个应用完全离线运行。只有当插件功能 打开了。当视角卸载时销毁编辑器,这样在窗口之间切换时 路由不会泄露实例。

安全考量

保持 contextIsolation: truesandbox: true,永不 在渲染器中启用 nodeIntegration — 只暴露最小值 load/save 通过 contextBridgeAPI验证 在写入前的主进程中,由于渲染器,有效载荷(形状和大小)就已完成 加载远程编辑器代码。写在 app.getPath('userData')

排查常见问题

渲染器中“要求未定义”表示你尝试使用 Node API 直接通过预加载桥接。未样式或空白 Canvas 意味着样式表没有加载,或者容器不存在。 “无声保存失败”通常指IPC信道名称或处理程序 不匹配。

何时在电子中使用GrapesJS

GrapesJS 适合需要离线可视化编辑器的桌面应用——本地页面或 邮件设计器、文档构建器、自助终端内容工具。因为 获得麻省理工学院授权且自成一体,你可以将整个编辑体验交付在你的内部 没有服务器,也没有按座位付费的应用。

下一步

请参见相关的 GrapesJS + Vite 设置 (方便捆绑渲染器)以及 GrapesJS + React 指南,浏览 GrapesJS市场,或者从这里开始 GJS。市场主页

常见问题

GrapesJS 能在 Electron 中离线运行吗?

是的——把GrapesJS捆绑在渲染器里,通过主硬盘把项目存到磁盘上 过程。不需要网络。

我该如何将项目保存到磁盘?

从渲染器发送该项目,带 ipcRenderer.invoke (exposed 通过预加载),并在主进程中写入 fs ,在 app.getPath('userData')

我应该启用 contextIsolation(上下文隔离)吗?

是的——保持开启,并用一个小型 API contextBridge 暴露 使得 nodeIntegration

更多标签:
发布于 2026年6月10日
更新于 2026年6月27日
🔌 GJS.Market

在寻找 GrapesJS 插件吗?

超过 100 款精选插件、预设与模板 —— 由社区精挑细选并持续维护。

分享本文TwitterFacebookLinkedIn
发布平台
DevFuture Development
DevFuture Development
访问店铺 →

更多来自 DevFuture Development

发现更多精彩文章,及时获取最新内容。

查看全部文章

来自 DevFuture Development 的付费插件

由该作者精心打造的精选付费插件。

访问店铺 →