Electron: No se permite cargar recursos locales: file://index.html/ después de webpacking main.js

Creado en 10 abr. 2016  ·  31Comentarios  ·  Fuente: electron/electron

Estoy tratando de empaquetar en la web todo el script main.js y sus dependencias en un solo archivo (quiero tener un archivo para la aplicación de interfaz de usuario y un archivo para la aplicación del servidor).

Si uso la fuente normal, index.html se carga bien. Sin embargo, cuando empaqueto web, aparece el error mencionado en el título.

Aquí está la configuración del paquete web que usé:

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

Cargo el archivo así:
mainWindow.loadURL('file://' + __dirname + '/index.html');

Creo que quizás se deba a que el paquete web llama / evalúa cosas fuera del contexto de electrones que permite servir archivos locales.

¿Alguna idea/sugerencia? ¡Gracias!

  • Versión electrónica: 0.37.2
  • Sistema operativo: Windows 10 Inicio

Comentario más útil

FYI para los que están aquí a través de Google: obtienes el mismo error si el archivo no existe. Olvidé decirle a electron-packager que copie el archivo de destino en la aplicación. Aprende de mis estúpidos errores :)

Todos 31 comentarios

Probablemente pueda intentar desactivar webSecurity en webPreferences de BrowserWindow . Para más preguntas sugiero buscar ayuda de la comunidad .

@MihaiValentin Oye, ¿encontraste una solución para esto?

@MihaiValentin @singhshashi Tuve el mismo problema. Parece que el paquete web, de forma predeterminada, intenta "simular" los globales de nodo como __dirname . Desactivé este comportamiento con la opción node.__dirname y… ¡funcionó!

Por si acaso, también estoy usando webpack-target-electron-renderer para la opción target .

Esta es mi configuración hasta ahora. Espero que ayude:

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 Gracias por compartir eso, sin embargo eso no funcionó. Si empaqueto los archivos para el proceso principal usando webpack, incluso con la configuración de nodo que ha dicho, sigo recibiendo el mismo error.

Estoy compartiendo una solución alternativa que estoy usando para solucionar el problema para otros que llegan a este hilo.

En lugar de usar funciones es que requieren que babel las transpile para que funcionen correctamente en el archivo principal. js, los separé en diferentes archivos. En mi main.js no uso ninguna característica que requiera transpilación de babel. Entonces, en lugar de importar, uso require. Para el código que usaba funciones de propuesta de es7 como asíncrono, moví ese código a diferentes archivos, dentro de una carpeta llamada servicios de escritorio (podría encontrar un nombre mejor). Ahora ejecuto webpack para crear un paquete para servicios de escritorio y hago referencia a este paquete en main.js.

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

Mi archivo webpack.config.main.js contiene la siguiente configuración.

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;

No es la forma más limpia, pero supongo que esta es la ruta que estoy tomando por el momento hasta que algunas de las características de es que quiero usar se incorporen al nodo y no requieran transpilación de babel.

Para mí, resultó ser un error engañoso. Estaba recibiendo el error not allowed to load local resource porque el paquete web no había terminado de escribir el archivo antes de intentar cargarlo, no porque estuviera allí con los permisos incorrectos.

Lo ~arreglé~lo envolví con setTimeout (la cinta adhesiva de javascript) para poder continuar con mi vida:

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

para mí... la razón fue porque la ruta del paquete web estaba generando el paquete... estaba fuera de alcance... lo resolví regresando algunos directorios y aplicando la configuración del nodo como se sugirió anteriormente... funciona perfectamente: D

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

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

FYI para los que están aquí a través de Google: obtienes el mismo error si el archivo no existe. Olvidé decirle a electron-packager que copie el archivo de destino en la aplicación. Aprende de mis estúpidos errores :)

Para referencia futura (ya que he buscado en esta página demasiadas veces), estos son los posibles problemas actuales:

  1. El archivo no existe o su aplicación Node no puede acceder a él. ¡Asegúrese de que electron-packager esté copiando el archivo de destino en la aplicación!

  2. Es posible que deba deshabilitar webSecurity dentro webPreferences cuando cree su BrowserWindow() :

