不能在电子伪造中使用静态文件 [英] Can't use static files in electron forge

查看:24
本文介绍了不能在电子伪造中使用静态文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法始终如一地在 Electron 中加载图像.我正在使用带有 webpack 模板的 Electron Forge

https://github.com/electron-userland/electron-forge/issues/941

我能想到几个方法来解决这个问题:

  1. webpack 配置需要通过某种环境变量或标志知道它是在开发还是生产中运行,并更改 copy-webpack-plugin 的to"路径.
  2. 更改开发服务器运行,使其根目录为.webpack/renderer/main_window

我已经看到了将图像导入 renderer.js 的建议,但我有几千张图像.我应该这样做吗?

import './images/1.png';导入'./images/2.png';导入'./images/3.png';//...导入'./images/1000.png';

有没有办法以编程方式导入?类似的东西:

let imageMap = {};for (let i of Iter.range(1, 1001)) {let image = import(`./images/${i}.png`);imageMap[i] = 图像;}

那我如何在 HTML 中引用它?可以不用DOM编辑代码吗?

我不想将我的图像导入我的 JavaScript 文件并通过 webpack 加载器运行它们.我只想以一种在开发和生产中都适用的方式从我的 HTML 代码中引用静态文件.

我还有一个 5MB 的 JSON 文件,我需要使用 fetch() 访问它.我试图通过加载程序导入它,但构建过程花了 5 多分钟,我把它杀死了.

加载静态文件是制作网页的基本部分,应该是项目模板的一部分,除非我遗漏了一些非常明显的东西.

解决方案

我能够通过在生产中运行静态 Express 服务器来解决这个问题,该服务器为 renderer 目录提供服务.我使用绝对路径 (/images/foo.png) 作为图像标签,并且可以访问我的静态文件.

webpack.renderer.config.js

const path = require('path');const rules = require('./webpack.rules');const CopyWebpackPlugin = require('copy-webpack-plugin');const assets = ['data', 'images'];const copyPlugins = assets.map(asset => {返回新的 CopyWebpackPlugin([{来自:path.resolve(__dirname, 'src', asset),至:资产}]);});模块.出口 = {模块: {规则: [...规则,],},插件: [...复制插件,]};

main.js

import { app, BrowserWindow } from 'electron';从路径"导入路径;从快递"导入快递;函数 isDebug() {返回 process.env.npm_lifecycle_event === '开始';}//处理安装/卸载时在 Windows 上创建/删除快捷方式.if (require('electron-squirrel-startup')) {//eslint-disable-line global-require应用程序退出();}const createWindow = () =>{//创建浏览器窗口.const mainWindow = new BrowserWindow({宽度:1200,高度:740,});如果(isDebug()){//创建浏览器窗口.mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);mainWindow.webContents.openDevTools();} 别的 {const exApp = express();exApp.use(express.static(path.resolve(__dirname, '..', 'renderer')));const server = exApp.listen(0, () => {console.log(`端口是 ${server.address().port}`);mainWindow.loadURL(`http://localhost:${server.address().port}/main_window/`);});}};//当 Electron 完成时将调用此方法//初始化并准备好创建浏览器窗口.//部分API只有在该事件发生后才能使用.app.on('ready', createWindow);

I'm having trouble getting images to load in Electron consistently. I'm using Electron Forge with the webpack template https://www.electronforge.io/templates/webpack-template

My src directory looks like this:

├── images
│   └── black.png
├── index.css
├── index.html
├── index.js
├── main.js
└── renderer.js

My HTML code looks like this:

<img src="images/black.png">

I'm using copy-webpack-plugin to copy the images directory.

When running in development (npm run start) the root of the dev server is .webpack/renderer so the image loads. When running in production (npm run package) the HTML file is being opened from the file system so the image tag is trying to access .webpack/renderer/main_window/images which is the wrong location and it doesn't load.

I have gotten it to work in both development and production by doing:

<img src="../images/black.png">

This is a hacky way and isn't correct to the way the files are stored in the src directory. This is something that should be simple but I've spent hours trying to figure it out and don't have a real solution yet.

I've seen a solution expressed in these links but I could not get it to work in both development and production without putting "../" in front of the path.

https://github.com/electron-userland/electron-forge/issues/1196

https://github.com/electron-userland/electron-forge/issues/941

I can think of a few ways to solve this:

  1. The webpack config needs to know via some kind of environment variable or flag if it is running in development or production and change the copy-webpack-plugin's "to" path.
  2. Change the development server to run so its root is .webpack/renderer/main_window

I've seen the recommendation to import the image into renderer.js but I have a few thousand images. Should I do it like this?

import './images/1.png';
import './images/2.png';
import './images/3.png';
// ...
import './images/1000.png';

Is there a way to programmatically import? Something like:

let imageMap = {};
for (let i of Iter.range(1, 1001)) {
  let image = import(`./images/${i}.png`);
  imageMap[i] = image;
}

Then how would I refer to it in HTML? Can it be done without DOM editing code?

I prefer not to import my images into my JavaScript file and run them through webpack loaders. I just want to reference static files from my HTML code in a way that works in both development and production.

I also have a 5MB JSON file that I need to access using fetch(). I tried to import this through a loader but the build process took more than 5 minutes and I killed it.

Loading static files is a basic part of making web pages and should be a part of the project template unless I am missing something super obvious.

解决方案

I was able to solve this by running a static Express server in production serving the renderer directory. I use absolute paths (/images/foo.png) for image tags and can access my static files.

webpack.renderer.config.js

const path = require('path');
const rules = require('./webpack.rules');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const assets = ['data', 'images'];
const copyPlugins = assets.map(asset => {
  return new CopyWebpackPlugin([
    {
      from: path.resolve(__dirname, 'src', asset),
      to: asset
    }
  ]);
});

module.exports = {
  module: {
    rules: [
      ...rules,
    ],
  },
  plugins: [
    ...copyPlugins,
  ]
};

main.js

import { app, BrowserWindow } from 'electron';
import path from 'path';
import express from 'express';

function isDebug() {
  return process.env.npm_lifecycle_event === 'start';
}

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) { // eslint-disable-line global-require
  app.quit();
}

const createWindow = () => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 1200,
    height: 740,
  });

  if (isDebug()) {
    // Create the browser window.
    mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);
    mainWindow.webContents.openDevTools();
  } else {
    const exApp = express();
    exApp.use(express.static(path.resolve(__dirname, '..', 'renderer')));
    const server = exApp.listen(0, () => {
      console.log(`port is ${server.address().port}`);
      mainWindow.loadURL(`http://localhost:${server.address().port}/main_window/`);
    });
  }
};

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

这篇关于不能在电子伪造中使用静态文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