英文:
Nuxt 3 + Electron no possible configuration to enable SSR
问题
我正在做一个项目(只是出于个人兴趣),要制作一个“更快的文件浏览器”。我习惯于在Nuxt中创建我的Web项目,所以我想尝试是否可以将“Electron与Nuxt”结合起来制作一个简单而不错的应用程序。
对于这个项目,我需要进行一些服务器端渲染(从用户计算机获取目录和驱动器)。我通过使用Nuxt的“集成服务器API路由”来实现这一点。这基本上与REST API的工作方式相同,所以我可以从前端向该路由发起请求。
在浏览器的开发模式下运行时非常好用!但是当我想要从服务器端API获取目录时,功能无法正常工作,因为它无法托管服务器端。
Electron还依赖于“nuxt generate”命令,因为Electron需要一个index.html。当尝试使用“nuxt build”而不是“nuxt generate”时,它不再创建所需的index.html。
有人知道解决办法吗,以确保这仍然能够工作?您可以在我的GitHub仓库上进行尝试。
要在浏览器中运行功能,请使用启动命令yarn dev
,要使用Electron运行它,请使用yarn generate
,然后使用yarn start
来运行应用程序。
英文:
I am working on a project (just for my own interest) to make a faster searching file explorer
. I am used to making my web-projects in Nuxt, so I wanted to try if I could combine electron with Nuxt
to make a nice simple application.
For this project, I need to do some server side rendering (getting directories and drives from the users computer). I do this by using the integrated server api routes
from nuxt. This basically works the same as a rest api, so i can just fetch from my frontend to that route.
Works verry nice in development mode in the browser! But when I want to fetch the directories from the server side api, the functionality does not work because it cannot host the server-side.
Electron also relies on the 'nuxt generate'
command, because electron needs an index.html. When trying to use 'nuxt build'
instead, it does not create the required index.html anymore
.
Any one knows a solution so this still works? You can play around at <a href="https://github.com/ericvdberge/Portfolio-FastExplorer">my github repository.</a>
To run the functionality in the browser, use the startup command yarn dev
, and to run it using electron, use yarn generate
, then use yarn start
to run the application.
答案1
得分: 0
我尝试了多种方法,经过几天的努力,我终于让它工作了。
-
我的第一种方法是使用
import { fork, spawn } from 'child_process'
(child_process 中的 fork 或 spawn 方法之一)来启动允许 SSR 的服务器,通过运行nuxt build
(生成.output/server/index.mjs
)并使用以下方式运行它:fork(path.join(process.env.ROOT, '.output/server/index.mjs'))
当我在 package.json 中使用
electron .
作为命令运行时,这个方法非常有效,因为它确实启动了服务器,并且通过使用window.loadURL('http://localhost:3000')
(而不是 index.html)来加载 SSR 时,前端页面已经被加载了。
但是问题是,在使用 electron-builder 打包应用程序后,fork 或 spawn 从 child_process 不再起作用。这是因为在构建应用程序后,环境中不再包含 node。 -
我的第二种方法(在尝试让第一种方法工作了两天后)是使用
const { pathToFileURL } = require('url')
来加载模块,并在 main.js 电子文件中调用脚本。通过动态导入脚本并使用以下方式运行它来完成这个操作:const modulePath = path.join(process.env.ROOT, '.output/server/index.mjs'); const moduleUrl = pathToFileURL(modulePath).href; const { default: startServer } = await import(moduleUrl); if (typeof startServer === 'function') { startServer(); }
这种方法在开发模式下运行,而且在使用 electron-builder 打包应用程序后也能正常工作! 唯一需要做的额外配置是在你的 package.json 中包含以下文本:
"build": { "extraResources": [ ".output/server/**" ] }
结论:确保你使用第二种方法来使 Nuxt 3 和 Electron 配合实现 SSR。不要忘记先运行服务器脚本,然后创建窗口,例如创建一个名为 startWebServer 的函数和一个名为 createWindow 的函数来运行这段代码:
app.whenReady()
.then(startWebServer)
.then(createWindow)
英文:
I tried multiple approaches, and after a couple of days I got it to work.
-
My first approach, was to use
import { fork, spawn } from 'child_process'
(one of the fork or spawn methods from child_process) to spin up the server that allows SSR by runningnuxt build
(which generates.output/server/index.mjs
) and run it using:fork(path.join(process.env.ROOT, '.output/server/index.mjs'))
This worked great when running
electron .
in my package.json as a command, because it did spin up the server, and by usingwindow.loadURL('http://localhost:3000')
(instead of the index.html), the SSR was working and the frontend page was loaded.<br>
But the problem was that fork or spawn from child_process are not working after packaging the app using electron-builder. This is because the environment does not contain node anymore after building the package in an app. -
My second approach (after trying to make approach 1 work for 2 days) was to use
const { pathToFileURL } = require('url')
to load the module and to call the script in the main.js electron file. This is done by dynamically importing the script and running it by using:const modulePath = path.join(process.env.ROOT, '.output/server/index.mjs'); const moduleUrl = pathToFileURL(modulePath).href; const { default: startServer } = await import(moduleUrl); if (typeof startServer === 'function') { startServer(); }
This method works in development mode, but also after packaging the application using electron-builder!. The only added configuration that you need to do is including the following text in your package.json:<br>
"build": { "extraResources": [ ".output/server/**" ] }
Conclusion: make sure you use the second approach to make SSR work with Nuxt 3 and Electron. Do not forget to run the server script first, and then create the window, so make for example a function called startWebServer and a function called createWindow to run this code:<br>
app.whenReady()
.then(startWebServer)
.then(createWindow)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论