不能在电子伪造中使用静态文件 [英] Can't use static files in electron forge
问题描述
我无法始终如一地在 Electron 中加载图像.我正在使用带有 webpack 模板的 Electron Forge
https://github.com/electron-userland/electron-forge/issues/941
我能想到几个方法来解决这个问题:
- webpack 配置需要通过某种环境变量或标志知道它是在开发还是生产中运行,并更改 copy-webpack-plugin 的to"路径.
- 更改开发服务器运行,使其根目录为
.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:
- 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.
- 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屋!