{
  webPreferences: {
    webSecurity: false
  }
}
  1. Webpack, de forma predeterminada, parece intentar "simular" los nodos globales como node.__dirname , puede desactivar esto agregando lo siguiente a su configuración:
  node: {
    __dirname: false
  }
  1. Puede retrasar la ejecución de la carga de la URL usando setTimeout() (no recomendado) o esperar a que se envíe el evento ready desde la aplicación (mejor).
setTimeout(() => {
  win.loadURL(`file:///${__dirname}/index.html`);
}, 2000); // 1 second wasn't enough lol
app.on('ready', () => {
  win.loadURL(`file:///${__dirname}/index.html`);
})

Para mi la solución fue

  1. desactivar la seguridad web.
  2. al intentar concatenar archivos, estaba haciendo __dirname+"./FileName". Entonces estaba creando 'C:/Folder./FileName'. Por lo tanto, no debería haber "./" sino solo "/". Esto no fue un problema en el desarrollo y no hasta que agregué ASAR.
  3. Sigue estrictamente el uso de mayúsculas y minúsculas en los nombres de los archivos. Este problema lo encontré después de agregar asar, hasta entonces funcionaba perfectamente tanto en desarrollo como en producción.

Espero que esto ayude a alguien nube como yo.

Estoy cargando http://localhost:8080/ en la ventana principal de mi navegador para el servidor de desarrollo webpack (para que pueda recargar el módulo en caliente). El problema era que al cargar con el protocolo file:// en un <iframe> no funcionaba.

Simplemente deshabilité la seguridad web como lo señaló @ popey456963 .

Tengo dos configuraciones para webpack, cada una para electron-main y 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
];

He intentado aplicar

  node: {
    __dirname: false
  },

He consolado en mi renderer.js el __dirname y en ambos casos, si tengo __dirname configurado en falso o verdadero, ambos imprimen /

Por supuesto, si introduzco manualmente la URL absoluta, funciona, aunque no estoy seguro de por qué __dirname se niega a dar la ruta correcta.

Consideraciones

webpackTargetElectronRenderer es lo mismo que el objetivo: electron-main

Creo que en algún momento electron-main se incorporó al paquete web, lo que hizo que webpackTargetElectronRenderer quedara obsoleto

Aquí puedes ver lo que hace electron-main
https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsApply.js#L70 -L185

Aquí puedes ver exactamente el mismo código.
https://github.com/chentsulin/webpack-target-electron-renderer/blob/master/index.js

resulta que tenia

  node: {
    __dirname: false
  },

En mi configuración de renderizador en lugar de mi configuración principal. Mantendré mi comentario anterior en caso de que a alguien le guste mi archivo de configuración.

¿Qué pasa si no estoy usando el paquete web?

@hbgdPro Pruebe algunas de las opciones de https://github.com/electron/electron/issues/5107#issuecomment -299971806, 1, 2 y 4, todas no requieren webpack.

@popey456963 Gracias. Ya había probado antes de preguntar. Mi problema era en realidad que tenía que especificar qué carpetas necesitaba incluir en el proceso de compilación. No tiene nada que ver con el paquete web.

Acabo de encontrar esto yo mismo (hola, soy del equipo de webpack). Tenemos un objetivo principal de electrones en el paquete web, y no sabía que los simulacros __dirname y __filename rompen el ejemplo predeterminado de inicio rápido.

Sólo para estar seguros, equipo de electrones. ¿Sería esta una recomendación oficial para tener esto deshabilitado? Si es así, seguiré adelante y PR nuestros valores predeterminados para el objetivo principal de electrones que tenemos para que estos elementos integrados no se burlen.

¡Gracias!

@TheLarkInn __dirname y __filename son muy importantes para la mayoría de las aplicaciones electrónicas, ya que se usan para encontrar la ruta al archivo HTML para mostrarlo en el proceso de procesamiento. Burlarse de ellos rompe cosas la mayor parte del tiempo. No burlarse de ellos solucionaría los problemas de muchas personas 👍

