コツコツとelectronでデスクトップアプリを作って1ヶ月、やっと形になったので動作を確認してみようとパッケージングをしたらメインウィンドウでボタンを押すとサブウィンドウが開くという部分がうまく動かなかったのでゴチャゴチャいじっていたらBrowswerwindowの理解が深まったので書き残しておこうという記事。
たぶんアプリをリリースしたことのある人には当たり前のことだと思うのでほぼ自分用です。
追記
アプリをMacのアップストアーでリリースしたのでよかったらみてみてください↓
https://apps.apple.com/jp/app/%E3%81%8A%E3%81%A4%E3%81%BE%E3%81%BF/id1549128084?mt=12
##環境
vue-cli-plugin-electron-builderをインストールしてvue-routerを使ってます。
##本編
メインウィンドウの元はほぼこんな感じのコードで
let win;
async function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 900,
height: 800,
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
}
});
win.maximize();
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
if (!process.env.IS_TEST) win.webContents.openDevTools();
// await transparentWnd.loadURL(process.env.WEBPACK_DEV_SERVER_URL+"/#/transparent");
} else {
createProtocol("app");
// Load the index.html when not in development
win.loadURL("app://./index.html");
}
}
サブウィンドウもこれ真似すればいいやとこんな感じのコードにしました。
let transparentWnd;
var is_showing = false;
ipcMain.handle("open-sub", (event, data, id, time, screenSize) => {
async function createTransparentWindow() {
transparentWnd = new BrowserWindow({
width: 930,
height: 610,
x: 100,
y: 150,
transparent: true,
hasShadow: false,
alwaysOnTop: true,
webPreferences: {
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
preload: `${__dirname}/preload.js`
}
});
if (process.env.WEBPACK_DEV_SERVER_URL) {
await transparentWnd
.loadURL(process.env.WEBPACK_DEV_SERVER_URL + "/#/transparent");
transparentWnd.webContents.send("comments", data, id, time);
;
if (!process.env.IS_TEST) transparentWnd.webContents.openDevTools();
} else {
transparentWnd.loadURL("app://./index.html");
})
}
transparentWnd.on("close", () => (is_showing = false));
}
if (is_showing === false) {
createTransparentWindow();
if (screenSize == "FullScreen") {
transparentWnd.maximize();
}
is_showing = true;
}
});
しかしこのままだとnpm run electron:serveでは正常なのに、 electron:buildでパッケージングしたアプリだとウィンドウは開くけどコンテンツが表示されませんでした。
###原因と解決方法
原因は if (process.env.WEBPACK_DEV_SERVER_URL)・・・の部分で、ここはおそらく「develepmentのときはif、それ以外(本番)のときはelseを読み込むよ」という意味なのでelectron:serveのときは"/#/transparent"を読み込んでいるけどパッケージングしたあとは"./index.html"を読み込んでしまっていたということです。
なのでelseの部分を
if (process.env.WEBPACK_DEV_SERVER_URL){
...
}
else{
await transparentWnd.loadURL("app://./index.html/#/transparent").then(()=>{
transparentWnd.webContents.send("comments", data, id, time);
})
}
とすることでelectron:serveのときと同じ期待通りの動きにすることができました!!