aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/watch.js
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/watch.js')
-rw-r--r--scripts/watch.js145
1 files changed, 145 insertions, 0 deletions
diff --git a/scripts/watch.js b/scripts/watch.js
new file mode 100644
index 0000000..dab2635
--- /dev/null
+++ b/scripts/watch.js
@@ -0,0 +1,145 @@
1#!/usr/bin/env node
2
3// @ts-check
4
5const { spawn } = require('child_process');
6const electronPath = require('electron');
7const { build, createLogger, createServer } = require('vite');
8
9/** @type string */
10const mode = process.env.MODE = process.env.MODE || 'development';
11
12/** @type {import('vite').LogLevel} */
13const LOG_LEVEL = 'info';
14
15/** @type {import('vite').InlineConfig} */
16const sharedConfig = {
17 mode,
18 build: {
19 watch: {},
20 },
21 logLevel: LOG_LEVEL,
22};
23
24/**
25 * Messages on stderr that match any of the contained patterns will be stripped from output
26 *
27 * @type RegExp[]
28 */
29const stderrFilterPatterns = [
30 // warning about devtools extension
31 // https://github.com/cawa-93/vite-electron-builder/issues/492
32 // https://github.com/MarshallOfSound/electron-devtools-installer/issues/143
33 /ExtensionLoadWarning/,
34];
35
36/**
37 * @param {{name: string; configFile: string; writeBundle: import('rollup').OutputPlugin['writeBundle'] }} config
38 * @returns {Promise<import('rollup').RollupOutput | Array<import('rollup').RollupOutput> | import('rollup').RollupWatcher>}
39 */
40function getWatcher({name, configFile, writeBundle}) {
41 return build({
42 ...sharedConfig,
43 configFile,
44 plugins: [
45 {
46 name,
47 writeBundle,
48 },
49 ],
50 });
51}
52
53/**
54 * Start or restart App when source files are changed.
55 *
56 * @param {import('vite').ViteDevServer} viteDevServer
57 * @returns {Promise<import('rollup').RollupOutput | Array<import('rollup').RollupOutput> | import('rollup').RollupWatcher>}
58 */
59function setupMainPackageWatcher(viteDevServer) {
60 // Write a value to an environment variable to pass it to the main process.
61 const protocol = `http${viteDevServer.config.server.https ? 's' : ''}:`;
62 const host = viteDevServer.config.server.host || 'localhost';
63 const port = viteDevServer.config.server.port;
64 const path = '/';
65 process.env.VITE_DEV_SERVER_URL = `${protocol}//${host}:${port}${path}`;
66
67 const logger = createLogger(
68 LOG_LEVEL,
69 {
70 prefix: '[main]',
71 },
72 );
73
74 /** @type {import('child_process').ChildProcessWithoutNullStreams | null} */
75 let spawnProcess = null;
76
77 return getWatcher({
78 name: 'reload-app-on-main-package-change',
79 configFile: 'packages/main/vite.config.js',
80 writeBundle() {
81 if (spawnProcess !== null) {
82 spawnProcess.kill('SIGINT');
83 spawnProcess = null;
84 }
85
86 spawnProcess = spawn(String(electronPath), ['.']);
87
88 spawnProcess.stdout.on('data', (data) => {
89 if (data.toString().trim() !== '') {
90 logger.warn(data.toString(), {timestamp: true})
91 }
92 });
93
94 spawnProcess.stderr.on('data', (data) => {
95 const trimmedData = data.toString().trim();
96 if (trimmedData === '') {
97 return;
98 }
99 const mayIgnore = stderrFilterPatterns.some((r) => r.test(data));
100 if (mayIgnore) {
101 return;
102 }
103 logger.error(data, { timestamp: true });
104 });
105 },
106 });
107}
108
109/**
110 * Start or restart App when source files are changed.
111 *
112 * @param {import('vite').ViteDevServer} viteDevServer
113 * @returns {Promise<import('rollup').RollupOutput | Array<import('rollup').RollupOutput> | import('rollup').RollupWatcher>}
114 */
115function setupPreloadPackageWatcher(viteDevServer) {
116 return getWatcher({
117 name: 'reload-page-on-preload-package-change',
118 configFile: 'packages/preload/vite.config.js',
119 writeBundle() {
120 viteDevServer.ws.send({
121 type: 'full-reload',
122 });
123 },
124 });
125}
126
127/**
128 * @returns Promise<void>
129 */
130async function setupDevEnvironment() {
131 const viteDevServer = await createServer({
132 ...sharedConfig,
133 configFile: 'packages/renderer/vite.config.js',
134 });
135
136 await viteDevServer.listen();
137
138 await setupPreloadPackageWatcher(viteDevServer);
139 return setupMainPackageWatcher(viteDevServer);
140}
141
142setupDevEnvironment().catch((err) => {
143 console.error(err);
144 process.exit(1);
145});