electron渲染打包后的前端项目

最后更新: 2025-12-12

前言

很多情况下嵌套页面内容我们可通过webview、iframe来实现

webview

内嵌的浏览器组件(如Android的Webview,IOS的WKWebView或Electron),它内置了:

  • HTML 解析器
  • CSS渲染引擎
  • JavaScript引擎
  • 网络栈

因此,它可以像完整浏览器一样渲染 HTML、CSS 和 JavaScript。

iframe

浏览器提供的内嵌框架标签,其 src 属性可以指向:

  • 远程url
  • 本地文件
  • 相对路径

但由于浏览器的一些安全限制,通常会禁用file://协议加载本地iframe,会需要做一定的配置。

electron

过往electron中使用的就是webview,但在≥5的版本中,electron webvie 默认情况下已经被弃用,转而提出的是BrowserView + WebContents的方式,虽然不是字面上的webview,但功能类似。

渲染单页应用

单页应用结构

前端项目(如react/vue)打包后通常会生成:

  • index.html
  • bundle.js
  • *.css
  • 静态资源

这些文件是标准的web资源,而要实现渲染便是加载入口文件(即index.html)

react

这里的例子将直接用dist作为项目名演示,实际情况改成项目名做区分更稳妥,以下是目录结构

Plain
1electron-app/ 2├── main.js 3├── preload.js 4├── dist/ 5│ ├── index.html 6│ ├── bundle.js 7│ └── style.css 8└── package.json

这里我们需要初始化一个BrowserWindow,BrowserWindow创建:

JavaScript
1const mainWindow = new BrowserWindow({ 2 width: 1200, 3 height: 800, 4 webPreferences: { 5 nodeIntegration: false, 6 contextIsolation: true, 7 webSecurity: true, 8 }, 9 autoHideMenuBar: true, 10})

然后使用window.loadUrl加载静态资源即可,但这里有个注意点,就是你的html在去拉css、js文件时需要获取的路径是/dist下的,否则就相当于直接拉的/目录下的文件

这个时候就可以用到protocol 来注册自定义协议:

JavaScript
1protocol.registerSchemesAsPrivileged([ 2 { 3 scheme: 'app', 4 privileges: { 5 standard: true, 6 secure: true, 7 supportFetchAPI: true, 8 corsEnabled: true, 9 allowServiceWorkers: true, 10 }, 11 }, 12])
JavaScript
1protocol.handle('app', (request) => { 2 let url = request.url.replace('app://', '') 3 4 url = url.split('?')[0].split('#')[0] 5 6 if (url.startsWith('./')) { 7 url = url.substring(2) 8 } 9 10 if (url.startsWith('/dist/')) { 11 url = url.replace('/dist/', '') 12 } else if (url.startsWith('dist/')) { 13 url = url.replace('dist/', '') 14 } 15 16 if (url.startsWith('/')) { 17 url = url.substring(1) 18 } 19 20 if (url === '' || url.endsWith('/')) { 21 url = url + 'index.html' 22 } 23 24 const filePath = path.join(__dirname, 'dist', url) 25 return net.fetch('file://' + filePath) 26})

这样当我们访问app://下就能直接转到dist下了,而我们loadUrl也就成了:

JavaScript
1mainWindow.loadURL('app://./index.html')

服务端渲染框架

nextjs

对于服务端渲染的框架,实现的路径会有些许不同,这里的例子将用nextjs选择standalone打包出来的应用,目录结构同上,dist目录换成nextjs默认打包的app

但由于选择在本地启动这个服务加载链接的形式,我们反而不用太在意文件路径了,核心的启动方法:

JavaScript
1async function startNextServer() { 2 const nextDir = path.join(__dirname, 'app', 'server.js') 3 try { 4 nextProcess = fork(nextDir, [], { 5 cwd: __dirname, 6 silent: false, 7 env: { 8 ...process.env, 9 NODE_ENV: 'production', 10 }, 11 }) 12 13 nextProcess.on('close', (code) => { 14 logToFile(`Next.js 进程退出,代码 ${code}`) 15 }) 16 nextProcess.on('error', (error) => { 17 logToFile('Next.js 进程启动失败:', error) 18 }) 19 } catch (error) { 20 logToFile('Next.js 进程启动失败:', error) 21 } 22}

加载的端口也就取决于你启动的端口了,这里是默认:

JavaScript
1await startNextServer() 2await mainWindow.loadURL('http://localhost:3000')