DEV Community

Cover image for Como criar um app Electron usando Vite
Rafael Beraldo
Rafael Beraldo

Posted on • Edited on

Como criar um app Electron usando Vite

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 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 └── ... 
Enter fullscreen mode Exit fullscreen mode

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() } }) 
Enter fullscreen mode Exit fullscreen mode

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 ."  }, ... 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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() 
Enter fullscreen mode Exit fullscreen mode

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" }, ... 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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()] }) 
Enter fullscreen mode Exit fullscreen mode

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" }, ... 
Enter fullscreen mode Exit fullscreen mode

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

Referências

Top comments (0)