Javascript 在Electron中提供静态文件(React应用程序)
我正在做一个项目,我需要在Electron中构建一个桌面应用程序。大部分功能将内置在React中,但还有一部分我们需要集成第三方静态HTML杂志。我需要一些关于如何做这件事的建议。我目前正在构建一个概念验证应用程序,并以此为基础 如何在/static/I服务器静态HTML文件中添加该文件。我知道我可以在express中实现,但我真的不想只为服务静态文件而包含整个express框架Javascript 在Electron中提供静态文件(React应用程序),javascript,node.js,reactjs,electron,Javascript,Node.js,Reactjs,Electron,我正在做一个项目,我需要在Electron中构建一个桌面应用程序。大部分功能将内置在React中,但还有一部分我们需要集成第三方静态HTML杂志。我需要一些关于如何做这件事的建议。我目前正在构建一个概念验证应用程序,并以此为基础 如何在/static/I服务器静态HTML文件中添加该文件。我知道我可以在express中实现,但我真的不想只为服务静态文件而包含整个express框架 我正在看这个,但不知道如何将它集成到我的react应用程序中,并将其捆绑到electron应用程序中。在您的主文件中
我正在看这个,但不知道如何将它集成到我的react应用程序中,并将其捆绑到electron应用程序中。在您的主文件中
const app = require("app")
app.on("ready", () => {
...
在这里,您可以像在node.js中一样启动服务器
const serveStatic = require('serve-static')
// or
const express = require('express')
...
}
我找到了另一个解决方案,没有使用
express
或service static
,我们只
需要自定义Electron内置的interceptFileProtocol()
,以提供静态内容
代码:(main.js)
(我使用电子模板)
参考:
解释:
- 通常,如果您将React应用程序作为普通网站运行,则所有静态内容都应该由
方法提供。尽管它们使用相对路径,但您的HTTP服务器将处理路径解析工作HTTP[GET]
- 然而,当在电子下运行时,情况会发生变化
- 您的静态内容通常使用相对路径,如
,Electron将使用/picture.jpg
协议而不是文件
协议,并在根路径下查找文件,如HTTP
。因此,像C://
这样的静态内容无法正确加载/picture.jpg
- 通过自定义interceptFileProtocol(),所有静态内容的请求都将指向您的工作目录,而不是Windows(或其他操作系统)根目录
最后,我不确定它是否是所有Electron项目的好解决方案,但如果您已经有了一个
React
项目(或其他SPA)并想用Electron将其包裹起来,那么这个解决方案就可以使用了。作为上面@yeze322伟大答案的补充,这里是一个工作示例,适用于所有不太熟悉节点和电子(如我)的人。我花了一些时间才找到正确的require语句
main.js(来自@yeze322的代码加上所需的导入)
将第三方资源放在resources目录中可以解决这个问题这对我来说很有效,但是我很难使用相对路径要求index.html中的index js文件。通过使用
require('electron')获取应用程序路径,最终要求使用绝对值。remote.app.getAppPath()
在哪里添加它@ChrisDolphin?我在这里遇到了一个大问题,可以在开发模式下正常工作,但是在打包应用程序后,我发现应用程序无法工作,这让我抓狂,我更改了url=path.join(require('electron').remote.app.getAppPath(),WEB_文件夹,url),谢谢,在打包应用程序时,我更改了url=path.join(require('electron').remote.app.getAppPath(),WEB_文件夹,url),谢谢,在打包appHi时,我发现创建自定义的应用程序
协议更容易,因此它不会干扰文件://
,使用registerFileProtocol
(语法与interceptFileProtocol
相同)。此外,您可能需要删除URL的查询参数,如app://foobar.js?version=2
,您应该删除?版本=2
。例如,在Electron应用程序中安装MathJax对我很有用。嘿@ales,我想知道下面的答案对你有用吗?在开发模式上,我使用的是WebPack给我的错误“找不到模块反应”,这意味着模块在没有拦截协议的情况下解决了问题,有什么想法吗?不是针对个人的-但这应该只是对@yeze322答案的评论。我花了一点时间在两个答案之间寻找,试图找出我应该使用哪一个;)谢谢,我能够通过Electron使用它运行Blazor WebAssembly应用程序。将Blazor WebAssembly应用程序制作成静态文件后。
function createWindow () {
window = new BrowserWindow({ width: 800, height: 600 })
window.loadURL(url.format({
pathname: 'index.html', /* Attention here: origin is path.join(__dirname, 'index.html') */
protocol: 'file',
slashes: true
}))
window.on('closed', () => {
window = null
})
}
app.on('ready', () => {
protocol.interceptFileProtocol('file', (request, callback) => {
const url = request.url.substr(7) /* all urls start with 'file://' */
callback({ path: path.normalize(`${__dirname}/${url}`)})
}, (err) => {
if (err) console.error('Failed to register protocol')
})
createWindow()
})
const { app, BrowserWindow, protocol } = require('electron')
const path = require('path')
const url = require('url')
let mainWindow
function createWindow() {
mainWindow = new BrowserWindow({ width: 800, height: 600 })
mainWindow.loadURL(url.format({
pathname: 'index.html', /* Attention here: origin is path.join(__dirname, 'index.html') */
protocol: 'file',
slashes: true
}))
mainWindow.on('closed', function () {
mainWindow = null
})
}
app.on('ready', () => {
protocol.interceptFileProtocol('file', (request, callback) => {
const url = request.url.substr(7) /* all urls start with 'file://' */
callback({ path: path.normalize(`${__dirname}/${url}`) })
}, (err) => {
if (err) console.error('Failed to register protocol')
})
createWindow()
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
if (mainWindow === null) {
createWindow()
}
})