Electron: Не разрешено загружать локальный ресурс: file://index.html/ после webpacking main.js

Созданный на 10 апр. 2016  ·  31Комментарии  ·  Источник: electron/electron

Я пытаюсь упаковать весь скрипт main.js и его зависимости в один файл (я хочу иметь один файл для приложения пользовательского интерфейса и один файл для серверного приложения).

Если я использую обычный источник, index.html загружается нормально. Однако при веб-упаковке я получаю сообщение об ошибке, упомянутое в заголовке.

Вот конфигурация веб-пакета, которую я использовал:

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

Я загружаю файл так:
mainWindow.loadURL('file://' + __dirname + '/index.html');

Я думаю, что это, возможно, связано с тем, что веб-пакет вызывает/оценивает вещи вне контекста электрона, что позволяет обслуживать локальные файлы.

Есть идеи/предложения? Спасибо!

  • Электронная версия: 0.37.2
  • Операционная система: Windows 10 Домашняя

Самый полезный комментарий

К сведению тех, кто здесь через Google: вы получаете ту же ошибку, если файл не существует. Я забыл сказать электронному упаковщику, чтобы он скопировал целевой файл в приложение. Учитесь на моих глупых ошибках :)

Все 31 Комментарий

Вероятно, вы можете попробовать отключить webSecurity в webPreferences из BrowserWindow . Для получения дополнительных вопросов я предлагаю обратиться за помощью к сообществу .

@MihaiValentin Эй, ты нашел решение для этого?

@MihaiValentin @singhshashi У меня была такая же проблема. Кажется, что webpack по умолчанию пытается «издеваться» над глобальными переменными Node, такими как __dirname . Я отключил это поведение с помощью опции node.__dirname и… это сработало!

На всякий случай я также использую webpack-target-electron-renderer для опции target .

Это моя конфигурация на данный момент. Я надеюсь, что это помогает:

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 Спасибо, что поделились этим, однако это не сработало. Если я упаковываю файлы для основного процесса с помощью веб-пакета, даже с указанной вами конфигурацией узла, я все равно получаю ту же ошибку.

Я делюсь обходным путем, который я использую, чтобы обойти проблему для других, которые попадают в эту тему.

Вместо того, чтобы использовать функции es, которые требуют, чтобы Babel транспилировал их для правильной работы в файле main. js, я разделил их на разные файлы. В моем main.js я не использую никаких функций, требующих транспиляции Babel. Поэтому вместо импорта я использую require. Для кода, в котором использовались функции предложения es7, такие как асинхронность, я переместил этот код в другие файлы в папку с именем desktopServices (вы могли бы придумать имя получше). Теперь я запускаю webpack, чтобы создать пакет для desktopServices, и ссылаюсь на этот пакет в main.js.

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

Мой файл webpack.config.main.js содержит следующую конфигурацию.

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;

Не самый чистый способ, но я думаю, что это путь, по которому я сейчас иду, пока некоторые из функций es, которые я хочу использовать, не будут включены в узел и не требуют транспиляции Babel.

Для меня это оказалось вводящей в заблуждение ошибкой. Я получал ошибку not allowed to load local resource , потому что веб-пакет не закончил запись файла до того, как я попытался его загрузить, а не потому, что он был там с неправильными разрешениями.

Я ~исправил~обмотал его setTimeout (клейкой лентой javascript), чтобы я мог жить дальше:

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

для меня .. причина была в том, что путь, по которому веб-пакет выводил пакет .. был вне досягаемости ... я решил это, вернувшись в несколько каталогов и применив конфигурацию узла, как было предложено выше .. работает отлично: D

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

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

К сведению тех, кто здесь через Google: вы получаете ту же ошибку, если файл не существует. Я забыл сказать электронному упаковщику, чтобы он скопировал целевой файл в приложение. Учитесь на моих глупых ошибках :)

Для справки в будущем (поскольку я слишком много раз просматривал эту страницу), вот текущие возможные проблемы:

  1. Файл не существует, или ваше приложение Node не может получить к нему доступ. Убедитесь, что electron-packager копирует целевой файл в приложение!

  2. Вам может потребоваться отключить webSecurity в пределах webPreferences при создании BrowserWindow() :

{
  webPreferences: {
    webSecurity: false
  }
}
  1. Webpack по умолчанию, кажется, пытается «издеваться» над глобальными узлами, такими как node.__dirname , вы можете отключить это, добавив следующее в свою конфигурацию:
  node: {
    __dirname: false
  }
  1. Вы можете отложить выполнение загрузки URL-адреса, используя setTimeout() (не рекомендуется) или дождавшись отправки события ready из приложения (лучше).
setTimeout(() => {
  win.loadURL(`file:///${__dirname}/index.html`);
}, 2000); // 1 second wasn't enough lol
app.on('ready', () => {
  win.loadURL(`file:///${__dirname}/index.html`);
})

Для меня решение было

  1. отключить веб-безопасность.
  2. при попытке объединить файл я делал __dirname+"./FileName". Итак, он создавал «C:/Folder./FileName». Так что не должно быть "./", а только "/". Это не было проблемой в разработке, пока я не добавил ASAR.
  3. Он следует строгому регистру имен файлов. С этой проблемой я столкнулся после добавления asar, до этого он отлично работал как в разработке, так и в производстве.

Надеюсь, это поможет кому-то, как я.

Я загружаю http://localhost:8080/ в главном окне браузера для сервера разработки webpack (так что я могу получить горячую перезагрузку модуля). Проблема заключалась в том, что при загрузке по протоколу file:// на <iframe> он не работал.

Я просто отключил веб-безопасность, как указал @popey456963 .

У меня есть две конфигурации для веб-пакета, каждая для electron-main и 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
];

я пытался применить

  node: {
    __dirname: false
  },

