Electron: Lokale Ressource darf nicht geladen werden: file://index.html/ nach dem Webpacking von main.js

Erstellt am 10. Apr. 2016  ·  31Kommentare  ·  Quelle: electron/electron

Ich versuche, das gesamte main.js-Skript und seine Abhängigkeiten in einer einzigen Datei zu webpacken (ich möchte eine Datei für die UI-App und eine Datei für die Server-App haben).

Wenn ich die normale Quelle verwende, wird index.html problemlos geladen. Allerdings bekomme ich beim Webpacking den im Titel genannten Fehler.

Hier ist die Webpack-Konfiguration, die ich verwendet habe:

webpack({
    entry: [
        './main'
    ],
    output: {
        path: path.join(__dirname, 'asar'),
        filename: 'main.js',
        libraryTarget: 'commonjs2'
    },
    externals: ['electron'],
    target: 'node'
});

Ich lade die Datei so:
mainWindow.loadURL('file://' + __dirname + '/index.html');

Ich denke, dass es vielleicht daran liegt, dass Webpack Dinge außerhalb des Elektronenkontexts aufruft / auswertet, die es ermöglichen, lokale Dateien bereitzustellen.

Irgendwelche Ideen/Vorschläge? Danke!

  • Elektronenversion: 0.37.2
  • Betriebssystem: Windows 10 Home

Hilfreichster Kommentar

FYI zu denen hier über Google: Sie erhalten den gleichen Fehler, wenn die Datei nicht existiert. Ich habe vergessen, electron-packager anzuweisen, die Zieldatei in die App zu kopieren. Lerne aus meinen dummen Fehlern :)

Alle 31 Kommentare

Sie können wahrscheinlich versuchen, webSecurity in webPreferences von BrowserWindow auszuschalten. Bei weiteren Fragen schlage ich vor, Hilfe von der Community zu suchen.

@MihaiValentin Hey, hast du dafür eine Lösung gefunden?

@MihaiValentin @singhshashi Ich hatte das gleiche Problem. Es scheint, dass Webpack standardmäßig versucht, Node Globals wie __dirname zu "mocken". Ich habe dieses Verhalten mit der Option node.__dirname deaktiviert und … es hat funktioniert!

Für alle Fälle verwende ich auch webpack-target-electron-renderer für die Option target .

Das ist bisher meine Konfig. Ich hoffe, es hilft:

var webpack = require('webpack');
var path = require('path');
var webpackTargetElectronRenderer = require('webpack-target-electron-renderer');

var BUILD_DIR = path.resolve(__dirname, 'build');
var APP_DIR = path.resolve(__dirname, 'src');

var config = {
  entry: APP_DIR + '/index.js',
  output: {
    path: BUILD_DIR,
    filename: 'index.js'
  },
  node: {
    __dirname: false,
    __filename: false
  },
  module : {
    loaders : [
      {
        test : /\.jsx?/,
        include : APP_DIR,
        exclude: /node_modules/,
        loader : 'babel'
      }
    ]
  }
};

config.target = webpackTargetElectronRenderer(config);

module.exports = config;

@eiriarte Danke, dass du das geteilt hast, aber das hat nicht funktioniert. Wenn ich die Dateien für den Hauptprozess mit Webpack packe, erhalte ich trotz der von Ihnen angegebenen Knotenkonfiguration immer noch den gleichen Fehler.

Ich teile eine Problemumgehung, die ich verwende, um das Problem für andere zu umgehen, die in diesem Thread landen.

Anstatt es-Funktionen zu verwenden, die von babel transpiliert werden müssen, damit sie in der Hauptsache korrekt funktionieren. js-Datei habe ich diese in verschiedene Dateien aufgeteilt. In meiner main.js verwende ich keine Features, die eine Babel-Transpilation erfordern. Anstelle von import verwende ich also require. Für Code, der es7-Vorschlagsfunktionen wie Async verwendete, habe ich diesen Code in andere Dateien innerhalb eines Ordners namens desktopServices verschoben (Sie könnten sich einen besseren Namen einfallen lassen). Ich führe jetzt webpack aus, um ein Bundle für desktopServices zu erstellen, und verweise auf dieses Bundle in main.js.

const myshell = require('./dist/desktopServices').myShell ;

Meine Datei webpack.config.main.js enthält die folgende Konfiguration.

