Как вставить файлы изображений в пакет настольных приложений Electron + React.js + Webpack для Mac OS

Я создаю настольное приложение для Mac OS с режимом Electron + React + Webpack. Когда я создаю настольное приложение Electron в качестве производственной версии, я хотел бы вставить несколько файлов изображений в установочный файл (Test.app и Test.dmg) и использовать изображение следующим образом:

let Logo = process.resourcesPath + '/logo.png';

class Loading extends Component {
  render() {
    return (
        <div className={styles.container}>
          <img className={styles.logo} src={Logo} />
          ...
       </div>
      );
  }
}

Но это приложение не может получить изображение, потому что файл logo.png не был включен в каталог Test.app/Content/Resources/, когда я запускаю команду npm run package и создаю Test.app для Mac OS.

Здесь проблема в следующем:

GET файл: ///Applications/Test.app/Contents/Resources/logo.png net :: ERR_FILE_NOT_FOUND

Я хотел бы вставить этот файл изображения в свой пакет Test.app для Mac OS.

Пожалуйста, помогите мне, как вставить файлы изображений в пакет Test.app для настольного приложения Mac OS.


webpack.config.base.js

import path from 'path';
import webpack from 'webpack';
import { dependencies as externals } from './app/package.json';

export default {
  externals: Object.keys(externals || {}),

  module: {
    rules: [{
      test: /\.jsx?$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          cacheDirectory: true
        }
      }
    }]
  },

  output: {
    path: path.join(__dirname, 'app'),
    filename: 'bundle.js',
    // https://github.com/webpack/webpack/issues/1114
    libraryTarget: 'commonjs2'
  },

  resolve: {
    extensions: ['.js', '.jsx', '.json'],
    modules: [
      path.join(__dirname, 'app'),
      'node_modules',
    ],
  },

  plugins: [
    new webpack.NamedModulesPlugin(),
  ],
};

webpack.config.production.js

import path from 'path';
import webpack from 'webpack';
import validate from 'webpack-validator';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import merge from 'webpack-merge';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import BabiliPlugin from 'babili-webpack-plugin';
import baseConfig from './webpack.config.base';

export default validate(merge(baseConfig, {
  devtool: 'cheap-module-source-map',

  entry: './app/index',

  output: {
    publicPath: '../dist/'
  },

  module: {
    loaders: [
      // Extract all .global.css to style.css as is
      {
        test: /\.global\.css$/,
        loader: ExtractTextPlugin.extract(
          'style-loader',
          'css-loader'
        )
      },

      // Pipe other styles through css modules and append to style.css
      {
        test: /^((?!\.global).)*\.css$/,
        loader: ExtractTextPlugin.extract(
          'style-loader',
          'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
        )
      },

      // Fonts
      { test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?name=fonts/[hash].[ext]&limit=50000&mimetype=application/font-woff' },
      { test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?name=fonts/[hash].[ext]&limit=50000&mimetype=application/font-woff' },
      { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?name=fonts/[hash].[ext]' },
      { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?name=fonts/[hash].[ext]' },
      { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?name=fonts/[hash].[ext]' },

      // Images
      {
        test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
        loader: 'url-loader'
      }
    ]
  },

  plugins: [
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production')
    }),
    new BabiliPlugin({
      // Disable deadcode until https://github.com/babel/babili/issues/385 fixed
      deadcode: false,
    }),
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        screw_ie8: true,
        warnings: false
      }
    }),
    new ExtractTextPlugin('style.css', { allChunks: true }),
    new HtmlWebpackPlugin({
      filename: 'app.html',
      template: 'app/app.html',
      inject: false
    })
  ],

  target: 'electron-renderer'
}));

webpack.config.electron.js

/**
 * Build config for electron 'Main Process' file
 */

import webpack from 'webpack';
import validate from 'webpack-validator';
import merge from 'webpack-merge';
import BabiliPlugin from 'babili-webpack-plugin';
import baseConfig from './webpack.config.base';

export default validate(merge(baseConfig, {
  devtool: 'source-map',

  entry: ['babel-polyfill', './main.development'],

  // 'main.js' in root
  output: {
    path: __dirname,
    filename: './main.js'
  },

  plugins: [
      deadcode: false,
    }),

    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production')
      }
    })
  ],

  target: 'electron-main',

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

раздел скриптов package.json

  "scripts": {
    "test": "cross-env NODE_ENV=test BABEL_DISABLE_CACHE=1 node --trace-warnings ./test/runTests.js",
    "test-all": "npm run lint && npm run flow && npm run test && npm run build && npm run test-e2e",
    "test-watch": "npm test -- --watch",
    "test-e2e": "cross-env NODE_ENV=test BABEL_DISABLE_CACHE=1 node --trace-warnings ./test/runTests.js e2e",
    "lint": "eslint --cache --format=node_modules/eslint-formatter-pretty .",
    "lint-fix": "npm run lint -- --fix",
    "lint-styles": "stylelint app/*.css app/components/*.css --syntax scss",
    "hot-updates-server": "cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack-dev-server/bin/webpack-dev-server --config webpack.config.renderer.dev.js",
    "build": "concurrently \"npm run copy-images\" \"npm run build-main\" \"npm run build-renderer\"",
    "build-dll": "cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.renderer.dev.dll.js --progress --profile --colors",
    "build-main": "cross-env NODE_ENV=production node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.main.prod.js --progress --profile --colors",
    "build-renderer": "cross-env NODE_ENV=production node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.renderer.prod.js --progress --profile --colors",
    "start": "cross-env NODE_ENV=production electron ./app/",
    "prestart": "npm run build",
    "flow": "flow",
    "flow-typed": "rm -rf flow-typed && flow-typed install --overwrite || true",
    "start-hot-renderer": "cross-env HOT=1 NODE_ENV=development electron -r babel-register -r babel-polyfill ./app/main.development",
    "postinstall": "concurrently \"npm run flow-typed\" \"npm run build-dll\" \"install-app-deps\" \"node node_modules/fbjs-scripts/node/check-dev-engines.js package.json\"",
    "dev": "cross-env START_HOT=1 npm run hot-updates-server",
    "package": "npm run build && build --publish never",
    "package-win": "npm run build && build --win --x64",
    "package-linux": "npm run build && build --linux",
    "package-all": "npm run build && build -mwl",
    "cleanup": "mop -v",
    "copy-images": "cp -Rf app/shared/images/ app/dist/images/"
  },
  "browserslist": "electron 1.4",
  "build": {
    "productName": "Test",
    "appId": "org.Test",
    "files": [
      "dist/",
      "node_modules/",
      "app.html",
      "main.js",
      "main.js.map",
      "package.json"
    ],
    "dmg": {
      "contents": [
        {
          "x": 130,
          "y": 220
        },
        {
          "x": 410,
          "y": 220,
          "type": "link",
          "path": "/Applications"
        }
      ]
    },
    "win": {
      "target": [
        "nsis"
      ]
    },
    "linux": {
      "target": [
        "deb",
        "AppImage"
      ]
    },
    "directories": {
      "buildResources": "resources",
      "output": "release"
    }
  },