Para aquellos que no usan Webpack, encontré una solución extraña que espero que alguien con más experiencia pueda desarrollar. Estaba usando lo siguiente y recibí el error mencionado a lo largo de este hilo.

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

después de cambiar el código anterior al siguiente, el error desapareció y el html se mostraría.

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

Parece que el original estaba dando una ruta incorrecta al archivo html por alguna razón, ¿alguien sabe por qué?

@s-lawrence La ruta incorrecta se debe a:

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

Debiera ser

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

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

Ah de acuerdo, eso tiene sentido. Gracias @milewski por dar más detalles sobre eso y proporcionar una referencia.

Por lo general, me quedo con la concatenación, pero ahora que conozco la sintaxis adecuada, comenzaré a usar más los literales de plantilla, tienen un aspecto mucho más limpio.

@milewski , no veo ninguna diferencia en tus dos fragmentos. ¿Se supone que el segundo es diferente al primero?

@jakehockey10 El segundo tiene acentos graves en lugar de comillas simples. Los acentos graves indican que es un literal de plantilla en lugar de solo un literal de cadena. El primer ejemplo es un literal de cadena normal, por lo que la parte ${__dirname} nunca se sustituye por el __dirname . Es bastante difícil darse cuenta a veces si su editor no los resalta de manera diferente (el resaltador de sintaxis GFM no los distingue, desafortunadamente).

Ah te pillo. No noté esa diferencia cuando lo vi en Markdown de GitHub, pero uso Visual Studio Code y definitivamente noto la diferencia allí como mencionas. Disculpa por la falsa alarma ;-)

Solo pensé en agregar, también recibí este error debido a mi propio error (sensibilidad de límite)
Estaba llamando a pathname: path.join(__dirname, 'Views/settingsWindow.html') cuando el nombre del archivo estaba en minúsculas.

Esto solo provocó un error una vez que se empaquetó en la web.

Probé algunas de las soluciones pero no pude hacer que funcionara (usando [email protected] con [email protected]).
Encontré la mejor solución en una publicación con solo 3 votos en SO: ¡Resulta que no hay necesidad de este paquete!
https://stackoverflow.com/questions/45041364/angular-electron-webpack-live-recarga

Solución sin problemas de configuración:
-npm desinstalar recarga de electrones
-Ejecutar servicio ng en una terminal
-en main.js cambia win.loadURL( http://localhost:4200/index.html );
-luego ejecuta npm ejecuta electrones en otra terminal

Simplemente FUNCIONA

Traté de arreglar esto todo el día y finalmente la solución de este chico funcionó, verifique
https://github.com/electron-userland/electron-builder/issues/2955#issuecomment -393524832

Cuando defina el atributo "construir" en el paquete.json, simplemente agregue los archivos requeridos de la siguiente manera:

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

Entonces el generador de electrones lo empacará correctamente.

Resultó que el prefijo 'file://' era todo lo que necesitaba para el método loadUrl.
Tenido:
win.loadUrl(path.join(__dirname, "./index.html"))
Reemplazadas con:
win.loadUrl(path.join("file://",__dirname, "./index.html"))

Webpack me desconcierta al mezclar barras diagonales hacia adelante y hacia atrás en la URL de la entrada html, así que uso url y path del nodo para que funcione:

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

es un desastre, estoy atascado en CRA + electron 😂, ejecutar en modo dev está bien, pero empaquetado en Windows exe no funciona en absoluto.

Lo tengo. 🤣 Si usa CRA con react-router, debe usar HashRouter, no BrowerRouter. ¡¡¡HECHO!!! 😂 consulta https://github.com/electron-userland/electron-builder/issues/2167

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

EladBezalel picture EladBezalel  ·  3Comentarios

feross picture feross  ·  3Comentarios

rhnorskov picture rhnorskov  ·  3Comentarios

lealife picture lealife  ·  3Comentarios

dangan-ronpa picture dangan-ronpa  ·  3Comentarios