let config = {
  target:'electron',
  entry:'./desktopServices/desktopServices.js',
  output:{
    path:path.resolve(__dirname, 'dist'),
    filename: 'desktopServices.js',
    publicPath:'/dist/',
    libraryTarget:'commonjs2'
  },
  resolve: {
    extensions:["",".js",".json"]
  },
  module: {
    noParse: /node_modules\/json-schema\/lib\/validate\.js/,
    loaders:[{
      test: /\.js?$/,
      exclude: /node_modules/,
      loader: 'babel-loader'
    },
      {
        test: /\.json/,
        loader: 'json-loader',
      },
    ],
  },
}

module.exports = config;

Nicht der sauberste Weg, aber ich denke, das ist der Weg, den ich vorerst einschlage, bis einige der es-Funktionen, die ich verwenden möchte, in den Knoten integriert werden und keine Babel-Transpilation erfordern.

Für mich stellte sich heraus, dass es sich um einen irreführenden Fehler handelte. Ich habe den Fehler not allowed to load local resource erhalten, weil das Webpack die Datei noch nicht fertig geschrieben hatte, bevor ich versuchte, sie zu laden, und nicht, weil sie mit den falschen Berechtigungen vorhanden war.

Ich ~fixierte~wickelte es mit setTimeout (dem Klebeband von Javascript) ein, damit ich mit dem Leben weitermachen konnte:

setTimeout(() => {
  win.loadURL(`file:///${__dirname}/index.html`);
}, 2000); // 1 second wasn't enough lol

Für mich war der Grund, dass der Pfad, auf dem das Webpack das Bundle ausgab, außer Reichweite war. Ich habe es gelöst, indem ich ein paar Verzeichnisse zurückgebracht und die Knotenkonfiguration wie oben vorgeschlagen angewendet habe

pathname: path.join(__dirname, '../../source/resources/views', 'index.html');

node: {
    __dirname: false,
    __filename: false
  },

FYI zu denen hier über Google: Sie erhalten den gleichen Fehler, wenn die Datei nicht existiert. Ich habe vergessen, electron-packager anzuweisen, die Zieldatei in die App zu kopieren. Lerne aus meinen dummen Fehlern :)

Als zukünftige Referenz (da ich diese Seite zu oft durchsucht habe) sind hier die aktuellen möglichen Probleme:

  1. Die Datei existiert nicht oder Ihre Node-Anwendung kann sie nicht erreichen. Stellen Sie sicher, dass electron-packager die Zieldatei in die App kopiert!

  2. Möglicherweise müssen Sie webSecurity innerhalb webPreferences deaktivieren, wenn Sie Ihr BrowserWindow() erstellen:

{
  webPreferences: {
    webSecurity: false
  }
}
  1. Webpack scheint standardmäßig zu versuchen, Node-Globals wie node.__dirname zu „mocken“, Sie können dies deaktivieren, indem Sie Folgendes zu Ihrer Konfiguration hinzufügen:
  node: {
    __dirname: false
  }
  1. Sie können die Ausführung des Ladens der URL verzögern, indem Sie setTimeout() verwenden (nicht empfohlen) oder auf das ready -Ereignis warten, das von der App gesendet wird (besser).
setTimeout(() => {
  win.loadURL(`file:///${__dirname}/index.html`);
}, 2000); // 1 second wasn't enough lol
app.on('ready', () => {
  win.loadURL(`file:///${__dirname}/index.html`);
})

Für mich war die Lösung

  1. Deaktivieren Sie die Websicherheit.
  2. Beim Versuch, Dateien zu verketten, habe ich __dirname+"./FileName" ausgeführt. Es wurde also 'C:/Folder./FileName' erstellt. Es sollte also kein "./" geben, sondern nur "/". Dies war kein Problem in der Entwicklung und nicht, bis ich ASAR hinzufügte.
  3. Es folgt einer strikten Groß- und Kleinschreibung von Dateinamen. Dieses Problem trat auf, nachdem ich asar hinzugefügt hatte, bis dahin funktionierte es sowohl in der Entwicklung als auch in der Produktion perfekt.

Hoffe, das hilft jemandem wie mir.

Ich lade http://localhost:8080/ in mein Hauptbrowserfenster für den Webpack-Entwicklungsserver (damit ich heiße Module neu laden kann). Das Problem war, dass es beim Laden mit dem file:// -Protokoll auf einem <iframe> nicht funktionierte.

Ich habe einfach die Websicherheit deaktiviert, wie von @popey456963 angegeben .

Ich habe jeweils zwei Konfigurationen für das Webpack für electron-main und electron-renderer

const path = require('path');
const config_main = {
  target: 'electron-main',
  entry: path.resolve(__dirname, 'src/main/index.js'),
  output: {
    path    : path.resolve(__dirname, 'static'),
    filename: 'main.js'
  },
  externals: [{ 'electron-store': 'require("electron-store")' }],
  resolve: {
    alias: {
      main   : path.resolve(__dirname, 'src/main/'),
      common : path.resolve(__dirname, 'src/common/')
    }
  }
};

const config_renderer = {
  target: 'electron-renderer',
  entry: path.resolve(__dirname, 'src/renderer/index.js'),
  output: {
    path    : path.resolve(__dirname, 'static'),
    filename: 'renderer.js'
  },
  externals: [{ 'electron-store': 'require("electron-store")' }],
  resolve: {
    alias: {
      components : path.resolve(__dirname, 'src/renderer/components/'),
      core       : path.resolve(__dirname, 'src/renderer/core/'),
      states     : path.resolve(__dirname, 'src/renderer/states/'),
      ui         : path.resolve(__dirname, 'src/renderer/ui/'),
      common     : path.resolve(__dirname, 'src/common/'),
    }
  }
};

module.exports = [
  config_main,
  config_renderer
];

Ich habe versucht mich zu bewerben

  node: {
    __dirname: false
  },

Ich habe in meinem renderer.js die __dirname ausgegeben und in beiden Fällen, wenn ich __dirname auf false oder true gesetzt habe, geben beide / aus

Wenn ich die absolute URL manuell einfüge, funktioniert es natürlich, obwohl ich nicht sicher bin, warum __dirname sich weigert, den richtigen Pfad anzugeben.

Überlegungen

webpackTargetElectronRenderer ist dasselbe wie Ziel: electron-main

Ich glaube, irgendwann wurde electron-main in das Webpack gerollt, wodurch webpackTargetElectronRenderer obsolet wurde

Hier können Sie sehen, was electron-main tut
https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsApply.js#L70 -L185

Hier sehen Sie genau den gleichen Code.
https://github.com/chentsulin/webpack-target-electron-renderer/blob/master/index.js

Es stellte sich heraus, dass ich hatte

  node: {
    __dirname: false
  },

In meiner Renderer-Konfiguration anstelle meiner Hauptkonfiguration. Ich werde meinen Kommentar oben behalten, falls jemand meine Konfigurationsdatei mag.

Was ist, wenn ich Webpack nicht verwende?

@hbgdPro Probieren Sie einige der Optionen von https://github.com/electron/electron/issues/5107#issuecomment -299971806 aus, 1, 2 und 4 erfordern alle kein Webpack.

@popey456963 Danke. Ich hatte es bereits versucht, bevor ich gefragt hatte. Mein Problem war eigentlich, dass ich angeben musste, welche Ordner ich in den Build-Prozess aufnehmen musste. Das hat nichts mit webpack zu tun.

Ich bin gerade selbst darauf gestoßen (Hallo, ich bin vom Webpack-Team). Wir haben ein Elektron-Hauptziel im Webpack, und ich wusste nicht, dass die Mocks __dirname und __filename das Standard-Schnellstartbeispiel unterbrechen.

Nur um sicherzugehen, Elektronenteam. Wäre dies eine offizielle Empfehlung, dies zu deaktivieren? Wenn ja, werde ich fortfahren und unsere Standardeinstellungen für das Elektronenhauptziel, das wir haben, veröffentlichen, damit diese eingebauten Elemente nicht verspottet werden.

Danke!

@TheLarkInn __dirname und __filename sind für die meisten Elektron-Apps sehr wichtig, da sie verwendet werden, um den Pfad zur HTML-Datei zu finden, die im Renderer-Prozess angezeigt werden soll. Sie zu verspotten, bricht die Dinge meistens / die ganze Zeit. Sie nicht zu verspotten, würde die Probleme vieler Menschen lösen 👍

Für diejenigen, die Webpack nicht verwenden, bin ich auf eine seltsame Lösung gestoßen, von der ich hoffe, dass jemand mit mehr Erfahrung darauf eingehen kann. Ich habe Folgendes verwendet und den in diesem Thread erwähnten Fehler erhalten.

win.loadURL('file://${__dirname}/renderer/main.html')

Nachdem der obige Code auf den folgenden umgestellt wurde, war der Fehler verschwunden und der HTML-Code wurde gerendert.

win.loadURL('file://' + __dirname + '/renderer/main.html')

