使用Electron和Angular的热钉仓

5hcedyr0  于 2022-12-16  发布在  Electron
关注(0)|答案(8)|浏览(156)

我正在为我的应用程序使用Angular和Electron。我正在寻找一种启用热重载的方法...当我运行我的yarn run electron(脚本:"electron": "ng build --base-href ./ && electron ."),如果我保存更改,我的应用不会重新加载。以下是我的main.js文件:

const { app, BrowserWindow } = require("electron");
const path = require("path");
const url = require("url");

let win;

function createWindow() {
  win = new BrowserWindow({ width: 800, height: 600 });

  // load the dist folder from Angular
  win.loadURL(
    url.format({
      pathname: path.join(__dirname, `/dist/index.html`),
      protocol: "file:",
      slashes: true
    })
  );

  // The following is optional and will open the DevTools:
  // win.webContents.openDevTools()

  win.on("closed", () => {
    win = null;
  });
}

app.on("ready", createWindow);

// on macOS, closing the window doesn't quit the app
app.on("window-all-closed", () => {
  if (process.platform !== "darwin") {
    app.quit();
  }
});

// initialize the app's main window
app.on("activate", () => {
  if (win === null) {
    createWindow();
  }
});

我尝试在main.js文件中包含require('electron-reload')(__dirname);,但没有任何变化

ahy6op9u

ahy6op9u1#

我发现了这个:https://github.com/maximegris/angular-electron这是一个空的项目模板,使用电子和Angular 。执行yarn start允许热重载。它写得很好,在README.md!

owfi6suc

owfi6suc2#

默认情况下,electron-reload只在文件更改时重新加载所有打开的BrowserWindows中的WebContents。如果您想重新启动Electron(iidoEe.如果您想更改Electron主进程文件以重新加载应用程序),那么您要寻找的是“硬重置”。
为此,您必须设置电子应用程序路径,如下所示:

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

documentation说路径应该是./node_modules/.bin/electron,但是我只能使用./node_modules/.bin/electron.cmd来使它工作。这显然是an issue with Windows machines,应该指向MacOS上的可执行文件。在Linux系统上也可能是这样。
下面应该是样板示例所需的所有文件:

./主文件.js

const { app, BrowserWindow } = require('electron')
const path = require('path')
const url = require('url')

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

let mainWindow = null

function main() {
    mainWindow = new BrowserWindow()

    mainWindow.loadURL(
        url.format({
            pathname: path.join(__dirname, '/dist/index.html'),
            protocol: 'file:',
            slashes: true
        })
    )

    mainWindow.on('closed', () => {
        mainWindow = null
    })
}

app.on('ready', main)

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

app.on('activate', () => {
    if (mainWindow === null)  {
        main()
    }
})

./索引.html

<h1>Hello World!</h1>

./包.json

{
    "name": "electron-hot-reload-boilerplate",
    "version": "1.0.0",
    "description": "An Electron Boilerplate demonstrating hot reloading",
    "main": "main.js",
    "scripts": {
        "start": "electron ."
    },
    "repository": "https://github.com/link/to/your/repo",
    "keywords": [],
    "author": "You",
    "license": "CC-BY-SA-3.0",
    "dependencies": {
        "electron": "^3.0.9",
        "electron-reload": "^1.3.0"
    }
}

安装时:

> npm install

运行条件:

> npm start
gzjq41n4

gzjq41n43#

难道app.relaunch()不是执行“硬重置”的方法吗?
app.relaunch([options])

  • options对象(可选)
  • args字符串
  • execPath字符串(可选)

当前示例退出时重新启动应用程序。
默认情况下,新示例将使用与当前示例相同的工作目录和命令行参数。如果指定args,则将args作为命令行参数传递。如果指定execPath,则将执行execPath以重新启动,而不是当前应用程序。
请注意,此方法在执行时不会退出应用,您必须在调用app.relaunch后调用app.quitapp.exit才能重新启动应用。

xxls0lw8

xxls0lw84#

像我一样修改你的代码:
并调用reloadWindow方法。
以下URL:https://electronjs.org/docs/api/browser-window#winreload

const { app, BrowserWindow, ipcMain } = require('electron');
const url = require('url');
const path = require('path');

let mainWindow;
app.on('ready', Start);

