diff options
author | Kristóf Marussy <kristof@marussy.com> | 2021-12-30 00:26:01 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2021-12-30 02:24:28 +0100 |
commit | 61fd13c55f5e69a9d8b32dd0d74b08870783bcce (patch) | |
tree | 4f3f97b1629f3c262bea076b596bc7245ccbc0bd /packages/main | |
parent | Revert "refactor: Switch back to consola for prettyness" (diff) | |
download | sophie-61fd13c55f5e69a9d8b32dd0d74b08870783bcce.tar.gz sophie-61fd13c55f5e69a9d8b32dd0d74b08870783bcce.tar.zst sophie-61fd13c55f5e69a9d8b32dd0d74b08870783bcce.zip |
build: Switch to esbuild
We will build all packages except the frontend (where vite remains in
use) with esbuild.
For some reason, the @yarnpkg/esbuild-plugin-pnp doesn't allow esbuild
to load esm modules and we fall back to commonjs for dependencies.
Hence we had to switch back to node_modules (but still rely on yarn
hardlinking for a more efficient install).
Diffstat (limited to 'packages/main')
-rw-r--r-- | packages/main/esbuild.config.js | 24 | ||||
-rw-r--r-- | packages/main/package.json | 10 | ||||
-rw-r--r-- | packages/main/src/controllers/config.ts | 2 | ||||
-rw-r--r-- | packages/main/src/devTools.ts | 41 | ||||
-rw-r--r-- | packages/main/src/index.ts | 38 | ||||
-rw-r--r-- | packages/main/src/services/ConfigPersistenceService.ts | 2 | ||||
-rw-r--r-- | packages/main/src/utils/logging.ts | 4 | ||||
-rw-r--r-- | packages/main/vite.config.js | 39 |
8 files changed, 70 insertions, 90 deletions
diff --git a/packages/main/esbuild.config.js b/packages/main/esbuild.config.js new file mode 100644 index 0000000..7653078 --- /dev/null +++ b/packages/main/esbuild.config.js | |||
@@ -0,0 +1,24 @@ | |||
1 | // @ts-check | ||
2 | |||
3 | const { node } = require('../../config/build-common'); | ||
4 | const { getConfig } = require('../../config/esbuild-config'); | ||
5 | |||
6 | const externalPackages = ['electron']; | ||
7 | |||
8 | if (process.env.MODE !== 'development') { | ||
9 | externalPackages.push('electron-devtools-installer'); | ||
10 | } | ||
11 | |||
12 | module.exports = getConfig({ | ||
13 | absWorkingDir: __dirname, | ||
14 | entryPoints: [ | ||
15 | 'src/index.ts', | ||
16 | ], | ||
17 | outfile: 'dist/index.cjs', | ||
18 | format: 'cjs', | ||
19 | platform: 'node', | ||
20 | target: node, | ||
21 | external: externalPackages, | ||
22 | }, { | ||
23 | VITE_DEV_SERVER_URL: process.env.VITE_DEV_SERVER_URL || null, | ||
24 | }); | ||
diff --git a/packages/main/package.json b/packages/main/package.json index c4670a8..76eff8e 100644 --- a/packages/main/package.json +++ b/packages/main/package.json | |||
@@ -6,7 +6,6 @@ | |||
6 | "types": "dist-types/index.d.ts", | 6 | "types": "dist-types/index.d.ts", |
7 | "scripts": { | 7 | "scripts": { |
8 | "clean": "rimraf dist", | 8 | "clean": "rimraf dist", |
9 | "build": "vite build", | ||
10 | "typecheck": "tsc" | 9 | "typecheck": "tsc" |
11 | }, | 10 | }, |
12 | "dependencies": { | 11 | "dependencies": { |
@@ -14,7 +13,7 @@ | |||
14 | "@sophie/shared": "workspace:*", | 13 | "@sophie/shared": "workspace:*", |
15 | "electron": "16.0.5", | 14 | "electron": "16.0.5", |
16 | "json5": "^2.2.0", | 15 | "json5": "^2.2.0", |
17 | "lodash": "^4.17.21", | 16 | "lodash-es": "^4.17.21", |
18 | "loglevel": "^1.8.0", | 17 | "loglevel": "^1.8.0", |
19 | "loglevel-plugin-prefix": "^0.8.4", | 18 | "loglevel-plugin-prefix": "^0.8.4", |
20 | "mobx": "^6.3.10", | 19 | "mobx": "^6.3.10", |
@@ -22,14 +21,13 @@ | |||
22 | "ms": "^2.1.3" | 21 | "ms": "^2.1.3" |
23 | }, | 22 | }, |
24 | "devDependencies": { | 23 | "devDependencies": { |
25 | "@types/debug": "^4", | ||
26 | "@types/electron-devtools-installer": "^2.2.1", | 24 | "@types/electron-devtools-installer": "^2.2.1", |
27 | "@types/lodash": "^4.14.178", | 25 | "@types/lodash-es": "^4.17.5", |
28 | "@types/ms": "^0.7.31", | 26 | "@types/ms": "^0.7.31", |
29 | "@types/node": "^17.0.5", | 27 | "@types/node": "^17.0.5", |
30 | "electron-devtools-installer": "^3.2.0", | 28 | "electron-devtools-installer": "^3.2.0", |
29 | "esbuild": "^0.14.9", | ||
31 | "rimraf": "^3.0.2", | 30 | "rimraf": "^3.0.2", |
32 | "typescript": "^4.5.4", | 31 | "typescript": "^4.5.4" |
33 | "vite": "^2.7.7" | ||
34 | } | 32 | } |
35 | } | 33 | } |
diff --git a/packages/main/src/controllers/config.ts b/packages/main/src/controllers/config.ts index 7187ab4..f2467c7 100644 --- a/packages/main/src/controllers/config.ts +++ b/packages/main/src/controllers/config.ts | |||
@@ -18,7 +18,7 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { debounce } from 'lodash'; | 21 | import debounce from 'lodash-es/debounce'; |
22 | import ms from 'ms'; | 22 | import ms from 'ms'; |
23 | import { applySnapshot, getSnapshot, onSnapshot } from 'mobx-state-tree'; | 23 | import { applySnapshot, getSnapshot, onSnapshot } from 'mobx-state-tree'; |
24 | 24 | ||
diff --git a/packages/main/src/devTools.ts b/packages/main/src/devTools.ts index b98974a..6c25b3e 100644 --- a/packages/main/src/devTools.ts +++ b/packages/main/src/devTools.ts | |||
@@ -18,38 +18,35 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import type { App, BrowserWindow } from 'electron'; | 21 | import type { BrowserWindow } from 'electron'; |
22 | 22 | ||
23 | /** | 23 | /** |
24 | * Installs the react and redux developer tools extensions. | 24 | * Installs the react and redux developer tools extensions. |
25 | * | 25 | * |
26 | * We use the redux devtools and connect the mobx store to it with `mst-middlewares`, | 26 | * We use the redux devtools and connect the mobx store to it with `mst-middlewares`, |
27 | * because the mobx-state-tree devtools are currently unmaintained. | 27 | * because the mobx-state-tree devtools are currently unmaintained. |
28 | * | ||
29 | * @param app The electron application instance. | ||
30 | */ | 28 | */ |
31 | export function installDevToolsExtensions(app: App): void { | 29 | export async function installDevToolsExtensions(): Promise<void> { |
32 | app.whenReady().then(async () => { | 30 | const installerPackage = await import('electron-devtools-installer'); |
33 | const { | 31 | const { |
34 | default: installExtension, | 32 | default: installExtension, |
33 | REACT_DEVELOPER_TOOLS, | ||
34 | REDUX_DEVTOOLS, | ||
35 | } = installerPackage.default instanceof Function | ||
36 | ? installerPackage | ||
37 | : installerPackage.default as unknown as typeof import('electron-devtools-installer'); | ||
38 | await installExtension( | ||
39 | [ | ||
35 | REACT_DEVELOPER_TOOLS, | 40 | REACT_DEVELOPER_TOOLS, |
36 | REDUX_DEVTOOLS, | 41 | REDUX_DEVTOOLS, |
37 | } = await import('electron-devtools-installer'); | 42 | ], |
38 | installExtension( | 43 | { |
39 | [ | 44 | forceDownload: false, |
40 | REACT_DEVELOPER_TOOLS, | 45 | loadExtensionOptions: { |
41 | REDUX_DEVTOOLS, | 46 | allowFileAccess: true, |
42 | ], | ||
43 | { | ||
44 | forceDownload: false, | ||
45 | loadExtensionOptions: { | ||
46 | allowFileAccess: true, | ||
47 | }, | ||
48 | }, | 47 | }, |
49 | ); | 48 | }, |
50 | }).catch((err) => { | 49 | ); |
51 | console.error('Failed to install devtools extension', err); | ||
52 | }); | ||
53 | } | 50 | } |
54 | 51 | ||
55 | /** | 52 | /** |
diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts index 7c7be35..f8b6787 100644 --- a/packages/main/src/index.ts +++ b/packages/main/src/index.ts | |||
@@ -50,6 +50,9 @@ import { createMainStore } from './stores/MainStore'; | |||
50 | 50 | ||
51 | const isDevelopment = import.meta.env.MODE === 'development'; | 51 | const isDevelopment = import.meta.env.MODE === 'development'; |
52 | 52 | ||
53 | // Alwayse enable sandboxing. | ||
54 | app.enableSandbox(); | ||
55 | |||
53 | // Use alternative directory when debugging to avoid clobbering the main installation. | 56 | // Use alternative directory when debugging to avoid clobbering the main installation. |
54 | if (isDevelopment) { | 57 | if (isDevelopment) { |
55 | app.setPath('userData', `${app.getPath('userData')}-dev`); | 58 | app.setPath('userData', `${app.getPath('userData')}-dev`); |
@@ -62,9 +65,6 @@ if (!isSingleInstance) { | |||
62 | process.exit(0); | 65 | process.exit(0); |
63 | } | 66 | } |
64 | 67 | ||
65 | // Alwayse enable sandboxing. | ||
66 | app.enableSandbox(); | ||
67 | |||
68 | // Disable chromium's MPRIS integration, which is usually more annoying | 68 | // Disable chromium's MPRIS integration, which is usually more annoying |
69 | // (triggered by random sounds played by websites) than useful. | 69 | // (triggered by random sounds played by websites) than useful. |
70 | app.commandLine.appendSwitch( | 70 | app.commandLine.appendSwitch( |
@@ -90,17 +90,13 @@ function getResourceUrl(relativePath: string): string { | |||
90 | return new URL(relativePath, baseUrl).toString(); | 90 | return new URL(relativePath, baseUrl).toString(); |
91 | } | 91 | } |
92 | 92 | ||
93 | let serviceInjectRelativePath = '../../service-inject/dist/index.cjs'; | 93 | let serviceInjectRelativePath = '../../service-inject/dist/index.js'; |
94 | let serviceInjectPath = getResourcePath(serviceInjectRelativePath); | 94 | let serviceInjectPath = getResourcePath(serviceInjectRelativePath); |
95 | let serviceInject: WebSource = { | 95 | let serviceInject: WebSource = { |
96 | code: readFileSync(serviceInjectPath, 'utf8'), | 96 | code: readFileSync(serviceInjectPath, 'utf8'), |
97 | url: getResourceUrl(serviceInjectRelativePath), | 97 | url: getResourceUrl(serviceInjectRelativePath), |
98 | }; | 98 | }; |
99 | 99 | ||
100 | if (isDevelopment) { | ||
101 | installDevToolsExtensions(app); | ||
102 | } | ||
103 | |||
104 | let mainWindow: BrowserWindow | null = null; | 100 | let mainWindow: BrowserWindow | null = null; |
105 | 101 | ||
106 | const store = createMainStore(); | 102 | const store = createMainStore(); |
@@ -134,13 +130,13 @@ function shouldCancelMainWindowRequest(url: string, method: string): boolean { | |||
134 | return !normalizedUrl.startsWith(getResourceUrl(rendererBaseUrl)); | 130 | return !normalizedUrl.startsWith(getResourceUrl(rendererBaseUrl)); |
135 | } | 131 | } |
136 | 132 | ||
137 | function createWindow(): Promise<unknown> { | 133 | async function createWindow(): Promise<unknown> { |
138 | mainWindow = new BrowserWindow({ | 134 | mainWindow = new BrowserWindow({ |
139 | show: false, | 135 | show: false, |
140 | autoHideMenuBar: true, | 136 | autoHideMenuBar: true, |
141 | webPreferences: { | 137 | webPreferences: { |
142 | devTools: isDevelopment, | ||
143 | sandbox: true, | 138 | sandbox: true, |
139 | devTools: isDevelopment, | ||
144 | preload: getResourcePath('../../preload/dist/index.cjs'), | 140 | preload: getResourcePath('../../preload/dist/index.cjs'), |
145 | }, | 141 | }, |
146 | }); | 142 | }); |
@@ -159,8 +155,14 @@ function createWindow(): Promise<unknown> { | |||
159 | }) | 155 | }) |
160 | }); | 156 | }); |
161 | 157 | ||
162 | webContents.on('will-navigate', (event) => { | 158 | const pageUrl = (isDevelopment && import.meta.env.VITE_DEV_SERVER_URL !== undefined) |
163 | event.preventDefault(); | 159 | ? import.meta.env.VITE_DEV_SERVER_URL |
160 | : getResourceUrl('../renderer/dist/index.html'); | ||
161 | |||
162 | webContents.on('will-navigate', (event, url) => { | ||
163 | if (url !== pageUrl) { | ||
164 | event.preventDefault(); | ||
165 | } | ||
164 | }); | 166 | }); |
165 | 167 | ||
166 | webContents.setWindowOpenHandler(() => ({ action: 'deny' })); | 168 | webContents.setWindowOpenHandler(() => ({ action: 'deny' })); |
@@ -279,10 +281,6 @@ function createWindow(): Promise<unknown> { | |||
279 | callback({ requestHeaders }); | 281 | callback({ requestHeaders }); |
280 | }); | 282 | }); |
281 | 283 | ||
282 | const pageUrl = (isDevelopment && import.meta.env.VITE_DEV_SERVER_URL !== undefined) | ||
283 | ? import.meta.env.VITE_DEV_SERVER_URL | ||
284 | : getResourceUrl('../renderer/dist/index.html'); | ||
285 | |||
286 | return Promise.all([ | 284 | return Promise.all([ |
287 | mainWindow.loadURL(pageUrl), | 285 | mainWindow.loadURL(pageUrl), |
288 | browserView.webContents.loadURL('https://git.marussy.com/sophie/about'), | 286 | browserView.webContents.loadURL('https://git.marussy.com/sophie/about'), |
@@ -307,7 +305,13 @@ app.on('window-all-closed', () => { | |||
307 | } | 305 | } |
308 | }); | 306 | }); |
309 | 307 | ||
310 | app.whenReady().then(createWindow).catch((err) => { | 308 | app.whenReady().then(async () => { |
309 | if (isDevelopment) { | ||
310 | await installDevToolsExtensions(); | ||
311 | } | ||
312 | |||
313 | return createWindow(); | ||
314 | }).catch((err) => { | ||
311 | console.error('Failed to create window', err); | 315 | console.error('Failed to create window', err); |
312 | process.exit(1); | 316 | process.exit(1); |
313 | }); | 317 | }); |
diff --git a/packages/main/src/services/ConfigPersistenceService.ts b/packages/main/src/services/ConfigPersistenceService.ts index 1c0315f..ee5eb9f 100644 --- a/packages/main/src/services/ConfigPersistenceService.ts +++ b/packages/main/src/services/ConfigPersistenceService.ts | |||
@@ -20,7 +20,7 @@ | |||
20 | import { watch } from 'fs'; | 20 | import { watch } from 'fs'; |
21 | import { readFile, stat, writeFile } from 'fs/promises'; | 21 | import { readFile, stat, writeFile } from 'fs/promises'; |
22 | import JSON5 from 'json5'; | 22 | import JSON5 from 'json5'; |
23 | import { throttle } from 'lodash'; | 23 | import throttle from 'lodash-es/throttle'; |
24 | import { join } from 'path'; | 24 | import { join } from 'path'; |
25 | 25 | ||
26 | import type { ConfigSnapshotOut } from '../stores/Config'; | 26 | import type { ConfigSnapshotOut } from '../stores/Config'; |
diff --git a/packages/main/src/utils/logging.ts b/packages/main/src/utils/logging.ts index 9f1133f..5cb5d21 100644 --- a/packages/main/src/utils/logging.ts +++ b/packages/main/src/utils/logging.ts | |||
@@ -36,10 +36,6 @@ prefix.apply(loglevel, { | |||
36 | const lastSegment = nameSegments.pop(); | 36 | const lastSegment = nameSegments.pop(); |
37 | shortName = [...nameSegments.map((segment) => segment[0]), lastSegment].join(':'); | 37 | shortName = [...nameSegments.map((segment) => segment[0]), lastSegment].join(':'); |
38 | } | 38 | } |
39 | if (isDevelopment) { | ||
40 | // `watch.js` already appends timestamps. | ||
41 | return `${level} (${shortName})`; | ||
42 | } | ||
43 | return `[${timestamp}] ${level} (${shortName})`; | 39 | return `[${timestamp}] ${level} (${shortName})`; |
44 | }, | 40 | }, |
45 | }); | 41 | }); |
diff --git a/packages/main/vite.config.js b/packages/main/vite.config.js deleted file mode 100644 index bdb0ca1..0000000 --- a/packages/main/vite.config.js +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | // @ts-check | ||
2 | |||
3 | import { builtinModules } from 'module'; | ||
4 | |||
5 | import { makeConfig, node } from '../../config/vite-common'; | ||
6 | |||
7 | /** @type {string} */ | ||
8 | const PACKAGE_ROOT = __dirname; | ||
9 | |||
10 | /** | ||
11 | * @type {import('vite').UserConfig} | ||
12 | * @see https://vitejs.dev/config/ | ||
13 | */ | ||
14 | const config = makeConfig({ | ||
15 | root: PACKAGE_ROOT, | ||
16 | define: { | ||
17 | // Allow access to process.env in imported packages. | ||
18 | // https://github.com/vitejs/vite/issues/3176#issuecomment-876610206 | ||
19 | 'process.env': 'process["env"]', | ||
20 | 'global.process.env': 'global.process["env"]', | ||
21 | 'globalThis.process.env': 'globalThis.process["env"]', | ||
22 | }, | ||
23 | build: { | ||
24 | target: node, | ||
25 | lib: { | ||
26 | entry: 'src/index.ts', | ||
27 | formats: ['cjs'], | ||
28 | }, | ||
29 | rollupOptions: { | ||
30 | external: [ | ||
31 | 'electron', | ||
32 | 'electron-devtools-installer', | ||
33 | ...builtinModules, | ||
34 | ], | ||
35 | }, | ||
36 | }, | ||
37 | }); | ||
38 | |||
39 | export default config; | ||