модуль fs не работает при интеграции Electron в проект Angular

У меня проблемы с интеграцией Electron. Когда я использую его, как описано в этой записи в блоге, все работает. Проблемы начинаются, когда я хочу использовать import Electron (electron.remote), чтобы использовать его в службе Angular2, чтобы приложение могло использовать функции рабочего стола, такие как системные диалоги и доступ к файловой системе.

Я получаю следующую ошибку при загрузке приложения в electron/index.js, которое включено в комплект веб-пакета:

Uncaught TypeError: fs.existsSync is not a function (index.js:6)

Файл выглядит довольно просто:

var fs = require('fs')
var path = require('path')

var pathFile = path.join(__dirname, 'path.txt')

if (fs.existsSync(pathFile)) {
module.exports = path.join(__dirname, fs.readFileSync(pathFile, 'utf-8'))
} else {
throw new Error('Electron failed to install correctly, please delete node_modules/' + path.basename(__dirname) + ' and try installing again')
}

//////////////////
// WEBPACK FOOTER
// ./~/electron/index.js
// module id = 609
// module chunks = 2

Самое забавное здесь то, что другой встроенный модуль path не имеет проблем в том же фрагменте кода. Когда я смотрю в инструменты разработчика электронного приложения, я вижу ожидаемые методы path, а также два статических свойства (разделители). Но когда я смотрю, что такое объект fs, я вижу, что это просто пустой Object с прототипом, соответствующим NodeJS 6.

Я импортирую электронный API в сервисный файл Angular service.ts, который очень тривиален:

import * as electron from 'electron' ;
import {Injectable} from '@angular/core' ;

@Injectable()
export class Electron {
getRemote(): any { return electron.remote ; }

Однако он никогда не вызывается, а только импортируется в app.module.ts. Я создал его только для того, чтобы увидеть возможные ошибки компиляции.

Что касается среды, я установил typings в devDependencies, а затем установил dt~node и dt~electron (в typings/global/electron/index. .d.ts есть некоторая проблема в том, что tsc не распознает Promise‹any›, который мне пришлось вручную заменить на any, чтобы сделать возможна компиляция электронного основного файла).

Пока я не хочу использовать электронный API (electron.remote), все работает нормально, с некоторыми незначительными причудами в angular, не относящимися к этой теме. Но как только я пытаюсь импортировать электрон, я получаю эту странную ошибку.

Любая идея, как преодолеть это или где искать причину? Почему один встроенный модуль nodejs, путь, импортируется без проблем, но в том же файле require() другого встроенного модуля, fs, возвращает что-то, что не является fs?

Версии (process.versions в процессе рендерера):

ares:"1.10.1-DEV"
atom-shell:"1.4.14"
chrome:"53.0.2785.143"
electron:"1.4.14"
http_parser:"2.7.0"
modules:"50"
node:"6.5.0"
openssl:"1.0.2h"
uv:"1.9.1"
v8:"5.3.332.47"
zlib:"1.2.8"

Версия NodeJS, в которой я выполняю компиляцию, — 6.9.3 x64 Windows.


person Jindrich Vavruska    schedule 21.01.2017    source источник
comment
У меня такая же проблема, ты что-то понял?   -  person EdoB    schedule 02.02.2017
comment
@EdoB, мы только что начали какой-то большой проект, и у меня не было много времени, чтобы поиграть с ним. Тем не менее, я использовал стартер, который работает для разных конфигураций angular 2 (dev-сервер, prod-сервер, электронное приложение), и он работает. API electron.remote еще не проверял. github.com/JonnyBGod/angular2-webpack-advance-starter   -  person Jindrich Vavruska    schedule 05.02.2017
comment
@EdoB протестирован и не прошел: та же проблема, когда я добавляю import remote from 'electron' ; - очевидно, в электронном пакете есть какая-то ошибка, которая приводит к сбою преобразователя модуля в fs.   -  person Jindrich Vavruska    schedule 05.02.2017
comment
Тоже с такой же проблемой. Кто-нибудь понял, в чем проблема?   -  person Karel-Jan    schedule 03.03.2017
comment
Возможный дубликат ` __webpack_require__(...) не функция` при использовании babel 6   -  person Matthias Sommer    schedule 15.08.2017


Ответы (1)


Как указал @ccnokes в этот ответ:

Webpack привносит свой собственный запрос, который требует clobbers node.js, поэтому, когда вам требуется основной модуль node.js, который webpack не может преобразовать в один из ваших файлов или зависимостей, он бросает. (Вы можете видеть в трассировке стека, что он включает webpack_require. Это потому, что webpack переписывает все требования в webpack_require, чтобы использовать собственную внутреннюю систему node.js-esque). Webpack создан для Интернета/браузеров, поэтому он не очень хорошо работает с узлом из коробки.

Я бы предложил использовать ngx-electron, который, похоже, несколько не поддерживается (последний коммит был год назад), но все еще работает как шарм и позволит вам использовать множество возможностей Electron в Angular (например, в комментарии к этому ответу ).

Вы также можете попробовать это временное решение от Векослав Раткаец:

В вашем index.html

<script>  const electron = require('electron');  </script>

Затем в любом из ваших файлов Typescript:

declare const electron: any;

Недостатком является то, что вам не понравится поддержка Typescript.

Вы также можете использовать webpack-target-electron-renderer, чтобы указать, что требуется импортировать с помощью электрона или веб-пакета, но я не пробовал его или этот шаблон, если Вы хотите начать свой проект с нуля!

Надеюсь, это поможет

person PaulCo    schedule 22.05.2018