Es scheint, als hätte das Original aus irgendeinem Grund einen falschen Pfad zur HTML-Datei angegeben. Weiß jemand warum?

@s-lawrence Der falsche Pfad ist auf Folgendes zurückzuführen:

win.loadURL('file://${__dirname}/renderer/main.html')

Sollte sein

win.loadURL(`file://${__dirname}/renderer/main.html`)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

Ah ok das macht Sinn. Vielen Dank an @milewski für die Ausarbeitung und die Bereitstellung einer Referenz.

Normalerweise bleibe ich bei der Verkettung, aber jetzt, da ich die richtige Syntax kenne, werde ich anfangen, mehr Vorlagenliterale zu verwenden, sie sehen viel sauberer aus.

@milewski , ich sehe keinen Unterschied in deinen beiden Ausschnitten. Soll der zweite anders sein als der erste?

@ jakehockey10 Der zweite hat Backticks anstelle von einfachen Anführungszeichen. Die Backticks zeigen an, dass es sich um ein Vorlagenliteral und nicht nur um ein Zeichenfolgenliteral handelt. Das erste Beispiel ist ein reguläres Zeichenfolgenliteral, sodass der Teil ${__dirname} niemals durch den __dirname ersetzt wird. Es ist manchmal ziemlich schwer zu bemerken, wenn Ihr Editor sie nicht anders hervorhebt (der GFM-Syntax-Highlighter unterscheidet sie leider nicht).

Ah, erwischt. Ich habe diesen Unterschied nicht bemerkt, als ich ihn in Markdown von GitHub betrachtete, aber ich verwende Visual Studio Code und bemerke den Unterschied dort definitiv, wie Sie erwähnt haben. Sorry für den Fehlalarm ;-)

Ich dachte nur, ich würde hinzufügen, ich habe diesen Fehler auch aufgrund meines eigenen Fehlers (Cap-Empfindlichkeit)
Ich habe pathname: path.join(__dirname, 'Views/settingsWindow.html') angerufen, als der Dateiname nur in Kleinbuchstaben geschrieben war.

Dies verursachte nur einen Fehler, nachdem es im Web gepackt wurde.

Ich habe einige der Lösungen ausprobiert, konnte es aber nicht zum Laufen bringen (mit [email protected] mit [email protected]).
Ich habe die beste Lösung in einem Beitrag mit nur 3 Stimmen zu SO gefunden: Es stellt sich heraus, dass dieses Paket nicht benötigt wird!
https://stackoverflow.com/questions/45041364/angular-electron-webpack-live-reloading

Lösung ohne Konfigurationsaufwand:
-npm Electron-Reload deinstallieren
-Run ng dienen in einem Terminal
-in main.js win.loadURL( http://localhost:4200/index.html ) ändern;
- Führen Sie dann npm Run Electron in einem anderen Terminal aus

Es FUNKTIONIERT einfach

Ich habe den ganzen Tag versucht, dies zu beheben, und schließlich hat die Lösung dieses Typen funktioniert
https://github.com/electron-userland/electron-builder/issues/2955#issuecomment -393524832

Wenn Sie das Attribut „build“ in der Datei „package.json“ definieren, fügen Sie einfach die erforderlichen Dateien wie folgt hinzu:

    "files": [
      "./build/**/*",
      "./index.html",
      "./src/*.js"
    ],

Dann packt der Elektronenbauer es richtig ein.

Es stellte sich heraus, dass das Präfix „file://“ alles war, was ich für die loadUrl-Methode benötigte.
Hatte:
win.loadUrl(path.join(__dirname, "./index.html"))
Ersetzt mit:
win.loadUrl(path.join("file://",__dirname, "./index.html"))

Webpack verblüfft mich beim Mischen von Schrägstrichen in der URL zum HTML-Eintrag, also verwende ich die Knoten url und path , damit es funktioniert:

const winURL = process.env.NODE_ENV === 'development'
  ? 'http://localhost:9080'
  : url.format({
    protocol: 'file',
    pathname: path.join(__dirname, 'index.html'),
  });

Es ist eine Katastrophe, ich stecke in CRA + Elektron fest 😂, das Ausführen im Entwicklungsmodus ist in Ordnung, aber in Windows exe verpackt funktioniert es überhaupt nicht.

Ich habe es verstanden. 🤣 Wenn Sie CRA mit React-Router verwenden, sollten Sie HashRouter verwenden, nicht BrowerRouter. FERTIG!!! 😂 siehe https://github.com/electron-userland/electron-builder/issues/2167

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen