Angular 4 + Electron - 如何运行应用程序并监视更改(实时重载)

8

我正在使用 Angular 4 创建一个 Electron 应用程序。如何设置它以便它可以监视任何更改和实时重新加载。

package.json

{
  "name": "angular-electron",
  "version": "0.0.0",
  "license": "MIT",
  "main": "main.js",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "electron": "electron .",
    "electron-build": "ng build --prod && electron ."
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.2.4",
    "@angular/common": "^4.2.4",
    "@angular/compiler": "^4.2.4",
    "@angular/core": "^4.2.4",
    "@angular/forms": "^4.2.4",
    "@angular/http": "^4.2.4",
    "@angular/platform-browser": "^4.2.4",
    "@angular/platform-browser-dynamic": "^4.2.4",
    "@angular/router": "^4.2.4",
    "angular-svg-round-progressbar": "^1.1.0",
    "bulma": "^0.5.3",
    "core-js": "^2.4.1",
    "rxjs": "^5.4.2",
    "zone.js": "^0.8.14"
  },
  "devDependencies": {
    "@angular/cli": "1.4.1",
    "@angular/compiler-cli": "^4.2.4",
    "@angular/language-service": "^4.2.4",
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "~3.1.1",
    "electron": "^1.7.6",
    "electron-packager": "^9.1.0",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.2.0",
    "tslint": "~5.3.2",
    "typescript": "~2.3.3"
  }
}

电子(electron)
const { app, BrowserWindow } = require('electron')

let win;

function createWindow () {
  // Create the browser window.
  win = new BrowserWindow({
    width: 600, 
    height: 600,
    backgroundColor: '#ffffff',
    icon: `file://${__dirname}/dist/assets/logo.png`
  })

  win.loadURL(`file://${__dirname}/dist/index.html`)

  //// uncomment below to open the DevTools.
  // win.webContents.openDevTools()

  // Event when the window is closed.
  win.on('closed', function () {
    win = null
  })
}

// Create window on electron intialization
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function () {

  // On macOS specific close process
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  // macOS specific close process
  if (win === null) {
    createWindow()
  }
})

谢谢。

目前,我每次使用以下命令构建我的应用程序:

ng build --prod && electron .

这样做会很繁琐,因此我希望能够构建并运行一个命令,以便它可以监视更改并进行实时重新加载。


1
你能否将 --watch 添加到构建命令 'ng build --watch --prod && electron .' 中? - mrdeleon
6个回答

2
你可以使用 electron-reload 实现热模块重载。它会监听文件变化并重新加载 electron 应用程序。
只需将其添加到 package.json 的 devDependencies 中即可。
然后,您需要将其添加到 main.ts 中:
import { app, BrowserWindow, Menu } from 'electron';

let win, serve;
const args = process.argv.slice(1);
serve = args.some(val => val === '--serve');

if (serve) {
  require('electron-reload')(__dirname, {});
}

请在您的 package.json 中添加一个命令。
"start": "webpack --watch",
"serve": "npm run build:main && electron ./dist --serve",
"build:main": "tsc main.ts --outDir dist && copyfiles package.json dist && cd dist && npm install --prod"

这里的build:main是编译项目的构建脚本。它会将所有Typescript文件编译并放入dist文件夹中。之后,它会运行npm install从NPM下载并安装模块。

为了运行它,您需要使用模块打包工具Webpack。使用以下命令进行安装:

npm install --save-dev webpack

首先,在控制台中运行npm start。然后,在第二个控制台中执行npm run serve。现在,它会监听变化并在文件更改时重新编译。
tsc代表TypeScript编译器。如果您正在使用tsc作为节点模块,请确保已安装:
npm install -g typescript

目前我正在使用它为一个具有相同设置的项目(Angular 4,Electron),并且它完美运行。


嘿,你能提供一下你的 package.json 文件的片段吗,这样我就可以清楚地看到它了,包括 build:main。而且我也对 ./dist 文件夹感到困惑,因为我在我的应用程序中没有这个文件夹。 - Kay
我再次尝试了一下,但是在你的npm start中,你正在执行webpack --watch。但是你没有提供有关你的webpack的信息... - Kay
@MatthiasSommer,我尝试了您的指示,但像KHAN所说的那样,当我运行第一个nom start时,我已经收到有关web pack的错误消息... - GY22
你的 devDependencies 中有 webpack 吗?例如 "webpack": "3.8.1" - Matthias Sommer
仅供参考,我从未使其工作。我刚开始使用 ng serve --watch 在浏览器中,并偶尔进行构建以检查电子。您在 Chrome 中看到的内容通常会在电子窗口中看到。 - user1829348
显示剩余8条评论

1
我个人非常不喜欢互联网上的其他答案。我选择做一些更加离经叛道的事情。我只使用原始的Angular进行所有开发,并为需要电子设备(如共享桌面或从某个地方获取配置文件)的应用程序部分提供存根。
if (!this.electron.isElectronApp) {
  return {
    config:data,
    more:data,
  }
} else {
  do electron things
}

到目前为止,它一直运作得非常好。如果有人认为这将在以后对我造成麻烦,请分享。


1

首先,我们需要了解实际上被问到的问题是什么。关于使用 Angular 和实时重新加载的 Electron,有两个问题如下:

  1. 如何在 Build 更改时重新加载 Electron
  2. 如何在 Source 更改时重新加载 Electron

现在,当我在寻找答案时,我实际上是在寻找问题2的答案,但是我得到的是问题1的答案。对我来说非常混乱,没有清晰的答案。因此,让我们消除这种困惑,我将回答问题2。

如何在 Source 更改时重新加载 Electron

很明显,当我们开发 Angular 应用程序时,我们运行 ng serve 命令,TS 编译为 JS 并放入内存中,并从内存中提供服务,而不是从磁盘(当我们创建构建时)。

因此,要使用该 内存源 进行 实时电子重新加载,请执行以下操作:

安装 electron-reloader

npm install electron-reloader --save-dev

将其添加到 main.js 文件中:

require('electron-reload')(__dirname, {
  electron: path.join(__dirname, 'node_modules/.bin/electron')
});

在一个终端中使用ng serve运行Angular应用程序,您将获得类似于http://localhost:4200的地址。

在另一个终端中运行electron,为此在您的package.json脚本文件中添加"electron": "electron ."并运行node electrone

现在,在main.js中将本地地址提供给mainWindow.loadURL()作为字符串。

现在,每当您进行更改时,您的electron应用程序都会重新加载,并且这将为您提供与在浏览器上运行Angular应用程序时相同的重新加载体验。


1
使用以下命令可以使用ng serve来启动应用程序,这样可以更快地进行开发,并在代码发生更改时自动重新加载。
安装electron-reloaderconcurrently
npm install --save-dev electron-reloader concurrently

在你的 main.js 中初始化 electron reloader 并从 URL 加载应用程序(我们这样做是因为应用程序是通过本地开发服务器从内存中提供的,而不是物理路径上的)
try {
  require('electron-reloader')(module)
} catch {}

//...

mainWindow.loadURL("http://localhost:4200/")

最后使用concurrently同时运行ng serveelectron .
"electron-dev": "concurrently \"ng serve\" \"electron .\""

你应该能够看到一个空的 Electron 应用窗口,但一旦开发服务器准备好,你可以按下 Ctrl+R 或者改变代码中的某些内容来查看你的应用。从现在开始,对代码的任何更改都会强制应用重新加载,就像你在浏览器上工作一样。

0
我使用以下解决方案(其中部分来自互联网)- 用于在Windows 11上使用angular: 13electron: ^19.0.4

更改后的代码编译

首先,在package.json中,我们使用ng build --watch代码来检测更改并编译代码(我将粘贴我的整个脚本-可能您可以简化它)。

"runElectron": "electron .",
"ngBuildDevHmr": "ng build --watch --configuration dev  --optimization=false --build-optimizer=false",
"hmr": "node electron/edit-package.js --dev && copy config\\env-dev.json electron\\env.json && cd electron && tsc --skipLibCheck && cd .. && npm run ngBuildDevHmr"

我只需在单独的终端中运行npm run hrm,以查看编译器消息。

Electron更新

好的,现在我们在更改后有了新编译的代码 - 但是electron还不知道。因此,它必须检测到新代码的出现 - 我们使用以下库进行此操作:

npm install --save-dev electron-reload

(不要将electron-reload (^2.0.0-alpha.1)与electron-reloader混淆 - 这是单独的项目)

在主电子文件angular\electron\main.ts中,我添加了此代码以检测文件更改(直接在imports部分下面的顶部)

if (!env.production) { 
    require('electron-reload')(
        __dirname+'\\..', // directory for detect changes
        {
            electron: path.join(__dirname+'\\..\\..', 'node_modules', '.bin', 'electron'), // path to electron executable
            hardResetMethod: 'exit' // hard reset after changes detection - you can comment it for better performance
        }
    );
}

可能是electron中包含angular代码的目录被删除并重新创建了 - 因此我们必须检测父目录(__dirname+'\\..')中的更改,同时我们还必须重新加载整个页面(在下面的代码中完成),因为electron将无法访问先前打开(但当前已删除)的文件夹。我使用did-fail-load事件来检测它。

main.ts的中间部分,我获取win = new BrowserWindow(...,我添加了重新加载浏览器的代码:

    if (!env.production) {
        win.webContents.on("did-fail-load", function() {
            win.loadURL(`file:///${__dirname}/../sqar-spaceplan-frontend/index.html`);
        });
    }

最后我在另一个终端中运行 npm run rumElectron


0

你可以同时使用 ng build 和 electron 运行 watch。

"electron": "tsc application/start.ts && concurrently \"ng build --watch  --base-href ./\"  \"devMode=1 electron .\""

同时使用electron-reload,并将其配置为在更改dist文件夹时重新加载。

require('electron-reload')(__dirname);

第一次打开电子窗口时会出现错误,因为尚未生成dist文件夹。完成ng build后,将生成dist文件夹,并且electron-reload将重新加载应用程序。之后,由于--watch的存在,每次更改都会更改dist文件夹,而electron-reload将重新加载应用程序。

相关的npm包

https://www.npmjs.com/package/concurrently

https://www.npmjs.com/package/electron-reload


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接