【vue CLI + electron】設定 preload.js,但 production 找不到 preload.js 的解法

因為要把網頁包成 desktop,所以用了electron

不過因為公司產品有自己的 title bar 的設計,所以我的預設外框是設成 false。那麼,我需要讓user點擊 vue component 裡的某個按鈕,然後 call 到 background.js 裡的 electron method,把 app 關閉




一、首先先架 electron

我的 vue + electron 配置照這份文件走:

重點在於
1. background.js 當 electron mine process
2. vue.config.js 設定 electronBuilder 這邊沒遇到問題

二、嘗試讓 vue component 使用 background.js 裡的 electron methods

最早的想法是在 vue component 裡 import electron 的 ipcRenderer。結果大失敗
後來爬了一些文,決定用一個 preload.js 把 ipcRenderer 預存到全域範圍裡。
這樣在 vue component 裡,用 window.ipcRenderer 就可以使用 electron ipcRenderer的功能

但這邊關於 background.js 裡的 preload 路徑卡了一陣,遇到各種問題。

最終寫法

先講講最後成功的配置:
  • preload.js 放在 public 裡。內容很簡單 window.ipcRenderer = require('electron').ipcRenderer;
  • background.js,new BrowserWindow 的 webPreference 配置寫成
webPreference: {
nodeIntegration: process.env.ELECTRON_VODE_INTEGRATION,
preload: path.join(app.getAppPath(), 'preload.js')
}

記得文件裡要先 const path = require('path')
如果有照上面的文件配置,nodeIntegration 會是 false,這在 vue.config.js 設定

這個最終寫法,是參考: Do not enable Node.js Integration for Remote Content

踩坑過程

一開始,直接在 vue component import 會失敗,是因為 electron 有根 node 整合過,佔據了一些命名。包起來後,nodeIntegration 設成 false,就不讓你用 node.js 裡的功能了 參見我不能在 Electron 裡用 jQuery/RequireJS/Meteor/AnguarJS〉

面對這個無法在 vue 裡使用 electron ipcRenderer 的狀況,網路上王道解法是用 preload.js,在其他東西跑起來之前先把 ipcRenderer 叫出來命另一個名稱。這樣在 vue 裡使用,就是用這個東西,而不是寄望無法被 import 的原本的 ipcRenderer 這時候,最容易找到的教學:https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/guide.html#preload-files

這個教學的配置重點是
  • preload.js 放在 src裡
  • webPreference 的 preload 設定是 path.join(__dirname, 'preload.js')

坑一:path.join(__dirname, 'preload.js')拿不到東西

我照這配置跑dev serve,preload並沒有執行。路徑撈出來一看,__dirname/preload.js 實際上是“project/electron_dist/preload.js”,不過若實際開專案資料夾,其實 electron_dist 裡還有一個 bundled ,寫在 vue 專案的內容應該都在這裡面

坑二:preload 路徑拿到東西,但並不是electron實際包起來後的正確路徑

後來參考了這位先生的寫法electron初探问题总结,用 process.cwd(),代替__dirname,改寫成 preload: path.join(process.cwd(), 'src/preload.js')

跑electron:serve 後果真拿到的東西,但這完全是錯的。因為這個 src/preload.js 完全就是開發時寫的那個檔案,根本不會出現在最後 build 出來的 production 裡。當然,跑了 electron:build 把 app 開起來,一點反應都沒有。跟這個 preload path 輾轉搞了2天,最後才照上面方式解決

三、其他小坑

如果 vue router 壞了的話,記得把 router/index.js 裡的 mode 改掉 ,詳見:Common Issues


留言

  1. 您好,按照你的写法我好想还是加载不出来

    回覆刪除
    回覆
    1. 抱歉,平常很少來看blog,希望您已經順利解決了
      有報錯之類的嗎?

      刪除

張貼留言