Я вывел в консоли renderer.js __dirname , и в обоих случаях, если для __dirname установлено значение false или true, они оба распечатывают /

Конечно, если я вручную ввожу абсолютный URL-адрес, он работает, хотя и не уверен, почему __dirname отказывается указывать правильный путь.

Соображения

webpackTargetElectronRenderer — это то же самое, что и target: electron-main

Я считаю, что в какой-то момент electron-main был включен в веб-пакет, что сделало webpackTargetElectronRenderer устаревшим

Здесь вы можете увидеть, что делает electron-main
https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsApply.js#L70 -L185

Здесь вы можете увидеть точно такой же код.
https://github.com/chentsulin/webpack-target-electron-renderer/blob/master/index.js

Оказывается, у меня было

  node: {
    __dirname: false
  },

В моей конфигурации рендерера вместо моей основной конфигурации. Я сохраню свой комментарий выше на случай, если кому-то понравится мой файл конфигурации.

Что делать, если я не использую веб-пакет?

@hbgdPro Попробуйте некоторые варианты из https://github.com/electron/electron/issues/5107#issuecomment -299971806, 1, 2 и 4, все они не требуют веб-пакета.

@ popey456963 Спасибо. Я уже пробовал, прежде чем я спросил. Моя проблема заключалась в том, что мне нужно было указать, какие папки мне нужно включить в процесс сборки. Это не имеет ничего общего с веб-пакетом.

Я только что сам наткнулся на это (привет, я из команды webpack). У нас есть электрон-основная цель в веб-пакете, и я не знал, что моки __dirname и __filename нарушают пример быстрого запуска по умолчанию.

Просто чтобы убедиться, электронная команда. Будет ли это официальной рекомендацией отключить это? Если это так, я продолжу и PR наши значения по умолчанию для главной электронной цели, которые у нас есть, чтобы эти встроенные функции не издевались.

Спасибо!

@TheLarkInn __dirname и __filename очень важны для большинства электронных приложений, поскольку они используются для поиска пути к файлу HTML для отображения в процессе рендеринга. Издевательство над ними ломает вещи чаще всего / все время. Если бы не издеваться над ними, это решило бы проблемы многих людей 👍

Для тех, кто не использует Webpack, я наткнулся на странное решение, которое, я надеюсь, кто-то с большим опытом сможет разработать. Я использовал следующее и получил сообщение об ошибке, упомянутое в этом потоке.

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

после переключения приведенного выше кода на следующий ошибка исчезла, и html отобразился.

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

Похоже, что оригинал по какой-то причине указывал неправильный путь к html-файлу, кто-нибудь знает, почему?

@s-lawrence Неправильный путь связан с:

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

Должно быть

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

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

Ах, хорошо, это имеет смысл. Спасибо @milewski за разъяснение этого вопроса, а также за предоставление ссылки.

Обычно я придерживаюсь конкатенации, но теперь, когда я знаю правильный синтаксис, я начну больше использовать литералы шаблонов, они выглядят намного чище.

@milewski , я не вижу разницы в ваших двух фрагментах. Второй должен отличаться от первого?

@jakehockey10 Во втором вместо одинарных кавычек обратные кавычки. Обратные кавычки указывают, что это литерал шаблона , а не просто литерал строки. Первый пример — это обычный строковый литерал, поэтому часть ${__dirname} никогда не заменяется значением __dirname . Иногда довольно трудно заметить, если ваш редактор не выделяет их по-разному (к сожалению, подсветка синтаксиса GFM их не различает).

Ах поймал. Я не заметил этой разницы при просмотре в GitHub Markdown, но я использую код Visual Studio и определенно замечаю разницу, как вы упомянули. Извините за ложную тревогу ;-)

Просто решил добавить, я также получил эту ошибку из-за моей собственной ошибки (чувствительность к кепке)
Я звонил pathname: path.join(__dirname, 'Views/settingsWindow.html') , когда имя файла было все в нижнем регистре.

Это вызвало ошибку только после того, как он был упакован в сеть.

Я попробовал некоторые из решений, но не смог заставить их работать (используя [email protected] с [email protected]).
Я нашел лучшее решение в посте с тремя голосами SO: Оказывается, этот пакет не нужен!
https://stackoverflow.com/questions/45041364/angular-electron-webpack-live-reloading

Решение без проблем с конфигурацией:
-npm удалить электронную перезагрузку
-Запуск службы в одном терминале
-в main.js изменить win.loadURL( http://localhost:4200/index.html );
- затем запустите npm run electronic в другом терминале

Это просто РАБОТАЕТ

Я пытался исправить это весь день, и, наконец, это решение сработало, проверьте
https://github.com/electron-userland/electron-builder/issues/2955#issuecomment -393524832

Когда вы определяете атрибут «build» в package.json, просто добавьте необходимые файлы следующим образом:

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

Тогда электронщик правильно упакует.

Оказалось, что префикс «file://» был всем, что мне было нужно для метода loadUrl.
Имел:
win.loadUrl(path.join(__dirname, "./index.html"))
Заменено на:
win.loadUrl(path.join("file://",__dirname, "./index.html"))

Webpack сбивает меня с толку, смешивая как прямые, так и обратные косые черты в URL-адресе записи html, поэтому я использую узлы url и path , чтобы заставить его работать:

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

это катастрофа, я застрял в CRA + электрон 😂, работает в режиме dev нормально, но запакованный в windows exe вообще не работает.

Я понял. 🤣 Если вы используете CRA с реактивным маршрутизатором, вам следует использовать HashRouter, а не BrowerRouter. ГОТОВО!!! 😂 см. https://github.com/electron-userland/electron-builder/issues/2167

Была ли эта страница полезной?
0 / 5 - 0 рейтинги