Electron: Não é permitido carregar o recurso local: file://index.html/ após o webpacking main.js

Criado em 10 abr. 2016  ·  31Comentários  ·  Fonte: electron/electron

Estou tentando webpack todo o script main.js e suas dependências em um único arquivo (eu quero ter um arquivo para o aplicativo de interface do usuário e um arquivo para o aplicativo do servidor).

Se eu usar a fonte normal, index.html carrega muito bem. No entanto, ao fazer o webpacking, recebo o erro mencionado no título.

Aqui está a configuração do webpack que usei:

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

Carrego o arquivo assim:
mainWindow.loadURL('file://' + __dirname + '/index.html');

Eu acho que talvez seja devido ao webpack chamando/avaliando coisas fora do contexto do elétron que permite servir arquivos locais.

Alguma ideia/sugestão? Obrigado!

  • Versão eletrônica: 0.37.2
  • Sistema operacional: Windows 10 Home

Comentários muito úteis

FYI para aqueles aqui via google: você recebe o mesmo erro se o arquivo não existir. Esqueci de dizer ao electron-packager para copiar o arquivo de destino no aplicativo. Aprenda com meus erros estúpidos :)

Todos 31 comentários

Você provavelmente pode tentar desativar webSecurity em webPreferences de BrowserWindow . Para mais dúvidas sugiro procurar ajuda da comunidade .

@MihaiValentin Ei, você encontrou uma solução para isso?

@MihaiValentin @singhshashi Eu tive o mesmo problema. Parece que o webpack, por padrão, tenta "zombar" de Node globais como __dirname . Desativei esse comportamento com a opção node.__dirname e… funcionou!

Por precaução, também estou usando webpack-target-electron-renderer para a opção target .

Esta é a minha configuração até agora. Espero que ajude:

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 Obrigado por compartilhar isso, porém não funcionou. Se eu empacotar os arquivos do processo principal usando o webpack, mesmo com a configuração do nó que você disse, ainda recebo o mesmo erro.

Estou compartilhando uma solução alternativa que estou usando para contornar o problema para outras pessoas que acessam este tópico.

Em vez de usar recursos es que exigem que o babel os transpile para funcionar corretamente no main. js, eu os separei em arquivos diferentes. No meu main.js eu não uso nenhum recurso que exija transpilação babel. Então, em vez de importar, eu uso require. Para o código que estava usando os recursos da proposta es7, como async, movi esse código para arquivos diferentes, dentro de uma pasta chamada desktopServices (você poderia criar um nome melhor). Agora executo o webpack para criar um pacote para desktopServices e faço referência a esse pacote em main.js.

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

Meu arquivo webpack.config.main.js contém a seguinte configuração.

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;

Não é a maneira mais limpa, mas acho que esta é a rota que estou tomando por enquanto até que alguns dos recursos es que quero usar sejam incorporados ao nó e não exijam transpilação babel.

Para mim, acabou por ser um erro enganoso. Eu estava recebendo o erro not allowed to load local resource porque o webpack não havia terminado de escrever o arquivo antes de tentar carregá-lo, não porque estava lá com as permissões erradas.

Eu ~consertei~ embrulhei com setTimeout (a fita adesiva do javascript) para que eu pudesse seguir com a vida:

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

para mim .. o motivo foi porque o caminho que o webpack estava produzindo o pacote .. estava fora de alcance ... eu resolvi voltando alguns diretórios e aplicando a configuração do nó como sugerido acima .. funciona perfeitamente :D

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

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

FYI para aqueles aqui via google: você recebe o mesmo erro se o arquivo não existir. Esqueci de dizer ao electron-packager para copiar o arquivo de destino no aplicativo. Aprenda com meus erros estúpidos :)

