无法在 Electron Forge 中使用静态文件

hek*_*ran 3 webpack electron-forge

我无法在 Electron 中一致地加载图像。我正在使用 Electron Forge 和 webpack 模板https://www.electronforge.io/templates/webpack-template

\n\n

我的 src 目录如下所示:

\n\n
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 images\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 black.png\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.css\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.html\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.js\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 renderer.js\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的 HTML 代码如下所示:

\n\n
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 images\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 black.png\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.css\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.html\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.js\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 renderer.js\n
Run Code Online (Sandbox Code Playgroud)\n\n

我用来copy-webpack-plugin复制images目录。

\n\n

当在开发 ( npm run start) 中运行时,开发服务器的根目录是.webpack/renderer这样加载图像的。当在生产中运行时 ( npm run package),HTML 文件正在从文件系统中打开,因此图像标签正在尝试访问.webpack/renderer/main_window/images错误的位置,并且无法加载。

\n\n

我通过执行以下操作使其在开发和生产中都能工作:

\n\n
<img src="images/black.png">\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n

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

\n\n

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

\n\n

我可以想出几种方法来解决这个问题:

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

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

\n\n
<img src="../images/black.png">\n
Run Code Online (Sandbox Code Playgroud)\n\n

有没有办法以编程方式导入?就像是:

\n\n
import \'./images/1.png\';\nimport \'./images/2.png\';\nimport \'./images/3.png\';\n// ...\nimport \'./images/1000.png\';\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n

我还有一个 5MB JSON 文件,需要使用fetch(). 我尝试通过加载程序导入它,但构建过程花费了 5 分钟以上,所以我终止了它。

\n\n

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

\n

zdd*_*zdd 6

对于不想启动服务器来提供静态资源的人,以下是最新版本的++使用electron-forge静态资源的步骤。typescriptwebpackreact

\n

假设您的项目具有以下文件结构:

\n
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n|    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 index.ts\n|    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 index.html\n|    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 App.tsx\n|    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 renderer.ts\n|    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 assets\n|          \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 images/a.png, b.png\n|          \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 fonts/a.ttf, t.ttf\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 forge.config.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.main.config.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.renderer.config.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.plugins.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.rules.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n
Run Code Online (Sandbox Code Playgroud)\n

注意:默认情况下,配置forge已合并,我将其精确到一个单独的文件,请参阅此处了解详细信息。package.jsonforge.config.js

\n

步骤1。

\n

首先我们需要在src/index.ts(这是电子主进程的入口点)中注册一个协议,我们称这个协议为static,稍后您需要将其用作static://您的图像资源的前缀。

\n
\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n|    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 index.ts\n|    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 index.html\n|    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 App.tsx\n|    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 renderer.ts\n|    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 assets\n|          \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 images/a.png, b.png\n|          \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 fonts/a.ttf, t.ttf\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 forge.config.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.main.config.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.renderer.config.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.plugins.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.rules.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n
Run Code Online (Sandbox Code Playgroud)\n

第2步。

\n

然后,在 中webpack.renderer.config.js,使用copy-webpack-plugin插件将静态资源复制到src/assets文件.webpack/renderer

\n
const CopyWebpackPlugin = require(\'copy-webpack-plugin\');\nconst path = require(\'path\');\n\nconst assets = [\'assets\'];\nconst copyPlugins = new CopyWebpackPlugin(\n  {\n    patterns: assets.map((asset) => ({\n      from: path.resolve(__dirname, \'src\', asset),\n      to: path.resolve(__dirname, \'.webpack/renderer\', asset)\n    }))\n  }\n);\n
Run Code Online (Sandbox Code Playgroud)\n

步骤 3.

\n

最后,在 中src/App.tsx,编写 React 代码来渲染图像。

\n
import React from \'react\'\nimport * as ReactDOM from \'react-dom/client\'\n\nconst root = ReactDOM.createRoot(document.getElementById(\'app\'))\nroot.render(<img src=\'static://assets/images/a.png\'/>)\n
Run Code Online (Sandbox Code Playgroud)\n

src/index.html在文件中添加一个 id = \'app\' 的新 div

\n
<body>\n  <div id="app"></div>\n</body>\n
Run Code Online (Sandbox Code Playgroud)\n

并且不要忘记在中引用它src/renderer.ts

\n
import \'./App\';\n
Run Code Online (Sandbox Code Playgroud)\n

故障排除

\n

如果您遇到内容安全策略问题,请将以下行放入您的forge.config.js.

\n
"plugins": [\n    [\n        "@electron-forge/plugin-webpack",\n        {\n            "mainConfig": "./webpack.main.config.js",\n            "devContentSecurityPolicy": "default-src \'self\' \'unsafe-eval\' \'unsafe-inline\' static: http: https: ws:", // <--- this line\n            // ...\n        }\n    ]\n]\n
Run Code Online (Sandbox Code Playgroud)\n

小心unsafe-inline,它可能会导致安全问题,请确保使用安全源,或者如果不需要它,请将其删除。

\n