Как управлять конфигурацией для 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/Resourc‌​es/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 только пачки файлов required или imported (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 переменной?

  1. используя __dirname не является надежным в webpack + electron настройки. Во время разработки __dirname мог бы быть в ссылке на каталог, который существует в вашем src/ файлы. В производстве, так как webpack связки наши src/ файлы в один скрипт, этот путь вы сформировали, чтобы добраться до static/ больше не существует. Кроме того, те файлы, которые вы положили внутрь src/ не было required или import Эд никогда не делает его к вашему строению продукции.

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