function Start() {
  createWindow();
  settingsWindow();
}
function createWindow() {
  mainWindow = new BrowserWindow();
  mainWindow.loadURL(url.format({ pathname: path.join(__dirname, `/dist/index.html`), protocol: 'file:', slashes: true, }));
}
function reloadWindow() {
  mainWindow.reload();
  mainWindow.loadURL(url.format({ pathname: path.join(__dirname, `/dist/index.html`), protocol: 'file:', slashes: true, }));
}
function settingsWindow() {
  mainWindow.maximize();
  mainWindow.setMenu(null);
}
y0u0uwnf

y0u0uwnf5#

这些步骤对我很有效:

  • 使用npm install electron-reload简单安装电子钉仓
  • 将这些行添加到main.js

const electron = require('electron')
require('electron-reload')(__dirname, { electron: require("${__dirname}/node_modules/electron") });

mspsb9vt

mspsb9vt6#

现在已经很晚了,但我认为这将有助于新的人登陆这个页面的问题。
只需替换win.loadFile(“Angular 应用索引文件路径”);具有以下代码

if(env==="PROD"){
   win.loadFile("path to index file of angular app");
}else{      //// Else block is for hot reload in dev mode
   win.loadUrl("http://localhost:4200")
}

在电子主文件中。在这之后运行你的角应用程序与--live-reload选项,然后单独运行电子应用程序或创建一个脚本在package.json如下
ng serve --live-reload && electron .

jv4diomz

jv4diomz7#

我发现最简单的方法是使用electron-reloader,安装后,只需将以下代码粘贴到.js文件的顶部,就可以了:

const { app } = require('electron')

app.isPackaged || require('electron-reloader')(module)
tzxcd3kk

tzxcd3kk8#

完整HMR

下面的解决方案显示了如何设置HMR,将电子重新加载到当前URL中
输入package.json

...
"scripts": {
  "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"
  ...
}
...
"devDependencies": {
  ...
   "electron-reload": "^2.0.0-alpha.1",
}
...

我们运行npm i(不要把electron-reloadelectron-reloader混淆,这两个是独立的库)。

import { BrowserWindow, ipcMain } from 'electron';
...

if (!env.production) { // do it only if we not in production build
    // Hot module replacement - if detect file changes in electron directory then reload it (external tool will delete and create new /dist electron folder after file changes)

    require('electron-reload')(
        __dirname + '\\..', // directory to check (we must go outside ../project dir because it will be deleted and recreated (detection not occure))
        {
            electron: path.join(__dirname + '\\..\\..', 'node_modules', '.bin', 'electron'), // path to electron executable
            //hardResetMethod: 'exit' // hard reset after changes detection
        }
    );
}

// this function will check condition periodically - as long as it's value is not true
const waitUntil = (condition, checkInterval=100) => {
    return new Promise(resolve => {
        let interval = setInterval(() => {
            if (!condition()) return;
            clearInterval(interval);
            resolve(1);
        }, checkInterval)
    })
}

...
app.on('ready', createWindow);
...
function createWindow() {
    let angularIsReady = false;

    win = new BrowserWindow({...});
    ...

    ipcMain.on('appControl', (event, eventType) => {
       if(eventType=="isReady") {
         angularIsReady = true;
       }
       ...
    }

    if (!env.production) {
        win.webContents.openDevTools();

        // Below code is used to jump into old page after HMR (hot module replacement)
        // when directory /dist will be deleted (during code rebuild by external tool) - then this event will be fired (because page will be deattachet from its old /dist directory)
        win.webContents.on("did-fail-load", async function(e) {
            // read current (old) url before page reload
            let previousUrl =  win.webContents.getURL(); 
            
            angularIsReady = false;

            // first we need load index.html from fresh /dist (and wait for angular run)
            win.loadURL(`file:///${__dirname}/../project/index.html`); 
            
            await waitUntil(()=>angularIsReady );

            // when angular is ready, then angular routing works, ang we can set old page url
            win.loadURL(previousUrl);
        });
    }

在文件angular\electron\preload.ts内添加

export type ContextBridgeApi = {
    ...
    appControl: {
        ...
        isReady: () => void; // when angular is loaded and run
    };
    ...
}

const exposedApi: ContextBridgeApi = {
  appControl: {
    ...
    isReady: () => ipcRenderer.send('appControl', 'isReady'),
}

ngOnInitangular\src\app\app.component.ts内部加上
window.electron.appControl.isReady();

如何运行它

在一个终端编译代码后,每次修改,运行
npm run hmr
此命令将重建(删除和创建)angular\dist\project目录。并在第二个终端运行electron by
x1米11米1x
它将自动检测/dist文件夹更改并将其重新加载到当前URL中。

相关问题