Как управлять конфигурацией для Webpack / Electron app?
я использую Webpack 2 и Electron для создания приложения nodejs на Mac.
в моем проекте в корне у меня есть каталог "данные", где я храню конфигурацию в json, как данные/конфигурации/файлы.json (на практике существуют разные файлы с динамическими именами)
после webpackaing, хотя, когда я звоню:fs.readdirSync(remote.app.getAppPath());
чтобы получить файлы в корне, я получаю только эти упакованные:[ "default_app.js", "icon.png", "index.html", "main.js", "package.json", "renderer.js" ]
path.join(remote.app.getAppPath(), 'data/tests/groups.json');
вызов с помощью FS ReadSync приводит к проблеме Error: ENOENT, data/tests/groups.json not found in /Users/myuser/myproject/node_modules/electron/dist/Electron.app/Contents/Resources/default_app.asar
. Так кажется что вся папка данных не подобрана webpacker.
конфигурация Webpack использует json-loader
и я не нашел никакой документации, упоминающей что-либо особенное о включении конкретных файлов или jsons. Или мне нужно ссылаться на файлы json в моем коде по-другому, поскольку они могут быть упакованы под main.js.
какова наилучшая практика для Electron / Webpack для управления файлами конфигурации JSON? Я делаю что-то неправильно, когда webpacking проект?
мой проект на основеhttps://github.com/SimulatedGREG/electron-vue использование webpack/electron / vue
3 ответов
Заблуждение Webpack
одна вещь, чтобы понять заранее, что webpack
не пачки файлов при помощи fs
или другие модули, которые запрашивают путь к файлу. Этот тип активов обычно обозначается как Статический Активов, поскольку они никоим образом не связаны. webpack
только пачки файлов require
d или import
ed (ES6). Кроме того, в зависимости от вашего webpack
конфигурация, ваш корень проекта может не всегда соответствовать тому, что выводится внутри вашей продукции строит.
на основе документации electron-vue Структура Проекта / Дерево Файлов, вы найдете, что только webpack
связки и static/
каталог доступны в производственных сборках. electron-vue также имеет удобный __static
глобальная переменная, которая может указать путь к этому в рамках разработки и производства. Вы можете использовать эту переменную аналогично тому, как это было бы с __dirname
и path.join
to доступ к файлам JSON, или действительно любые файлы.
решение для статических активов
кажется, текущая версия electron-vue boilerplate уже решил это для вас, но я собираюсь описать, как это настроено с webpack
как он может применяться не только к файлам JSON и как он также может применяться для любого webpack
+ electron
настройка. Следующее решение предполагает ваш webpack
сборки в отдельную папку, которую мы будем использовать dist/
в этом случае, предполагает, что ваша webpack
конфигурация находится в корневом каталоге вашего проекта и предполагает process.env.NODE_ENV
установлено значение development
во время разработки.
на static/
каталог
во время разработки нам нужно место для хранения наших статических активов, поэтому давайте разместим их в каталоге под названием static/
. Здесь мы можем поместить файлы, такие как JSONs, которые нам нужно будет прочитать с помощью fs
или какой-либо другой модуль, который требует полного пути к файлу.
теперь мы нужно сделать это static/
каталог ресурсов в производстве строит.
но
webpack
не обрабатывает эту папку вообще, что мы можем сделать?
давайте использовать простой copy-webpack-plugin
. Внутри нашего webpack
файл конфигурации, мы можем добавить этот плагин при строительстве для производства и настройте его для копирования .
new CopyWebpackPlugin([
{
from: path.join(__dirname, '/static'),
to: path.join(__dirname, '/dist/static'),
ignore: ['.*']
}
])
Итак, активы находятся в производстве, но как получить путь к этой папке как в разработке, так и в производстве?
создание глобального __static
переменная
какой смысл делать это
__static
переменной?
используя
__dirname
не является надежным вwebpack
+electron
настройки. Во время разработки__dirname
мог бы быть в ссылке на каталог, который существует в вашемsrc/
файлы. В производстве, так какwebpack
связки нашиsrc/
файлы в один скрипт, этот путь вы сформировали, чтобы добраться доstatic/
больше не существует. Кроме того, те файлы, которые вы положили внутрьsrc/
не былоrequire
d илиimport
Эд никогда не делает его к вашему строению продукции.при обработке различий в структуре проекта от разработки и производства, пытаясь получить путь к
static/
будет очень раздражать во время разработки, чтобы всегда проверять вашprocess.env.NODE_ENV
.
Итак, давайте упростим это, создав один источник истины.
с помощью webpack.DefinePlugin
мы можем установить наш __static
переменная только в развитии чтобы получить путь, который указывает на <projectRoot>/static/
. В зависимости от того, есть ли у вас несколько webpack
конфигурации, вы можете применить это как main
и renderer
настройки процесса.
new webpack.DefinePlugin({
'__static': `"${path.join(__dirname, '/static').replace(/\/g, '\\')}"`
})
в производстве нам нужно установить __static
переменной вручную в коде. Вот что мы можем сделать...
.HTML-код ()
<!-- Set `__static` path to static files in production -->
<script>
if (process.env.NODE_ENV !== 'development') window.__static = require('path').join(__dirname, '/static').replace(/\/g, '\\')
</script>
<!-- import webpack bundle -->
main.js (
Я думаю, что путаница (если она есть) может возникнуть из-за того, что webpack не только "пакеты", вложения, вещи, код и т. д... но также обрабатывать контент с его плагинами.
HTML-приложение является хорошим примером, так как он просто генерирует HTML-файл во время сборки.
и как это относится к проблеме с конфигурационным файлом?, ну, в зависимости от того, как вы "требуете" файл "config", какой плагин вы используете для обработки этого контента.
вы могли бы быть встраивание его, или просто загрузка его в виде текста, из файловой системы или http, или еще...
в случае файла конфигурации, который, я думаю, вы хотите, чтобы он был проанализирован во время выполнения,
в противном случае это просто причудливые значения жесткого кодирования, которые, возможно, вам лучше просто ввести в исходный код как простые объекты.
и снова в этом случае я думаю, что webpack мало что добавляет к потребностям среды выполнения, так как нет ничего, чтобы предварительно упаковать для чтения при более позднем использовании,
так Я бы, возможно, вместо этого или "потребовал" его, я прочитаю его из файловой системы, с чем-то вроде :
// read it parse it relative to appPath/cwd,
const config = JSON.parse(
fs.readfileSync(
path.join( app.getAppPath(), "config.json" ),
"utf-8"
))
//note: look fs-extra, it does all that minus the app.path plus async
и electron будет читать его из файловой системы или при использовании Electron.require будет читать его из asar / fileSystem (в этом порядке, если я правильно помню, я могу ошибаться),
философия дизайна Webpack сосредоточена на очень простой, но мощной концепции:
преобразование и связывание всего, что фактически используется вашим приложением.
для достижения этого webpack вводит мощную концепцию графика зависимостей, которая способна управлять практически любыми зависимостями (не только *.JS modules) с помощью так называемых погрузчиков.
цель загрузчика-преобразовать вашу зависимость таким образом, чтобы заявление import smth from 'your_dependency'
осмысленное. Например, json-loader
звонки JSON.parse(...)
во время загрузки *.JSON файл и возвращает объект конфигурации. Поэтому, чтобы воспользоваться системой разрешения зависимостей webpack для управления JSONs, начните с установки json-loader
:
$ npm install --save-dev json-loader
изменить webpack.config.js
следующим образом:
module.exports = {
...
module: {
rules: [
{test: /\.json$/, use: 'json-loader'}
]
}
...
};
на этом этапе webpack должен иметь возможность разрешать ваши зависимости JSON по их абсолютным путям, поэтому следующее должно работа (я предполагаю, что здесь у вас есть подкаталог config
вашего корневого контекста dir, содержащего файл sample.json
):
import sampleCfg from './config/sample.json';
но импорт физических путей не приводит к элегантному, надежному и поддерживаемому коду (например, подумайте о тестируемости), поэтому считается хорошей практикой добавлять псевдонимы к вашему webpack.config.js
для абстрагирования от физической .config/
папка из ваших операторов импорта
module.exports = {
...
resolve: {
alias: {
cfg: './config'
}
}
...
}
тогда вы сможете импортировать конфигурацию JSON, как что:
import sampleCfg from 'cfg/sample.json'
наконец, если вы используете SimulatedGREG/electron-vue
шаблон проекта Electron (как вы упомянули в своем посте), тогда у вас есть три файла конфигурации webpack:
.electron-vue/webpack.web.config.js
- используйте этот файл конфигурации, если вы используете этот шаблон только для обычной веб-разработки (т. е. не для создания собственных электронных проектов);.electron-vue/webpack.main.config.js
- используйте этот файл для настройки модуля webpack, который будет работать внутри основной Electron процесс;.electron-vue/webpack.renderer.config.js
- используйте этот файл для процесса визуализации Electron.
вы можете найти более подробную информацию о процессах main и renderer в официальная электронная документация.