person Golden Star    schedule 04.05.2017    source источник
comment
Вы используете какой-нибудь загрузчик, например file-loader или url-loader? Было бы здорово, если бы вы разместили свой файл конфигурации webpack.   -  person Julio Betta    schedule 04.05.2017
comment
В ПОРЯДКЕ. Скоро выложу файл webpack ocnfig.   -  person Golden Star    schedule 04.05.2017
comment
Я разместил файлы конфигурации webpack выше.   -  person Golden Star    schedule 04.05.2017
comment
Попробуйте импортировать свое изображение примерно так: import Logo from 'path/to/logo.png';. (замените path/to/ на реальный путь к файлу).   -  person Julio Betta    schedule 04.05.2017
comment
Это возможно, когда это электронное настольное приложение запускается в режиме разработки с помощью команды npm run dev в Mac OS.   -  person Golden Star    schedule 04.05.2017
comment
Оба импортируют логотип из «path / to / logo.png»; и пусть Logo = path.resolve ('./') + '/resources/logo.png'; возможно, когда это электронное настольное приложение запускает команду npm run dev для режима разработки или команду npm run start для производственного режима в Терминале в Mac OS. Но когда я дважды щелкнул Test.app, созданный командой npm run package в Mac OS, это приложение не нашло путь к файлу изображения.   -  person Golden Star    schedule 04.05.2017
comment
Наконец, мне нужно использовать этот путь к изображению в Test.app для Mac OS.   -  person Golden Star    schedule 04.05.2017
comment
Например, я скопировал этот logo.png в каталог [Test_project_code] /node_modules/electron/dist/Electron.app/Contents/Resources/ и выполнил команду npm run dev или npm run start. Затем этот код позволяет Logo = process.resourcesPath + '/logo.png'; получил файл изображения правильно и отображается. Поэтому я хотел бы включить файл logo.png в каталог Test.app/Contents/Resources при создании настольного приложения Test.app с помощью команды npm run package.   -  person Golden Star    schedule 04.05.2017
comment
Попробуйте использовать file-loader для загрузки изображений вместо url-loader. И вместо использования import, как сказано в предыдущем комментарии, используйте const Logo = require("file-loader!path/to/logo.png");. Стоит проверить file-loader документы здесь github.com/webpack-contrib/file-loader   -  person Julio Betta    schedule 04.05.2017
comment
Я добавил ниже код в файл webpack.config.development.js: module {... {test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/, loader: file-loader? Name = [имя]. [ext] & publicPath = resources / img / & outputPath = app / img /}} Но когда я запускаю команду 'npm run package', каталог img и файлы изображений не включаются в Test.app/Contents / Ресурсы / каталога пока нет.   -  person Golden Star    schedule 05.05.2017
comment
Хммм ... вы можете попробовать создать задачу npm для копирования папки изображений в выходной путь перед запуском команды package.   -  person Julio Betta    schedule 05.05.2017
comment
Я еще не понял. Пожалуйста, дайте мне знать с примером, более подробно.   -  person Golden Star    schedule 05.05.2017
comment
вероятно, в вашем package.json есть раздел scripts. создайте следующую задачу: "copy-images": "cp -R path/to/images dist". Затем в задаче package запустите задачу copy-images перед командой build. Примерно так: "package": "npm run copy-images && build ...".   -  person Julio Betta    schedule 05.05.2017
comment
Когда я запускаю команду npm run build с npm run copy-images, каталог изображений был скопирован в каталог dist. Но когда я запускаю команду npm run package, каталог изображений еще не включается в каталог Test.app/Contents/Resources.   -  person Golden Star    schedule 05.05.2017
comment
Покажите, пожалуйста, свой scripts раздел ...   -  person Julio Betta    schedule 05.05.2017
comment
Мой раздел сценария выглядит следующим образом:   -  person Golden Star    schedule 05.05.2017
comment
опубликуйте в исходном вопросе, пожалуйста ...   -  person Julio Betta    schedule 05.05.2017
comment
Я снова разместил свой раздел сценария файла package.json в своем исходном вопросе. Пожалуйста, проверь это.   -  person Golden Star    schedule 05.05.2017


Ответы (1)


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

const { remote } = require('electron');
let tempFolder =path.join( remote.app.getPath("documents"), 'AppFiles');

используйте каталог tempFolder для сохранения изображения.

person Debashis Chowdhury    schedule 16.09.2020