This article is also in english.
Então você quer disponibilizar seu novo aplicativo em Vite usando Electron, mas não quer usar o código pronto dos outros. Vamos entender como funciona e fazer o nosso próprio.
Criar um app Vite
Nós vamos utilizar a estrutura de arquivos do Vite como base do nosso projeto. Inicie com o comando:
$ npm create vite@latest
Depois siga as instruções no terminal. Neste exemplo eu utilizei o preset react-ts
. Mas também funciona com Vuejs e provavelmente todos outros.
Adicione o Electron
Agora adicionamos o Electron ao nosso projeto:
$ npm i -D electron@latest
Depois criamos um diretório electron
na raíz, e dois arquivos main.js
e preload.js
. Nossa estrutura de arquivos ficou assim:
project-root/
├── electron/
│ ├── main.js
│ └── preload.js
├── src/
│ └── ...
├── index.html
├── package.json
├── vite.config.ts
└── ...
Arquivo de entrada do Electron
Electron precisa de um arquivo de entrada para funcionar, vamos editar o electron/main.js
:
const { app, BrowserWindow, shell } = require('electron')
const { join } = require('path')
if (!app.requestSingleInstanceLock()) {
app.quit()
process.exit(0)
}
let win = null
async function createWindow () {
win = new BrowserWindow({
title: 'Main window',
width: 1024,
height: 768,
webPreferences: {
preload: join(__dirname, '../electron/preload.js'),
nodeIntegration: true
}
})
if (app.isPackaged) {
// win.removeMenu()
win.loadFile(join(__dirname, '../dist/index.html'))
} else {
// Vite's dev server
win.loadURL('http://localhost:5173')
win.webContents.openDevTools()
}
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
win = null
if (process.platform !== 'darwin') app.quit()
})
app.on('second-instance', () => {
if (win) {
// Focus on the main window if the user tried to open another
if (win.isMinimized()) win.restore()
win.focus()
}
})
app.on('activate', () => {
const allWindows = BrowserWindow.getAllWindows()
if (allWindows.length) {
allWindows[0].focus()
} else {
createWindow()
}
})
O arquivo preload.js
vai ficar em branco para esse tutorial. Mas você provavelmente vai utilizar num aplicativo real.
Adicione-o ao package.json
:
...
+ "main": "electron/main.js",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
+ "electron:dev": "electron ."
},
...
Você já pode testar, execute o dev server do Vite num terminal, e do Electron em outro:
# Primeiro terminal
$ npm run dev
# Segundo terminal
$ npm run electron:dev
Repare que estão completamente desacoplados, o HMR funciona normalmente já que só estamos abrindo o dev server do Vite no Electron.
Mas eu quero executar de um único terminal/comando!
Para isso podemos criar um script customizado. Crie um novo arquivo scripts/dev.mjs
com:
import { spawn } from 'child_process'
import { createServer } from 'vite'
import electron from 'electron'
const server = await createServer({ configFile: 'vite.config.ts' })
spawn(electron, ['.'], { stdio: 'inherit' }).once('exit', process.exit)
await server.listen()
E atualize o script no package.json
:
...
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
- "electron:dev": "electron ."
+ "electron:dev": "node scripts/dev.mjs"
},
...
Agora você pode abrir ambos dev server num único comando npm run electron:dev
.
Note que nesse exemplo não teremos Live Reload nem TypeScript no electron/main.js
. Para isso funcionar você pode implementar algo parecido com isso. Na minha opinião não é necessário na maioria dos casos.
Gerando o executável
Nosso dev server está funcionando bem. Agora temos que gerar o executável do app.
Vamos usar o electron-builder. Adicione ao projeto:
$ npm i -D electron-builder
E precisamos de uma arquivo de configuração, crie o electron-builder.yaml
na raíz:
# https://www.electron.build/configuration/configuration
appId: your.app.id
asar: true
directories:
output: release/${version}
files:
- dist
- electron
mac:
artifactName: "${productName}_${version}.${ext}"
target:
- dmg
win:
target:
- target: nsis
arch:
- x64
artifactName: "${productName}_${version}.${ext}"
nsis:
oneClick: false
perMachine: false
allowToChangeInstallationDirectory: true
deleteAppDataOnUninstall: false
Adicione a propriedade base
ao arquivo de configuração do Vite vite.config.ts
:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
base: './',
plugins: [react()]
})
Isso adiciona o prefixo ./
em todos assets, necessário para funcionar com o protocolo file://
do Electron.
Agora adicione o script ao package.json
:
...
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"electron:dev": "node scripts/dev.mjs",
+ "electron:build": "npm run build && electron-builder"
},
...
Como você pode ver, iremos primeiramente executar a build do Vite, e depois do Electron.
A build do Vite estará localizada no diretório dist
, a build do Electron estará localizada no diretório release
. Adicione ambos ao .gitignore
.
Agora você pode buildar o app com o comando npm run electron:build
.
Eeee é isso! Você agora tem seu app Electron usando Vite!
Código completo do tutorial: https://github.com/rafaberaldo/vite-electron
Top comments (0)