Para referência futura (já que pesquisei muitas vezes nesta página), aqui estão os possíveis problemas atuais:

  1. O arquivo não existe ou seu aplicativo Node não pode alcançá-lo. Certifique-se de que electron-packager esteja copiando o arquivo de destino para o aplicativo!

  2. Você pode precisar desabilitar webSecurity em webPreferences ao criar seu BrowserWindow() :

{
  webPreferences: {
    webSecurity: false
  }
}
  1. O Webpack, por padrão, parece tentar "zombar" de nós globais como node.__dirname , você pode desabilitar isso adicionando o seguinte à sua configuração:
  node: {
    __dirname: false
  }
  1. Você pode atrasar a execução do carregamento da URL usando setTimeout() (não recomendado) ou esperando o evento ready ser enviado do aplicativo (melhor).
setTimeout(() => {
  win.loadURL(`file:///${__dirname}/index.html`);
}, 2000); // 1 second wasn't enough lol
app.on('ready', () => {
  win.loadURL(`file:///${__dirname}/index.html`);
})

Para mim a solução foi

  1. desative a segurança da web.
  2. ao tentar concatenar o arquivo, eu estava fazendo __dirname+"./FileName". Então estava criando 'C:/Folder./FileName'. Portanto, não deve haver "./" em vez de apenas "/". Este não foi um problema no desenvolvimento e não até que eu adicionei o ASAR.
  3. Segue maiúsculas e minúsculas de nomes de arquivos. Esse problema que encontrei após adicionar o asar, até então estava funcionando perfeitamente no desenvolvimento e na produção.

Espero que isso ajude alguém nube como eu.

Estou carregando http://localhost:8080/ na minha janela principal do navegador para o servidor webpack dev (para que eu possa recarregar o módulo quente). O problema foi que ao carregar com o protocolo file:// em um <iframe> não funcionou.

Eu simplesmente desabilitei a segurança da web, conforme apontado por @popey456963 .

Eu tenho duas configurações para webpack cada para o electron-main e 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
];

ja tentei aplicar

  node: {
    __dirname: false
  },

Eu consolei no meu renderer.js o __dirname e em ambos os casos, se eu tiver __dirname definido como false ou true, ambos imprimem /

É claro que se eu colocar manualmente o URL absoluto, ele funciona, embora não saiba por que __dirname se recusa a fornecer o caminho correto.

Considerações

webpackTargetElectronRenderer é a mesma coisa que alvo: electron-main

Eu acredito que em algum momento electron-main foi colocado no webpack tornando webpackTargetElectronRenderer obsoleto

Aqui você pode ver o que electron-main faz
https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsApply.js#L70 -L185

Aqui você pode ver exatamente o mesmo código.
https://github.com/chentsulin/webpack-target-electron-renderer/blob/master/index.js

Acontece que eu tinha

  node: {
    __dirname: false
  },

Na minha configuração do renderizador em vez da minha configuração principal. Vou manter meu comentário acima caso alguém goste do meu arquivo de configuração.

E se eu não estiver usando o webpack?

@hbgdPro Experimente algumas das opções de https://github.com/electron/electron/issues/5107#issuecomment -299971806, 1, 2 e 4 não requerem webpack.

@popey456963 Obrigado. Eu já havia tentado antes de perguntar. Meu problema era que eu tinha que especificar quais pastas eu precisava incluir no processo de compilação. Não tem nada a ver com webpack.

Acabei de me deparar com isso, (oi, sou da equipe do webpack). Temos um alvo electron-main no webpack, e eu não sabia que os mocks __dirname e __filename quebram o exemplo padrão de início rápido.

Só para ter certeza, equipe eletrônica. Isso seria uma recomendação oficial para desabilitar isso? Se assim for, vou em frente e PR nossos padrões para o alvo principal de elétrons que temos para que esses builtins não sejam ridicularizados.

Obrigado!

@TheLarkInn __dirname e __filename são super críticos para a maioria dos aplicativos eletrônicos, pois são usados ​​para encontrar o caminho para o arquivo HTML a ser exibido no processo de renderização. Zombar deles quebra as coisas na maioria das vezes. Não zombar deles resolveria os problemas de muitas pessoas 👍

