Я пытаюсь упаковать весь скрипт 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');
Я думаю, что это, возможно, связано с тем, что веб-пакет вызывает/оценивает вещи вне контекста электрона, что позволяет обслуживать локальные файлы.
Есть идеи/предложения? Спасибо!
Вероятно, вы можете попробовать отключить 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: вы получаете ту же ошибку, если файл не существует. Я забыл сказать электронному упаковщику, чтобы он скопировал целевой файл в приложение. Учитесь на моих глупых ошибках :)
Для справки в будущем (поскольку я слишком много раз просматривал эту страницу), вот текущие возможные проблемы:
Файл не существует, или ваше приложение Node не может получить к нему доступ. Убедитесь, что electron-packager
копирует целевой файл в приложение!
Вам может потребоваться отключить webSecurity
в пределах webPreferences
при создании BrowserWindow()
:
{
webPreferences: {
webSecurity: false
}
}
node.__dirname
, вы можете отключить это, добавив следующее в свою конфигурацию: node: {
__dirname: false
}
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`);
})
Для меня решение было
Надеюсь, это поможет кому-то, как я.
Я загружаю 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
Самый полезный комментарий
К сведению тех, кто здесь через Google: вы получаете ту же ошибку, если файл не существует. Я забыл сказать электронному упаковщику, чтобы он скопировал целевой файл в приложение. Учитесь на моих глупых ошибках :)