Библиотека Electron проста в использовании для нативных настольных приложений со знанием веб-технологий. Если вы новичок в Electron и нуждаетесь в представлении, ознакомьтесь с этой статьей .
В этой статье мы собираемся создать собственный файловый менеджер с возможностью просмотра нескольких папок или файлов одновременно. Мы будем использовать TypeScript поверх библиотеки Electron.
Начиная
Мы можем начать с проекта шаблона из этого репозитория github. Просто клонируйте проект и выполните следующие команды:
npm install   npm start 
Это запустит наше приложение и отобразит окно браузера, в котором отображаются версии Node и Electron, которые у нас работают.
Теперь мы добавим кнопку для открытия диалогового окна собственных папок и кнопку ввода для отображения выбранных папок и файлов ( index.html ).
HTML
1
<label class="padding20">Folders: </label>
2
<input id="selectedfolders" class="inputtextwidth" type="text" 
3
          placeholder="Selected folders paths displayed here.." disabled>
4
<button class="inlinedisplay margin20" id="folderchooser">Choose folder to list files</button>
  
 
В renderer.ts у нас есть обработчик кнопок для отправки канала ipcRenderer.
JavaScript
xxxxxxxxxx
1
    btn.addEventListener("click", (ev: Event) => {
2
        ipcRenderer.send("showFolderDialog");
3
    });
Вам также может понравиться:
что такое электрон и почему мы должны его использовать?
В main.ts , то showfolderdialogканал слушал , а затем открыл диалог. Диалог будет предоставлен Electron, который имеет свойства как openfile и opendirectory  с несколькими вариантами выбора. 
Затем, когда обещание выполняется, мы получаем пути к выбранным файлам, которые отображают путь к файлу для чтения каталога и получают все файлы внутри каталога. Это, мы снова отправляем в reduceфункцию, чтобы получить статистику файлов. Он отправит файлы со статистикой, отправленной через канал filelist.
Функция Reduce состоит в том, чтобы объединить все файлы разных папок в один список.
Мы также отправляем пути к файлам отдельно, отправляя selectedfoldersдля отображения пути к папкам в поле ввода.
 
JavaScript
xxxxxxxxxx
1
  ipcMain.on("showFolderDialog", (event: IpcMainEvent) => {
2
    let fileSelectionPromise = dialog.showOpenDialog({properties: ["openFile", "openDirectory", "multiSelections"]});
3
    fileSelectionPromise.then(function(obj) {
4
        event.sender.send("selectedfolders", obj.filePaths);
5
        let cumfileslist = obj.filePaths.map((filePath, index)=>{
6
          return fs.readdirSync(filePath, {withFileTypes: true})
7
                   .filter(dirent=>!dirent.isDirectory())
8
                   .map(dirent=>filePath + "/" + dirent.name);
9
        }).reduce((filesacc, files) => {
10
            filesacc = filesacc.concat(files);
11
            return filesacc;
12
        }).every((absolutefilepath, index, array) => {
13
          let stats:fs.Stats = fs.statSync(absolutefilepath);
14
          event.sender.send("fileslist", path.basename(absolutefilepath), stats);
15
          return true;
16
        });
17
    });
18
  });
19
В renderer.ts ,   selectedfoldersиспользуются для создания слушателя событий , чтобы получить все пути к файлам , а затем объединить их с символом трубы и поместить его в значении.
xxxxxxxxxx
1
ipcRenderer.on("selectedfolders", (evt: IpcRendererEvent, selectedfolders: string[]) => {
2
    const selectedFolderElem: HTMLInputElement = document.getElementById("selectedfolders") as HTMLInputElement;
3
    selectedFolderElem.value = selectedFolderElem.value !== "" ? selectedFolderElem.value + "|"
4
                                                            : selectedFolderElem.value ;
5
    selectedFolderElem.value += selectedfolders.join(" | ");
6
});
7
  
 
Чтобы получить список всех файлов, у нас может быть ulэлемент и элемент шаблона, который можно развернуть для каждого отображения файла.
xxxxxxxxxx
1
<div>
2
      <ul id="filelist" class="nopadding">
3
      </ul>
4
    </div>
5
    <template id="filerec">
6
      <div class="row">
7
          <li class="grid-container">
8
              <span></span>
9
              <span>234234</span>
10
              <span>234</span>
11
          </li>
12
      </div>
13
    </template>
  
 
В renderer.ts он прослушивает   filelistэлемент, который получает параметры (имя файла, статистика) и заполняет все элементы диапазона шаблона. Затем шаблон клонируется и добавляется к ulэлементу.
JavaScript
xxxxxxxxxx
1
ipcRenderer.on("fileslist", (event: IpcRendererEvent, fileName: string, stats: fs.Stats) => {
2
    const filetemplate = document.getElementById("filerec") as HTMLTemplateElement;
3
    const filedisplayrec = filetemplate.content;
4
    const spanElements = filedisplayrec.querySelectorAll("span");
5
    spanElements[0].innerText = fileName;
6
    spanElements[1].innerText = stats.size.toString();
7
    spanElements[2].innerText = stats.mtime.toString();
8
    const nodeElement: Node = filedisplayrec.cloneNode(true);
9
    document.getElementById("filelist").appendChild(nodeElement);
10
});
11
  
 
Настольное приложение наконец-то будет выглядеть так. Полный исходный код доступен на github для справки .