Executando verificação de segurança...
1

Node: como trabalhar com recriação de processos filhos no Windows?

O problema

A situação é a seguinte: eu tô trabalhando em um projeto Electron e tô tendo um problema com a recriação do processo filho que exibe a janela no Windows. Sempre que há alguma alteração no código main, o processo filho do Electron precisa ser recriado pra que a alteração seja vista na janela. Porém, eu sou obrigado a matar o processo pai todas as vezes, pra que o processo filho seja encerrado e rodo o script pra recriar o processo pai - e, consequentemente, o filho. Em tese, o processo pai não precisaria ser encerrado pra que a alteração seja implementada na janela, apenas o processo filho. A minha ideia era criar uma função pra encerrar o processo filho e recriá-lo, porém o Windows parece lidar de uma maneira peculiar com processos. Digo isso, porque tentei fazer isso pelo Linux e tudo fluiu naturalmente. Eu encerrava o processo filho, ligado ao Electron, e spawnava um novo processo filho em seguida com o novo conteúdo da janela. Já no Windows, não funciona dessa forma. Se eu encerro o processo filho, o processo pai também é encerrado e a única forma de criar um filho que não mate o pai (que creep) quando encerrado é criando um processo sem ponte, só que se eu faço isso, o processo filho continua rodando mesmo que o processo pai tente encerrar. Na prática, isso significa várias janelas sendo criadas pra cada alteração feita.

Uma breve explicação do Electron

O que é o Electron?

Em resumo, é um framework Javascript usado pra construir aplicações desktop sendo um navegador com uma integração mais profunda com o sistema (que permite lidar com notificações, tray, gerenciamento de janelas, etc).

Explicando main e renderer

Basicamente, a organização do Electron funciona numa divisão de dois elementos principais: main e renderer. Como o nome deste último já deixa claro, ele se refere ao código que lida com a renderização, a parte visual. Ela não importa muito (nesse caso), porque o Electron apenas o consome (em development mode, geralmente por meio de um localhost que em hot reload já exibe atualizações pra cada alteração). Já o elemento main lida com a parte estrutural do Electron, como construção de janelas, o tamanho delas, o comportamento do aplicativo desktop como um todo. Essa parte fica a cargo do próprio Electron e cada alteração feita não é imediatamente refletida como acontece no hot reload. Porém, a ideia com a implementação que tô tentando e onde encontrei o problema é criar uma espécie de reload pra que, a cada interação, o processo anterior seja encerrado e um novo seja criado com as alterações do código.

O que eu já tentei

Bem, pra me ajudar (se isso for possível), eu precisaria de alguém que pudesse me explicar como eu posso criar um processo filho que continue conectado ao pai, mas que não o encerre quando ele, em si, for encerrado.

Em todas as minhas tentativas, eu utilizei o spawn do Node, inspirado por outras implementações semelhantes e por se encaixar melhor na situação, afinal eu só quero criar o novo processo quando o anterior for encerrado e isso é possível por meio da função unref().

Na minha primeira tentativa (e que funciona no Linux), eu tentei utiliza a seguinte configuração:

const child = spawn('yarn', ['dev:electron'], {
    stdio: 'inherit',
    shell: process.env.SHELL,
})
child.unref()
app.quit()

Obs.: app.quit() é a função executada pra matar o processo filho do Electron. Porém, no Windows, essa função tem encerrado todo o processo pai também - diferente do Linux.

Na segunda tentativa, eu tentei o seguinte:

const child = spawn('yarn', ['dev:electron'], {
    detached: true,
    stdio: 'inherit',
    shell: process.env.SHELL,
})
child.unref()
app.quit()

Mas, o detached como true faz com que o novo processo seja criado sem referência ao processo pai e acaba por recriar diferentes processos independentes que abrem inúmeras janelas.

Reafirmando a dúvida

Como, então, no Windows, criar um processo filho sem matar o processo pai quando ele for encerrado e sem criar um processo independente (ou seja, criar um processo que esteja ainda em comunicação com o processo pai)?

Carregando publicação patrocinada...