215 lines
6.0 KiB
JavaScript
215 lines
6.0 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
const {createServer, build, createLogger} = require('vite');
|
|
const electronPath = require('electron');
|
|
const {spawn} = require('child_process');
|
|
const node = 'node' + (process.platform === 'win32' ? '.exe' : '');
|
|
|
|
const server = !process.argv.includes('--noserver');
|
|
|
|
/** @type 'production' | 'development'' */
|
|
const mode = process.env.MODE = process.env.MODE || 'development';
|
|
|
|
|
|
/** @type {import('vite').LogLevel} */
|
|
const logLevel = 'info';
|
|
|
|
|
|
/** Messages on stderr that match any of the contained patterns will be stripped from output */
|
|
const stderrFilterPatterns = [
|
|
/**
|
|
* warning about devtools extension
|
|
* @see https://github.com/cawa-93/vite-electron-builder/issues/492
|
|
* @see https://github.com/MarshallOfSound/electron-devtools-installer/issues/143
|
|
*/
|
|
/ExtensionLoadWarning/,
|
|
];
|
|
|
|
const setupServerPackageWatcher = () => {
|
|
const logger = createLogger(logLevel, {
|
|
prefix: '[srvr]',
|
|
allowClearScreen: false,
|
|
});
|
|
|
|
let spawnProcess = null;
|
|
|
|
const processDied = () => {
|
|
logger.error('Server has died.', {timestamp: false});
|
|
spawnProcess = null;
|
|
};
|
|
|
|
return build({
|
|
mode,
|
|
logLevel,
|
|
build: {
|
|
watch: {},
|
|
},
|
|
configFile: 'packages/server/vite.config.js',
|
|
plugins: [{
|
|
name: 'reload-server-on-server-package-change',
|
|
writeBundle() {
|
|
if (spawnProcess !== null) {
|
|
spawnProcess.off('exit', processDied);
|
|
spawnProcess.kill('SIGINT');
|
|
spawnProcess = null;
|
|
}
|
|
|
|
spawnProcess = spawn(node, ['./index.cjs'], {
|
|
cwd: './packages/server/dist',
|
|
env: {
|
|
...process.env,
|
|
FORCE_COLOR: "true"
|
|
}
|
|
});
|
|
|
|
/** Proxy all logs */
|
|
spawnProcess.stdout.on('data', d => d.toString().trim() && d.toString().trim().split('\n').forEach(str => logger.info(str, {timestamp: false})));
|
|
|
|
/** Proxy error logs but stripe some noisy messages. See {@link stderrFilterPatterns} */
|
|
spawnProcess.stderr.on('data', d => {
|
|
const data = d.toString().trim();
|
|
if (!data) return;
|
|
const mayIgnore = stderrFilterPatterns.some((r) => r.test(data));
|
|
if (mayIgnore) return;
|
|
data.split('\n').forEach(d => logger.error(d, {timestamp: false}));
|
|
});
|
|
|
|
/** Stops the watch script when the application has been quit */
|
|
spawnProcess.on('exit', processDied);
|
|
},
|
|
}],
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Setup watcher for `main` package
|
|
* On file changed it totally re-launch electron app.
|
|
* @param {import('vite').ViteDevServer} watchServer Renderer watch server instance.
|
|
* Needs to set up `VITE_DEV_SERVER_URL` environment variable from {@link import('vite').ViteDevServer.resolvedUrls}
|
|
*/
|
|
|
|
const setupMainPackageWatcher = ({resolvedUrls}) => {
|
|
process.env.VITE_DEV_SERVER_URL = resolvedUrls.local[0];
|
|
|
|
const logger = createLogger(logLevel, {
|
|
prefix: '[main]',
|
|
allowClearScreen: false,
|
|
});
|
|
|
|
/** @type {ChildProcessWithoutNullStreams | null} */
|
|
let spawnProcess = null;
|
|
|
|
return build({
|
|
mode,
|
|
logLevel,
|
|
build: {
|
|
/**
|
|
* Set to {} to enable rollup watcher
|
|
* @see https://vitejs.dev/config/build-options.html#build-watch
|
|
*/
|
|
watch: {},
|
|
},
|
|
configFile: 'packages/main/vite.config.js',
|
|
plugins: [{
|
|
name: 'reload-app-on-main-package-change',
|
|
writeBundle() {
|
|
/** Kill electron ff process already exist */
|
|
if (spawnProcess !== null) {
|
|
spawnProcess.off('exit', process.exit);
|
|
spawnProcess.kill('SIGINT');
|
|
spawnProcess = null;
|
|
}
|
|
|
|
/** Spawn new electron process */
|
|
spawnProcess = spawn(String(electronPath), ['.'], {
|
|
env: {
|
|
...process.env,
|
|
FORCE_COLOR: "true"
|
|
}
|
|
});
|
|
|
|
/** Proxy all logs */
|
|
spawnProcess.stdout.on('data', d => d.toString().trim() && logger.warn(d.toString(), {timestamp: false}));
|
|
|
|
/** Proxy error logs but stripe some noisy messages. See {@link stderrFilterPatterns} */
|
|
spawnProcess.stderr.on('data', d => {
|
|
const data = d.toString().trim();
|
|
if (!data) return;
|
|
const mayIgnore = stderrFilterPatterns.some((r) => r.test(data));
|
|
if (mayIgnore) return;
|
|
logger.error(data, {timestamp: false});
|
|
});
|
|
|
|
/** Stops the watch script when the application has been quit */
|
|
spawnProcess.on('exit', process.exit);
|
|
},
|
|
}],
|
|
});
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Setup watcher for `preload` package
|
|
* On file changed it reload web page.
|
|
* @param {import('vite').ViteDevServer} watchServer Renderer watch server instance.
|
|
* Required to access the web socket of the page. By sending the `full-reload` command to the socket, it reloads the web page.
|
|
*/
|
|
const setupPreloadPackageWatcher = ({ws}) =>
|
|
build({
|
|
mode,
|
|
logLevel,
|
|
build: {
|
|
/**
|
|
* Set to {} to enable rollup watcher
|
|
* @see https://vitejs.dev/config/build-options.html#build-watch
|
|
*/
|
|
watch: {},
|
|
},
|
|
configFile: 'packages/preload/vite.config.js',
|
|
plugins: [{
|
|
name: 'reload-page-on-preload-package-change',
|
|
writeBundle() {
|
|
ws.send({
|
|
type: 'full-reload',
|
|
});
|
|
},
|
|
}],
|
|
});
|
|
|
|
|
|
(async () => {
|
|
try {
|
|
|
|
/**
|
|
* Renderer watcher
|
|
* This must be the first,
|
|
* because the {@link setupMainPackageWatcher} and {@link setupPreloadPackageWatcher} depend on the renderer params
|
|
*/
|
|
const rendererWatchServer = await createServer({
|
|
mode,
|
|
logLevel,
|
|
configFile: 'packages/renderer/vite.config.js',
|
|
});
|
|
|
|
/**
|
|
* Should launch watch server before create other watchers
|
|
*/
|
|
await rendererWatchServer.listen();
|
|
|
|
/**
|
|
* See {@link setupPreloadPackageWatcher} JSDoc
|
|
*/
|
|
await setupPreloadPackageWatcher(rendererWatchServer);
|
|
|
|
/**
|
|
* See {@link setupMainPackageWatcher} JSDoc
|
|
*/
|
|
await setupMainPackageWatcher(rendererWatchServer);
|
|
if(server) await setupServerPackageWatcher();
|
|
} catch (e) {
|
|
console.error(e);
|
|
process.exit(1);
|
|
}
|
|
})();
|