无法在电子伪造中使用静态文件

时间:2020-03-24 21:28:22

标签: webpack electron-forge

我无法始终如一地将图像加载到Electron中。我正在将Electron Forge与webpack模板https://www.electronforge.io/templates/webpack-template

一起使用

我的src目录如下:

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

我的HTML代码如下:

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

我正在使用copy-webpack-plugin复制images目录。

在开发环境(npm run start中运行时,开发服务器的根目录为.webpack/renderer,因此将加载映像。在生产环境(npm run package中运行时,正在从文件系统中打开HTML文件,因此图像标记正尝试访问错误位置且不会加载的.webpack/renderer/main_window/images

我已经做到了,它可以同时在开发和生产中工作

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

这是一种骇客的方式,与文件在src目录中的存储方式不正确。这应该很简单,但是我花了数小时试图弄清楚,还没有真正的解决方案。

我已经看到了在这些链接中表达的解决方案,但是如果不将“ ../”放在路径的前面,我将无法在开发和生产中使用它。

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

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

我可以想到几种解决方法:

  1. webpack配置需要通过某种环境变量或标志来了解它是否正在开发或生产中运行,并更改copy-webpack-plugin的“至”路径。
  2. 更改开发服务器以使其运行,使其根目录为.webpack/renderer/main_window

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

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

是否可以通过编程方式导入?像这样:

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

那我怎么用HTML引用它呢?不用DOM编辑代码就能做到吗?

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

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

加载静态文件是制作网页的基本步骤,并且应该是项目模板的一部分,除非我错过了一些显而易见的内容。

2 个答案:

答案 0 :(得分:1)

我能够通过在生产中运行renderer目录的生产环境中运行静态Express服务器来解决此问题。我将绝对路径(/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 => {
  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);

答案 1 :(得分:0)

我也遇到了在生产环境中加载静态文件的问题,但是我认为我找到了解决该问题的方法。我们可以使用electron-is-dev包来检查应用程序是否正在生产中运行,然后可以为文件指定其他路径。就我而言,我在加载应用程序图标时遇到问题,这是解决该问题的方法:

import isDev from "electron-is-dev";

const createWindow = () => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    height: 1000,
    width: 1000,
    webPreferences: {
      nodeIntegration: true,
    },
  });

  mainWindow.setIcon(
    isDev
      ? path.join(__dirname, "../../src/assets/app.ico")
      : path.join(__dirname, "./assets/app.ico")
  );
};