aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-12-22 19:17:07 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2021-12-22 19:37:20 +0100
commit929171dcba75b51be464e12906801c875ab7647a (patch)
treeae59d77dd1a8dda3ec8118f8f810a783c9103655 /scripts
downloadsophie-929171dcba75b51be464e12906801c875ab7647a.tar.gz
sophie-929171dcba75b51be464e12906801c875ab7647a.tar.zst
sophie-929171dcba75b51be464e12906801c875ab7647a.zip
Initial commit
Project skeleton based on https://github.com/cawa-93/vite-electron-builder but we use react instead of vue and yarn instead of npm.
Diffstat (limited to 'scripts')
-rw-r--r--scripts/build.js50
-rw-r--r--scripts/update-electron-vendors.js55
-rw-r--r--scripts/watch.js145
3 files changed, 250 insertions, 0 deletions
diff --git a/scripts/build.js b/scripts/build.js
new file mode 100644
index 0000000..79cc564
--- /dev/null
+++ b/scripts/build.js
@@ -0,0 +1,50 @@
1#!/usr/bin/env node
2
3// @ts-check
4
5const { build } = require('vite');
6
7/** @type 'production' | 'development' */
8const mode = process.env.MODE = process.env.MODE || 'production';
9
10/** @type string[] */
11const packagesToBuild = [
12 'main',
13 'preload',
14 'renderer',
15];
16
17/**
18 * Builds all packages from `packagesToBuild` sequentially.
19 *
20 * @returns Promise<void>
21 */
22async function buildAll() {
23 const totalTimeLabel = 'Total bundling time';
24 console.time(totalTimeLabel);
25
26 for (const packageToBuild of packagesToBuild) {
27 const consoleGroupName = `package ${packageToBuild}`;
28 console.group(consoleGroupName);
29
30 const timeLabel = 'Bundling time';
31 console.time(timeLabel);
32
33 const packageConfigPath = `packages/${packageToBuild}/vite.config.js`;
34 await build({
35 configFile: packageConfigPath,
36 mode,
37 });
38
39 console.timeEnd(timeLabel);
40
41 console.groupEnd();
42 }
43
44 console.timeEnd(totalTimeLabel);
45}
46
47buildAll().catch((err) => {
48 console.error(err);
49 process.exit(1);
50});
diff --git a/scripts/update-electron-vendors.js b/scripts/update-electron-vendors.js
new file mode 100644
index 0000000..650d394
--- /dev/null
+++ b/scripts/update-electron-vendors.js
@@ -0,0 +1,55 @@
1#!/usr/bin/env node
2
3// @ts-check
4
5const { execSync } = require('child_process');
6const electronPath = require('electron');
7const { writeFile } = require('fs/promises');
8const path = require('path');
9
10/**
11 * Returns versions of electron vendors
12 * The performance of this feature is very poor and can be improved
13 * @see https://github.com/electron/electron/issues/28006
14 *
15 * @returns {NodeJS.ProcessVersions}
16 */
17function getVendors() {
18 const output = execSync(`${electronPath} -p "JSON.stringify(process.versions)"`, {
19 env: {'ELECTRON_RUN_AS_NODE': '1'},
20 encoding: 'utf-8',
21 });
22
23 return JSON.parse(output);
24}
25
26/**
27 * Generates the `.browserlistrc` and `.electron-vendors.cache.json` files.
28 *
29 * @returns Promise<void>
30 */
31function updateVendors() {
32 const electronRelease = getVendors();
33
34 const nodeMajorVersion = electronRelease.node.split('.')[0];
35 const chromeMajorVersion = electronRelease.v8.split('.')[0] + electronRelease.v8.split('.')[1];
36
37 const browserslistrcPath = path.resolve(process.cwd(), '.browserslistrc');
38
39 return Promise.all([
40 writeFile(
41 './.electron-vendors.cache.json',
42 JSON.stringify({
43 chrome: chromeMajorVersion,
44 node: nodeMajorVersion,
45 }, null, 2) + '\n',
46 ),
47
48 writeFile(browserslistrcPath, `Chrome ${chromeMajorVersion}\n`, 'utf8'),
49 ]);
50}
51
52updateVendors().catch((err) => {
53 console.error(err);
54 process.exit(1);
55});
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});