Created
April 2, 2020 11:45
-
-
Save bengsfort/855c3ef55987ce6de5d56473fdee8338 to your computer and use it in GitHub Desktop.
Client + Server watching/rebuilding with rollup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const loadConfigFile = require('rollup/dist/loadConfigFile'); | |
const rollup = require('rollup'); | |
const fs = require('fs'); | |
const fsPromises = fs.promises; | |
const path = require('path'); | |
const child = require('child_process'); | |
const NOOP = () => {}; | |
const CLIENT_CONFIG = path.resolve(__dirname, '../configs/rollup.client.js'); | |
const SERVER_CONFIG = path.resolve(__dirname, '../configs/rollup.server.js'); | |
const BUILT_SERVER_PATH = path.resolve(__dirname, '../build/server.js'); | |
console.log('Loading server config file at:', SERVER_CONFIG); | |
console.log('Loading client config file at:', CLIENT_CONFIG); | |
const timerPrmise = (interval) => new Promise(resolve => { | |
setTimeout(() => resolve(), interval); | |
}); | |
async function waitForBundle(dir, retries = 10, interval = 150) { | |
let currentTry = 0; | |
let result = false; | |
while (currentTry < retries) { | |
try { | |
await fsPromises.access(dir, fs.constants.R_OK); | |
result = true; | |
currentTry = retries + 1; | |
} catch { | |
currentTry += 1; | |
console.log(`Server bundle doesn't exist yet, retrying... (try ${currentTry}/${retries})`); | |
await timerPromise(interval); | |
} | |
} | |
return result; | |
} | |
async function waitForProcessClosed(childProcess, retries = 10, interval = 150) { | |
let currentTry = 0; | |
while (!childProcess.killed) { | |
await timerPrmise(interval); | |
currentTry += 1; | |
console.log(`Process not killed yet. Retrying... (try ${currentTry}/${retries})`) | |
if (currentTry < retries) process.kill(0); | |
} | |
} | |
function clientWatcher(config) { | |
const watch = rollup.watch(config); | |
watch.on('restart', () => console.log('Client watcher restarted.')); | |
watch.on('change', id => { | |
console.log('Client watcher changed:', id); | |
}); | |
watch.on('event', event => { | |
if (event.code === 'START') { | |
console.log('\n\tClient watcher started.\n\t'); | |
} else if (event.code === 'END') { | |
console.log('Client bundle built.'); | |
} else if (event.code === 'ERROR') { | |
console.log('Client bundle errored.'); | |
} | |
}); | |
return () => watch.close(); | |
} | |
function serverWatcher(config, clientConfig) { | |
const watch = rollup.watch(config); | |
let srvProcess = null; | |
let closeClient = NOOP; | |
watch.on('restart', () => console.log('Server watcher restarted.')); | |
watch.on('change', id => { | |
console.log('Server watcher changed:', id); | |
if (srvProcess) srvProcess.kill('SIGINT'); | |
}); | |
watch.on('event', async event => { | |
if (event.code === 'START') { | |
console.log('\n\tStarting server watcher.\n'); | |
} else if (event.code === 'END') { | |
console.log('Server bundle built. Restarting server...'); | |
// Close shit | |
if (srvProcess) await waitForProcessClosed(srvProcess); | |
if (closeClient) closeClient(); | |
// Wait for bundle | |
const exists = await waitForBundle(BUILT_SERVER_PATH, 10, 1000); | |
if (!exists) { | |
console.log('\nServer bundle is taking too long to build. Retrying once more.\n'); | |
if (!await waitForBundle(BUILT_SERVER_PATH, 20, 1000)) { | |
process.exit(0); | |
} | |
} | |
console.log('\nServer bundle written. Starting server.') | |
// Restart shit | |
srvProcess = child.fork(BUILT_SERVER_PATH, [], { cwd: path.dirname(BUILT_SERVER_PATH) }); | |
closeClient = clientWatcher(clientConfig); | |
} else if (event.code === 'ERROR') { | |
console.log('Server bundle errored.'); | |
} | |
}); | |
return () => watch.close(); | |
} | |
async function main() { | |
const server = await loadConfigFile(SERVER_CONFIG); | |
const client = await loadConfigFile(CLIENT_CONFIG); | |
console.log(` | |
Server warnings: ${server.warnings.count}. | |
Client warnings: ${client.warnings.count}. | |
Flushing warnings. | |
`); | |
server.warnings.flush(); | |
client.warnings.flush(); | |
serverWatcher(server.options, client.options); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment