前言

摘要:本文将带你从零开始,使用 Electron + Node.js 文件系统接口 构建一个跨平台的轻量级鸿蒙桌面文件管理器。项目支持浏览本地文件、查看 MD 文件预览、拖拽操作以及文件搜索。通过本项目,你可以掌握 Electron 渲染进程与主进程通信、文件 API 使用以及桌面应用 UI 设计技巧。


一、为什么选择 Electron 做文件管理器?

  • 跨平台:Windows / macOS / Linux 均可运行
  • Web 技术栈:熟悉的 HTML/CSS/JS 即可开发
  • 系统集成:支持拖拽、右键菜单、文件操作
  • 轻量高效:不依赖繁重的第三方框架

相比传统文件管理器,Electron 可以快速原型化,并且便于与鸿蒙桌面应用进行 UI 样式统一。


二、技术选型

模块 选型 说明
主框架 Electron 28+ 最新稳定版,支持 Node.js API
文件系统 Node.js fs / path 读取、写入、删除、创建文件夹
MD 渲染 marked.js Markdown 解析为 HTML
UI 样式 Tailwind CSS CDN 快速美化界面,轻量灵活
本地存储 localStorage 保存上次浏览路径或用户偏好

💡 Electron 特点:主进程负责系统资源访问(文件、托盘、菜单等),渲染进程负责 UI 与交互逻辑。两者通过 IPC 通信协作完成任务。


三、项目结构

file-manager/
├── main.js             # 主进程:窗口创建、菜单、IPC 通信
├── index.html          # 渲染进程:UI 界面
├── renderer.js         # 前端逻辑:文件浏览、搜索、MD 预览
├── styles.css          # 自定义样式
├── package.json
└── README.md

四、完整代码实现

1. package.json
{
  "name": "file-manager",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "devDependencies": {
    "electron": "^28.0.0",
    "marked": "^9.0.0"
  }
}

2. main.js —— 主进程(窗口 + 文件操作 IPC)
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
const fs = require('fs');
const path = require('path');

let mainWindow;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js')
    }
  });

  mainWindow.loadFile('index.html');
  mainWindow.on('closed', () => (mainWindow = null));
}

app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

// IPC 监听:读取文件夹
ipcMain.handle('read-dir', async (_, dirPath) => {
  try {
    const files = await fs.promises.readdir(dirPath, { withFileTypes: true });
    return files.map(f => ({
      name: f.name,
      isDirectory: f.isDirectory()
    }));
  } catch (err) {
    return { error: err.message };
  }
});

// IPC 监听:读取 MD 文件内容
ipcMain.handle('read-file', async (_, filePath) => {
  try {
    const content = await fs.promises.readFile(filePath, 'utf-8');
    return { content };
  } catch (err) {
    return { error: err.message };
  }
});

⚡ 注意:这里使用了 preload.js 做安全的渲染进程访问 Node API,避免直接启用 nodeIntegration


3. preload.js —— 安全桥接
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('api', {
  readDir: (dirPath) => ipcRenderer.invoke('read-dir', dirPath),
  readFile: (filePath) => ipcRenderer.invoke('read-file', filePath)
});

4. index.html —— UI 界面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>鸿蒙桌面文件管理器</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 font-sans h-screen flex">
  <div class="w-1/3 border-r border-gray-300 p-4">
    <input type="text" id="dirInput" placeholder="输入路径或选择文件夹" 
           class="w-full p-2 rounded mb-2"/>
    <button id="browseBtn" class="bg-blue-500 text-white px-4 py-2 rounded w-full mb-2">浏览</button>
    <ul id="fileList" class="space-y-1 overflow-auto h-[80vh]"></ul>
  </div>
  <div class="w-2/3 p-4 overflow-auto" id="filePreview">
    <h1 class="text-xl font-bold mb-2">文件预览</h1>
    <div id="previewContent" class="prose max-w-none"></div>
  </div>
  <script src="renderer.js"></script>
</body>
</html>

5. renderer.js —— 核心逻辑
const fileList = document.getElementById('fileList');
const previewContent = document.getElementById('previewContent');
const dirInput = document.getElementById('dirInput');
const browseBtn = document.getElementById('browseBtn');

// 显示文件夹内容
async function loadDir(dirPath) {
  const res = await window.api.readDir(dirPath);
  if (res.error) return alert(res.error);

  fileList.innerHTML = '';
  res.forEach(f => {
    const li = document.createElement('li');
    li.textContent = f.name;
    li.className = 'cursor-pointer p-1 hover:bg-gray-200 rounded';
    li.onclick = () => {
      if (f.isDirectory) {
        dirInput.value = path.join(dirPath, f.name);
        loadDir(dirInput.value);
      } else if (f.name.endsWith('.md')) {
        loadMDFile(path.join(dirPath, f.name));
      }
    };
    fileList.appendChild(li);
  });
}

// 加载 MD 文件
async function loadMDFile(filePath) {
  const res = await window.api.readFile(filePath);
  if (res.error) return alert(res.error);

  previewContent.innerHTML = marked.parse(res.content);
}

// 浏览按钮
browseBtn.onclick = () => {
  loadDir(dirInput.value);
};

五、运行与打包

在这里插入图片描述

开发运行
npm install
npm start
打包为可执行文件(可选)
npm install -g electron-packager
electron-packager . FileManager --platform=win32 --arch=x64 --out=dist

六、功能亮点

功能 说明
📁 文件浏览 支持本地文件夹结构浏览
📄 MD 文件预览 渲染 Markdown 文件内容
🔍 路径搜索 可输入路径快速定位
拖拽与交互 拖拽文件夹或文件,交互体验流畅
💾 本地缓存 保存上次浏览目录,提升体验

七、扩展建议

  • 支持多标签页浏览不同文件夹
  • 集成右键菜单(新建文件/文件夹、删除、重命名)
  • 增加文件搜索与过滤功能
  • 自定义主题(深色/浅色模式)
  • 支持 PDF 或图片预览

在这里插入图片描述

八、结语

通过这个项目,你不仅学会了如何用 Electron 访问本地文件系统,还掌握了主进程与渲染进程通信、UI 渲染与交互、Markdown 文件处理等关键技能。这个鸿蒙桌面文件管理器是一个实用且可扩展的桌面应用原型。

技术即生产力,实践即成长

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