最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Electron: Unable to load preload script: Resourcesapp.asarsrcpreload.js - Stack Overflow

programmeradmin1浏览0评论

I have an electron app that builds and runs in development, but when packaging the app with electron-builder, the preload script is not packaged in the right location.

This is a well documented issue and there are very similar questions here and here for example, but none of the replies or solutions are working in my case.

From my electron.js file:

function createWindow() {
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(app.getAppPath(), 'src/preload.js'),
            contextIsolation: true,
        },
    });

    // In production, set the initial browser path to the local bundle generated
    // by the Create React App build process.
    // In development, set it to localhost to allow live/hot-reloading.
    const appURL = app.isPackaged
        ? url.format({
            pathname: path.join(__dirname, 'index.html'),
            protocol: 'file:',
            slashes: true,
        })
        : 'http://localhost:3000';
    mainWindow.loadURL(appURL);

    mainWindow.webContents.openDevTools();
}

My preload script:

const { contextBridge, shell } = require('electron')

contextBridge.exposeInMainWorld(
    'electron',
    {
        openBrowserWindow: (url) => shell.openExternal(url)
    }
)

And my Electron app package.json:

    "build": {
        "extends": null,
        "appId": ".app",
        "productName": "App",
        "directories": {
            "output": "dist"
        },
        "mac": {
            "target": {
                "target": "pkg",
                "arch": [
                    "universal"
                ]
            },
            "darkModeSupport": "true",
            "extendInfo": "app"
        },
        "pkg": {
            "installLocation": "/Applications",
            "overwriteAction": "upgrade"
        },
        "files": [
            "**",
            "../app/src/*",
            "src/preload.js"
        ],
        "extraResources": [
            "../app/src/*",
            "src/preload.js"
        ],
        "extraFiles": [
            "../app/src/*",
            "src/preload.js"
        ]
    }

Above I have tried to make sure the "src/preload.js" file is copied over in different ways, but I still get the error:

Unable to load preload script: ...app/Contents/Resources/app.asar/src/preload.js

Error: Cannot find module '...app/Contents/Resources/app.asar/src/preload.js'

The preload script is in fact copied over, but it is not part of the app.asar file. It is copied in to a src folder outside of the Resources folder which contains the app.asar file:

How do I correctly configure electron-builder so this file is in the right location and can be accessed at package runtime?

I have an electron app that builds and runs in development, but when packaging the app with electron-builder, the preload script is not packaged in the right location.

This is a well documented issue and there are very similar questions here and here for example, but none of the replies or solutions are working in my case.

From my electron.js file:

function createWindow() {
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(app.getAppPath(), 'src/preload.js'),
            contextIsolation: true,
        },
    });

    // In production, set the initial browser path to the local bundle generated
    // by the Create React App build process.
    // In development, set it to localhost to allow live/hot-reloading.
    const appURL = app.isPackaged
        ? url.format({
            pathname: path.join(__dirname, 'index.html'),
            protocol: 'file:',
            slashes: true,
        })
        : 'http://localhost:3000';
    mainWindow.loadURL(appURL);

    mainWindow.webContents.openDevTools();
}

My preload script:

const { contextBridge, shell } = require('electron')

contextBridge.exposeInMainWorld(
    'electron',
    {
        openBrowserWindow: (url) => shell.openExternal(url)
    }
)

And my Electron app package.json:

    "build": {
        "extends": null,
        "appId": ".app",
        "productName": "App",
        "directories": {
            "output": "dist"
        },
        "mac": {
            "target": {
                "target": "pkg",
                "arch": [
                    "universal"
                ]
            },
            "darkModeSupport": "true",
            "extendInfo": "app"
        },
        "pkg": {
            "installLocation": "/Applications",
            "overwriteAction": "upgrade"
        },
        "files": [
            "**",
            "../app/src/*",
            "src/preload.js"
        ],
        "extraResources": [
            "../app/src/*",
            "src/preload.js"
        ],
        "extraFiles": [
            "../app/src/*",
            "src/preload.js"
        ]
    }

Above I have tried to make sure the "src/preload.js" file is copied over in different ways, but I still get the error:

Unable to load preload script: ...app/Contents/Resources/app.asar/src/preload.js

Error: Cannot find module '...app/Contents/Resources/app.asar/src/preload.js'

The preload script is in fact copied over, but it is not part of the app.asar file. It is copied in to a src folder outside of the Resources folder which contains the app.asar file:

How do I correctly configure electron-builder so this file is in the right location and can be accessed at package runtime?

Share Improve this question asked Nov 30, 2021 at 19:58 Mr. RobotMr. Robot 1,8449 gold badges37 silver badges95 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 2

If you do:

const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
        preload: path.resolve(app.getAppPath(), 'preload.js'),
        contextIsolation: true,
    },
});

Does it works ? (worked for me with electron-webpack and electron-builder)

        preload: path.join(app.getAppPath(), 'src/preload.js'),

As you are not packaging the preload.js into the app package file (asar default), this won't work like this. app.getAppPath() will indicate the app package file(or directory, in case you are setting asar as false)

Your code is indicating /xxx.app/Contents/Resources/app.asar/src/preload.js or /xxx.app/Contents/Resources/app/src/preload.js Your preload script file is not there but in the 2nd parent's directory.

So here is the correct path in your case,

path.join(app.getAppPath(), '..', '..', 'src', 'preload.js');

First, add console logs for testing.

console.log({dirname: __dirname})
console.log({getAppPath: app.getAppPath()})
console.log({resourcesPath: process.resourcesPath})

const mainWindow = new BrowserWindow({ ... })

Second, you have to add contextIsolation: true.

If you are using electron-builder and for some reason you cannot add contextIsolation: true you can use this workaround:

package.json

  "build": {
    ...
    "extraResources": [
      ...
      "app/preload.js" // <---- add your path
    ],
  }

electron.js

const preloadPath =
      process.env.NODE_ENV === 'development'
        ? path.join(__dirname, '../preload.js') // <---- add your path
        : path.join(process.resourcesPath, '/app/preload.js'); // <---- add your path

const mainWindow = new BrowserWindow({
      ...
      webPreferences: {
        contextIsolation: false,
        preload: preloadPath,
        ...
      }
})

What is path.join(process.resourcesPath, '/app/preload.js') ?

After building your app you can find your extra resources here

C:\Users\<user>\AppData\Local\Programs\<app>\resources - for Windows.

For MacOS you can right click on your app and click on Show Package Contents > Resources

I solved this problem by adding "preload.js" directly to the build -> files list in my package.json - I don't know why that was necessary since it already had "*.json" in it but it fixed the problem for me.

发布评论

评论列表(0)

  1. 暂无评论