動態

詳情 返回 返回

electron-build報錯:cannot find module/ valid " main " entry - 動態 詳情

解決electron-build打包後運行app報錯:cannot find module xxx/ Please verify that the package . json has a valid " main " entry

先看一個簡單報錯:

圖片

或者類似這種:

圖片

解決方法:

檢查package. Json 中是否寫了“main”,這裏的“main”必須寫,且應當使用npm指令build的dist-electron文件夾中的main.js

那麼有人會問了:還沒有跑過npm命令呢,沒有dist-electron需要自己構建一個嗎?答案是不需要,見附錄1

//package.json
{
    "name": "DXY 1st",
    "version": "5.3.0",
    "private": true,
    "description": "DXY 666",
    "author": "DXY",
    "license": "MIT",
    "main": "dist-electron/main.js",

既然你已經會修bug了,那我們就來打boss吧(截圖我搞丟了,只剩文字了):

Background:打包已有的vue3工程(vue3自己的main.js被放進electron的main.js裏了),preload.js、renderer.js都用的官網的示例代碼,跑完npm run dev總是出bug,且無法transform main.js

圖片

Unable to find Electron app at D :\…… .Cannot find module ' D :\ …… \ dist - electron \ main . js '. Please verify that the package . json has a valid " main " entry

目前為止我沒找到針對這個bug的貼子,那就讓我來水一貼吧:

檢查並修正 main.js中的導入

打開報錯信息中提到的 D:\……\dist-electron\main.js文件:

//問題代碼main.js

/*先寫electron的app塊兒

*/

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

const path = require('path')

const createWindow = () => {

  const win = new BrowserWindow({

    width: 800,

    height: 600,

    webPreferences: {

      preload: path.join(__dirname, 'preload.js')

    }

  })

  // 開發環境加載 Vite 開發服務器,生產環境加載打包後的文件

  if (process.env.NODE_ENV === 'development') {

    win.loadURL('你的web網址')

  } else {

    win.loadFile('dist/index.html')

  }

    // win.loadFile('index.html')

}



app.whenReady().then(() => {

  ipcMain.handle('ping', () => 'pong')

  createWindow()



  app.on('activate', () => {

    if (BrowserWindow.getAllWindows().length === 0) {

      createWindow()

    }

  })

})



app.on('window-all-closed', () => {

  if (process.platform !== 'darwin') {

    app.quit()

  }

})

/*以下是雜糅在一塊兒的Vue工程main.js代碼

*/

import { createApp } from 'vue'

import { createPinia } from 'pinia'

import * as ElementPlusIconsVue from '@element-plus/icons-vue'

import App from './App.vue'

import router from './router'

/*………*/

查找其中是否有導入 App.vue的部分(不是説某一行import,而是説一整個相關的代碼塊兒),這才是問題的根源,是因為:主進程的代碼不應該直接導入前端組件,主進程文件(如 main.js)和渲染進程文件應被正確區分和管理,所以你首先需要思考你導入它的目的:

如果是為了創建瀏覽器窗口(BrowserWindow)並加載頁面,正確的方式應該是使用 loadFile或 loadURL方法來加載一個已經編譯好的 HTML 文件(如 index.html),而不是直接導入 .vue文件

具體的做法就是:

1.不要直接使用或拼接Vue工程的main.js,應創建獨立的 Electron 主進程文件 electron/main.js:附錄2

2.更新vite.config.ts配置

//vite.config.ts
export default defineConfig({
    base: './',
    plugins: [
        vue(),
        electron({
            main: {
                entry: 'electron/main.js',//更新主入口路徑
            }
  1. 更新 package.json
//package.json
{
    "name": "DXY 1st",
    "version": "5.3.0",
    "private": true,
    "description": "DXY 666",
    "author": "duandashuaige",
    "license": "MIT",
    "main": "dist-electron/main.js",//修改主入口

這個問題高發於electron+vue全家桶場景,即對已有的Vue工程打包,雖然不算是難點,但也很容易被忽略

附錄:

1.新建electron文件夾,並填充main.js,preload.js,然後終端跑npm run dev會報錯:

圖片

同時會自動生成一個dist-electron文件夾,包含兩個js:

圖片

裏面的倆js和之前填充的electron文件夾內的main.js和preload.js的內容是一樣的,但是這倆js是經過編譯的,未經編譯過的文件electron讀不懂,因此一定要先編譯再打包!具體原因可以參考我的另一篇貼子:解決electron打包Vue工程(Vite)報錯electron : Failed to load URL : xxx... with error : ERR _CONNECTION_REFUSED

2.

// electron/main.js

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

const path = require('path')



const createWindow = () => {

  const win = new BrowserWindow({

    width: 1200,

    height: 800,

    webPreferences: {

      preload: path.join(__dirname, 'preload.js')

    }

  })



  // 開發環境加載 Vite 開發服務器,生產環境加載打包後的文件

  if (process.env.NODE_ENV === 'development') {

    win.loadURL('你的web網址')

  } else {

    win.loadFile('dist/index.html')

  }

}



app.whenReady().then(() => {

  ipcMain.handle('ping', () => 'pong')

  createWindow()



  app.on('activate', () => {

    if (BrowserWindow.getAllWindows().length === 0) {

      createWindow()

    }

  })

})



app.on('window-all-closed', () => {

  if (process.platform !== 'darwin') {

    app.quit()

  }

})

3.官網示例代碼4件套,供大家參考:

/*main.js

*/

const { app, BrowserWindow, ipcMain } = require('electron/main')



const path = require('node:path')



const createWindow = () => {

  const win = new BrowserWindow({

    width: 800,

    height: 600,

    webPreferences: {

      preload: path.join(__dirname, 'preload.js')

    }

  })

  win.loadFile('index.html')

}

app.whenReady().then(() => {

  ipcMain.handle('ping', () => 'pong')

  createWindow()

})
/*preload.js

*/

const { contextBridge } = require('electron/renderer')



contextBridge.exposeInMainWorld('versions', {

  node: () => process.versions.node,

  chrome: () => process.versions.chrome,

  electron: () => process.versions.electron

})
/*index.html

*/

<!DOCTYPE html>

<html>

  <head>

    <meta charset="UTF-8" />

    <meta

      http-equiv="Content-Security-Policy"

      content="default-src 'self'; script-src 'self'"

    />

    <meta

      http-equiv="X-Content-Security-Policy"

      content="default-src 'self'; script-src 'self'"

    />

    <title>Hello from Electron renderer!</title>

  </head>

  <body>

    <h1>Hello from Electron renderer!</h1>

    <p>👋</p>

    <p id="info"></p>

  </body>

  <script src="./renderer.js"></script>

</html>
/*renderer.js

*/

const information = document.getElementById('info')

information.innerText = `This app is using Chrome (v${window.versions.chrome()}), Node.js (v${window.versions.node()}), and Electron (v${window.versions.electron()})`

官網:使用預加載腳本 | Electron

user avatar toopoo 頭像 grewer 頭像 alibabawenyujishu 頭像 linlinma 頭像 guochenglong 頭像 nihaojob 頭像 jcguanqi 頭像 yelloxing 頭像 chongdianqishi 頭像 6fafa 頭像 huichangkudelingdai 頭像 qian5201314 頭像
點贊 201 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.