Para aqueles que não usam o Webpack, encontrei uma solução estranha que espero que alguém com mais experiência possa elaborar. Eu estava usando o seguinte e recebendo o erro mencionado em todo este tópico.

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

depois de mudar o código acima para o seguinte, o erro desapareceu e o html seria renderizado.

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

Parece que o original estava dando um caminho impróprio para o arquivo html por algum motivo, alguém sabe por quê?

@s-lawrence O caminho impróprio é devido a:

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

Deveria estar

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

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

Ah ok isso faz sentido. Obrigado @milewski por elaborar isso, além de fornecer uma referência.

Eu costumo ficar com a concatenação, mas agora que eu sei a sintaxe correta, começarei a usar mais literais de modelo, eles têm uma aparência muito mais limpa.

@milewski , não vejo diferença nos seus dois trechos. O segundo deve ser diferente do primeiro?

@jakehockey10 O segundo tem acentos graves em vez de aspas simples. Os backticks indicam que é um literal de modelo em vez de apenas um literal de string. O primeiro exemplo é um literal de string regular, então a parte ${__dirname} nunca é substituída pelo __dirname . Às vezes, é muito difícil perceber se o seu editor não os destaca de maneira diferente (o marcador de sintaxe GFM não os distingue, infelizmente).

Ah entendi. Não notei essa diferença ao visualizá-lo no Markdown do GitHub, mas uso o Visual Studio Code e definitivamente noto a diferença como você mencionou. Desculpe pelo alarme falso ;-)

Apenas pensei em adicionar, também recebi esse erro devido ao meu próprio erro (sensibilidade ao limite)
Eu estava chamando pathname: path.join(__dirname, 'Views/settingsWindow.html') quando o nome do arquivo estava todo em letras minúsculas.

Isso só causou um erro quando foi compactado na web.

Eu tentei algumas das soluções, mas não consegui fazê-lo funcionar (usando [email protected] com [email protected]).
Encontrei a melhor solução em um post com apenas 3 votos no SO: Acontece que não há necessidade desse pacote!
https://stackoverflow.com/questions/45041364/angular-electron-webpack-live-reloading

Solução sem complicações de configuração:
-npm desinstala o electron-reload
-Executar ng serve em um terminal
-in main.js altere win.loadURL( http://localhost:4200/index.html );
- então execute npm run electron em outro terminal

Simplesmente FUNCIONA

Eu tentei consertar isso o dia todo e finalmente essa solução de cara funcionou, verifique
https://github.com/electron-userland/electron-builder/issues/2955#issuecomment -393524832

Ao definir o atributo "build" no package.json, basta adicionar os arquivos necessários da seguinte forma:

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

Então o construtor de elétrons irá embalá-lo corretamente.

Acabou que o prefixo 'file://' era tudo o que eu precisava para o método loadUrl.
Teve:
win.loadUrl(path.join(__dirname, "./index.html"))
Substituído por:
win.loadUrl(path.join("file://",__dirname, "./index.html"))

O Webpack me confunde ao misturar barras para frente e para trás na URL para a entrada html, então eu uso url e path do nó para fazê-lo funcionar:

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

é um desastre, estou preso no CRA + elétron 😂, rodar no modo dev é bom, mas empacotado no windows exe não funciona de jeito nenhum.

Eu entendi. 🤣 Se você usa CRA com react-router, deve usar HashRouter, não BrowerRouter. FEITO!!! 😂 consulte https://github.com/electron-userland/electron-builder/issues/2167

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

chonsser picture chonsser  ·  3Comentários

ThorstenHans picture ThorstenHans  ·  3Comentários

PhilAndrew picture PhilAndrew  ·  3Comentários

christiangenco picture christiangenco  ·  3Comentários

reggi picture reggi  ·  3Comentários