From 840adf9429ed47f9e88c05e90f1d3ab930c2dfc4 Mon Sep 17 00:00:00 2001 From: undergroundwires Date: Mon, 18 Mar 2024 11:55:56 +0100 Subject: [PATCH] Bump Electron to latest and use native ESM This commit bumps Electron and related dependencies to their latest versions to leverage native ESM support. It adjusts build configuration to use native ESM support instead of relying on CommonJS bundling. Key changes: - Bump Electron to latest v29. Electron v28 ships with native ESM/ECMAScript modules support. Details on Electron ESM support: - electron/electron#21457 - electron/electron#37535 - Bump `electron-builder` to latest v24.13. `electron-builder` is used to package and publish the application. It supports ESM since 24.10. Details on `electron-builder` ESM support: - electron-userland/electron-builder#7936 - electron-userland/electron-builder#7935 - Bump `electron-log` to latest v5.1. `electron-log` supports ESM since version 5.0.4. Details on `electron-log` ESM support: - megahertz/electron-log#390. - Change `electron-vite` configuration to bundle as ESM instead of CommonJS to leverage Electron's native ESM support. Other supporting changes: - Add type hint for electron-builder configuration file. - Update import statements for `electron-updater` as it still is a CommonJS module and does not support ESM. Details: - electron-userland/electron-builder#7976 - Improve `electron-builder` configuration file to dynamically locate main entry files, supporting various JavaScript file extensions (`.js`, `.mjs` and `.cjs`) to facilitate easier future changes. - Change comment about Electron process-specific module alias registration. This issue has been fixed in `electron-vite`, but subpath module imports for Electron still do not work when building tests (`npm run test:unit`). Details: - alex8088/electron-vite#372 - Add `electron-log` in bundling process instead of externalizing to workaround Electron ESM loader issues with subpath imports (inability to do `electron-log/main`). Details: - alex8088/electron-vite#401 - electron/electron#41241 - Improve desktop runtime error checks' assertion message for better clarity. --- electron-builder.cjs | 21 +- electron.vite.config.ts | 20 +- package-lock.json | 209 ++++++------------ package.json | 6 +- scripts/verify-build-artifacts.js | 4 +- .../electron/main/ElectronConfig.ts | 2 +- .../main/Update/AutomaticUpdateCoordinator.ts | 12 +- .../main/Update/ElectronAutoUpdaterFactory.ts | 8 + .../electron/main/Update/UpdateInitializer.ts | 5 +- .../desktop-runtime-errors/main.spec.ts | 6 +- vite-config-helper.ts | 2 +- 11 files changed, 129 insertions(+), 166 deletions(-) create mode 100644 src/presentation/electron/main/Update/ElectronAutoUpdaterFactory.ts diff --git a/electron-builder.cjs b/electron-builder.cjs index e08e8c211..95e2408bf 100644 --- a/electron-builder.cjs +++ b/electron-builder.cjs @@ -1,8 +1,13 @@ /* eslint-disable no-template-curly-in-string */ const { join } = require('node:path'); +const { readdirSync } = require('fs'); const { electronBundled, electronUnbundled } = require('./dist-dirs.json'); +/** +* @type {import('electron-builder').Configuration} +* @see https://www.electron.build/configuration/configuration +*/ module.exports = { // Common options publish: { @@ -14,7 +19,9 @@ module.exports = { output: electronBundled, }, extraMetadata: { - main: join(electronUnbundled, 'main/index.cjs'), // do not `path.resolve`, it expects a relative path + main: findMainEntryFile( + join(electronUnbundled, 'main'), // do not `path.resolve`, it expects a relative path + ), }, // Windows @@ -41,3 +48,15 @@ module.exports = { artifactName: '${name}-${version}.${ext}', }, }; + +/** + * Finds by accommodating different JS file extensions and module formats. + */ +function findMainEntryFile(parentDirectory) { + const files = readdirSync(parentDirectory); + const entryFile = files.find((file) => /^index\.(cjs|mjs|js)$/.test(file)); + if (!entryFile) { + throw new Error(`Main entry file not found in ${parentDirectory}.`); + } + return join(parentDirectory, entryFile); +} diff --git a/electron.vite.config.ts b/electron.vite.config.ts index 25daee0a7..c778e5027 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -14,7 +14,7 @@ const ELECTRON_DIST_SUBDIRECTORIES = { renderer: resolveElectronDistSubdirectory('renderer'), }; -process.env.ELECTRON_ENTRY = resolve(ELECTRON_DIST_SUBDIRECTORIES.main, 'index.cjs'); +process.env.ELECTRON_ENTRY = resolve(ELECTRON_DIST_SUBDIRECTORIES.main, 'index.mjs'); export default defineConfig({ main: getSharedElectronConfig({ @@ -54,13 +54,23 @@ function getSharedElectronConfig(options: { }, rollupOptions: { output: { - // Mark: electron-esm-support - // This is needed so `type="module"` works - entryFileNames: '[name].cjs', + format: 'es', + + // Ensure all generated files use '.mjs' for module consistency. + // Otherwise, preloader process get `.mjs` extension but main process get `.js` extension, see https://github.com/alex8088/electron-vite/issues/397. + entryFileNames: '[name].mjs', }, }, }, - plugins: [externalizeDepsPlugin()], + plugins: [externalizeDepsPlugin({ + exclude: [ + // Keep 'electron-log' in bundling process. + // This is a workaround for inability of Electron's ESM loader to resolve subpath imports. + // Do not externalize `electron-log` so subpath imports such as `electron-log/main` works. + // See https://github.com/electron/electron/issues/41241, https://github.com/alex8088/electron-vite/issues/401 + 'electron-log', + ], + })], define: { ...getClientEnvironmentVariables(), }, diff --git a/package-lock.json b/package-lock.json index 356ab4f60..bd39961fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@juggle/resize-observer": "^3.4.0", "@types/markdown-it": "^13.0.7", "ace-builds": "^1.30.0", - "electron-log": "^5.0.1", + "electron-log": "^5.1.2", "electron-progressbar": "^2.1.0", "electron-updater": "^6.1.4", "file-saver": "^2.0.5", @@ -34,8 +34,8 @@ "@vue/test-utils": "^2.4.1", "autoprefixer": "^10.4.16", "cypress": "^13.3.1", - "electron": "^27.0.0", - "electron-builder": "^24.6.4", + "electron": "^29.1.4", + "electron-builder": "^24.13.3", "electron-devtools-installer": "^3.2.0", "electron-icon-builder": "^2.0.1", "electron-vite": "^2.1.0", @@ -4879,19 +4879,6 @@ "electron-builder-squirrel-windows": "24.13.3" } }, - "node_modules/app-builder-lib/node_modules/builder-util-runtime": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", - "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/app-builder-lib/node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -5718,9 +5705,9 @@ } }, "node_modules/builder-util-runtime": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.1.tgz", - "integrity": "sha512-2rLv/uQD2x+dJ0J3xtsmI12AlRyk7p45TEbE/6o/fbb633e/S3pPgm+ct+JHsoY7r39dKHnGEFk/AASRFdnXmA==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", + "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", "dependencies": { "debug": "^4.3.4", "sax": "^1.2.4" @@ -5744,19 +5731,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/builder-util/node_modules/builder-util-runtime": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", - "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/builder-util/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -7140,19 +7114,6 @@ "dmg-license": "^1.0.11" } }, - "node_modules/dmg-builder/node_modules/builder-util-runtime": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", - "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/dmg-builder/node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -7347,14 +7308,14 @@ } }, "node_modules/electron": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-27.0.0.tgz", - "integrity": "sha512-mr3Zoy82l8XKK/TgguE5FeNeHZ9KHXIGIpUMjbjZWIREfAv+X2Q3vdX6RG0Pmi1K23AFAxANXQezIHBA2Eypwg==", + "version": "29.1.4", + "resolved": "https://registry.npmjs.org/electron/-/electron-29.1.4.tgz", + "integrity": "sha512-IWXys0SqgmIfrqXusUGQC0gGG7CCqA5vfmNsUMj8dFkAnK3lisKyjSESStWlrsste/OX/AAC5wsVlf23reUNnw==", "dev": true, "hasInstallScript": true, "dependencies": { "@electron/get": "^2.0.0", - "@types/node": "^18.11.18", + "@types/node": "^20.9.0", "extract-zip": "^2.0.1" }, "bin": { @@ -7433,19 +7394,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/electron-builder/node_modules/builder-util-runtime": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", - "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/electron-builder/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -7565,9 +7513,9 @@ } }, "node_modules/electron-log": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.0.1.tgz", - "integrity": "sha512-x4wnwHg00h/onWQgjmvcdLV7Mrd9TZjxNs8LmXVpqvANDf4FsSs5wLlzOykWLcaFzR3+5hdVEQ8ctmrUxgHlPA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.1.2.tgz", + "integrity": "sha512-Cpg4hAZ27yM9wzE77c4TvgzxzavZ+dVltCczParXN+Vb3jocojCSAuSMCVOI9fhFuuOR+iuu3tZLX1cu0y0kgQ==", "engines": { "node": ">= 14" } @@ -7610,19 +7558,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/electron-publish/node_modules/builder-util-runtime": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", - "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/electron-publish/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -7699,11 +7634,11 @@ "dev": true }, "node_modules/electron-updater": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.1.4.tgz", - "integrity": "sha512-yYAJc6RQjjV4WtInZVn+ZcLyXRhbVXoomKEfUUwDqIk5s2wxzLhWaor7lrNgxODyODhipjg4SVPMhJHi5EnsCA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.2.1.tgz", + "integrity": "sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==", "dependencies": { - "builder-util-runtime": "9.2.1", + "builder-util-runtime": "9.2.4", "fs-extra": "^10.1.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", @@ -7755,6 +7690,21 @@ } } }, + "node_modules/electron/node_modules/@types/node": { + "version": "20.11.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.28.tgz", + "integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/electron/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -24107,16 +24057,6 @@ "temp-file": "^3.4.0" }, "dependencies": { - "builder-util-runtime": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", - "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } - }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -24751,16 +24691,6 @@ "color-convert": "^2.0.1" } }, - "builder-util-runtime": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", - "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -24815,9 +24745,9 @@ } }, "builder-util-runtime": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.1.tgz", - "integrity": "sha512-2rLv/uQD2x+dJ0J3xtsmI12AlRyk7p45TEbE/6o/fbb633e/S3pPgm+ct+JHsoY7r39dKHnGEFk/AASRFdnXmA==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", + "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", "requires": { "debug": "^4.3.4", "sax": "^1.2.4" @@ -25829,16 +25759,6 @@ "js-yaml": "^4.1.0" }, "dependencies": { - "builder-util-runtime": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", - "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } - }, "fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -25989,14 +25909,31 @@ } }, "electron": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-27.0.0.tgz", - "integrity": "sha512-mr3Zoy82l8XKK/TgguE5FeNeHZ9KHXIGIpUMjbjZWIREfAv+X2Q3vdX6RG0Pmi1K23AFAxANXQezIHBA2Eypwg==", + "version": "29.1.4", + "resolved": "https://registry.npmjs.org/electron/-/electron-29.1.4.tgz", + "integrity": "sha512-IWXys0SqgmIfrqXusUGQC0gGG7CCqA5vfmNsUMj8dFkAnK3lisKyjSESStWlrsste/OX/AAC5wsVlf23reUNnw==", "dev": true, "requires": { "@electron/get": "^2.0.0", - "@types/node": "^18.11.18", + "@types/node": "^20.9.0", "extract-zip": "^2.0.1" + }, + "dependencies": { + "@types/node": { + "version": "20.11.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.28.tgz", + "integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + } } }, "electron-builder": { @@ -26027,16 +25964,6 @@ "color-convert": "^2.0.1" } }, - "builder-util-runtime": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", - "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -26157,9 +26084,9 @@ } }, "electron-log": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.0.1.tgz", - "integrity": "sha512-x4wnwHg00h/onWQgjmvcdLV7Mrd9TZjxNs8LmXVpqvANDf4FsSs5wLlzOykWLcaFzR3+5hdVEQ8ctmrUxgHlPA==" + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.1.2.tgz", + "integrity": "sha512-Cpg4hAZ27yM9wzE77c4TvgzxzavZ+dVltCczParXN+Vb3jocojCSAuSMCVOI9fhFuuOR+iuu3tZLX1cu0y0kgQ==" }, "electron-progressbar": { "version": "2.1.0", @@ -26193,16 +26120,6 @@ "color-convert": "^2.0.1" } }, - "builder-util-runtime": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz", - "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -26263,11 +26180,11 @@ "dev": true }, "electron-updater": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.1.4.tgz", - "integrity": "sha512-yYAJc6RQjjV4WtInZVn+ZcLyXRhbVXoomKEfUUwDqIk5s2wxzLhWaor7lrNgxODyODhipjg4SVPMhJHi5EnsCA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.2.1.tgz", + "integrity": "sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==", "requires": { - "builder-util-runtime": "9.2.1", + "builder-util-runtime": "9.2.4", "fs-extra": "^10.1.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", diff --git a/package.json b/package.json index cabc86338..7b7f973ac 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@juggle/resize-observer": "^3.4.0", "@types/markdown-it": "^13.0.7", "ace-builds": "^1.30.0", - "electron-log": "^5.0.1", + "electron-log": "^5.1.2", "electron-progressbar": "^2.1.0", "electron-updater": "^6.1.4", "file-saver": "^2.0.5", @@ -58,8 +58,8 @@ "@vue/test-utils": "^2.4.1", "autoprefixer": "^10.4.16", "cypress": "^13.3.1", - "electron": "^27.0.0", - "electron-builder": "^24.6.4", + "electron": "^29.1.4", + "electron-builder": "^24.13.3", "electron-devtools-installer": "^3.2.0", "electron-icon-builder": "^2.0.1", "electron-vite": "^2.1.0", diff --git a/scripts/verify-build-artifacts.js b/scripts/verify-build-artifacts.js index 1ca9d77f1..4c32dabeb 100644 --- a/scripts/verify-build-artifacts.js +++ b/scripts/verify-build-artifacts.js @@ -44,8 +44,8 @@ function getBuildVerificationConfigs() { '--electron-unbundled': { printDistDirScriptArgument: '--electron-unbundled', filePatterns: [ - /main[/\\]index\.cjs/, - /preload[/\\]index\.cjs/, + /main[/\\]index\.(cjs|mjs|js)/, + /preload[/\\]index\.(cjs|mjs|js)/, /renderer[/\\]index\.htm(l)?/, ], }, diff --git a/src/presentation/electron/main/ElectronConfig.ts b/src/presentation/electron/main/ElectronConfig.ts index a8b3604c2..2954f64f1 100644 --- a/src/presentation/electron/main/ElectronConfig.ts +++ b/src/presentation/electron/main/ElectronConfig.ts @@ -13,4 +13,4 @@ export const RENDERER_URL = process.env.ELECTRON_RENDERER_URL; export const RENDERER_HTML_PATH = join('file://', __dirname, '../renderer/index.html'); -export const PRELOADER_SCRIPT_PATH = join(__dirname, '../preload/index.cjs'); +export const PRELOADER_SCRIPT_PATH = join(__dirname, '../preload/index.mjs'); diff --git a/src/presentation/electron/main/Update/AutomaticUpdateCoordinator.ts b/src/presentation/electron/main/Update/AutomaticUpdateCoordinator.ts index b56d8db5d..c235f8716 100644 --- a/src/presentation/electron/main/Update/AutomaticUpdateCoordinator.ts +++ b/src/presentation/electron/main/Update/AutomaticUpdateCoordinator.ts @@ -1,18 +1,20 @@ import { app, dialog } from 'electron/main'; -import { autoUpdater, type UpdateInfo } from 'electron-updater'; import { ElectronLogger } from '@/infrastructure/Log/ElectronLogger'; import { UpdateProgressBar } from './UpdateProgressBar'; +import { getAutoUpdater } from './ElectronAutoUpdaterFactory'; +import type { AppUpdater, UpdateInfo } from 'electron-updater'; import type { ProgressInfo } from 'electron-builder'; export async function handleAutoUpdate() { + const autoUpdater = getAutoUpdater(); if (await askDownloadAndInstall() === DownloadDialogResult.NotNow) { return; } - startHandlingUpdateProgress(); + startHandlingUpdateProgress(autoUpdater); await autoUpdater.downloadUpdate(); } -function startHandlingUpdateProgress() { +function startHandlingUpdateProgress(autoUpdater: AppUpdater) { const progressBar = new UpdateProgressBar(); progressBar.showIndeterminateState(); autoUpdater.on('error', (e) => { @@ -29,11 +31,11 @@ function startHandlingUpdateProgress() { autoUpdater.on('update-downloaded', async (info: UpdateInfo) => { ElectronLogger.info('@update-downloaded@\n', info); progressBar.close(); - await handleUpdateDownloaded(); + await handleUpdateDownloaded(autoUpdater); }); } -async function handleUpdateDownloaded() { +async function handleUpdateDownloaded(autoUpdater: AppUpdater) { if (await askRestartAndInstall() === InstallDialogResult.NotNow) { return; } diff --git a/src/presentation/electron/main/Update/ElectronAutoUpdaterFactory.ts b/src/presentation/electron/main/Update/ElectronAutoUpdaterFactory.ts new file mode 100644 index 000000000..7acbcd1cb --- /dev/null +++ b/src/presentation/electron/main/Update/ElectronAutoUpdaterFactory.ts @@ -0,0 +1,8 @@ +import electronUpdater, { type AppUpdater } from 'electron-updater'; + +export function getAutoUpdater(): AppUpdater { + // Using destructuring to access autoUpdater due to the CommonJS module of 'electron-updater'. + // It is a workaround for ESM compatibility issues, see https://github.com/electron-userland/electron-builder/issues/7976. + const { autoUpdater } = electronUpdater; + return autoUpdater; +} diff --git a/src/presentation/electron/main/Update/UpdateInitializer.ts b/src/presentation/electron/main/Update/UpdateInitializer.ts index 5d0bb1863..dc0e8c99c 100644 --- a/src/presentation/electron/main/Update/UpdateInitializer.ts +++ b/src/presentation/electron/main/Update/UpdateInitializer.ts @@ -1,13 +1,16 @@ -import { autoUpdater, type UpdateInfo } from 'electron-updater'; import { ElectronLogger } from '@/infrastructure/Log/ElectronLogger'; import { requiresManualUpdate, startManualUpdateProcess } from './ManualUpdater/ManualUpdateCoordinator'; import { handleAutoUpdate } from './AutomaticUpdateCoordinator'; +import { getAutoUpdater } from './ElectronAutoUpdaterFactory'; +import type { UpdateInfo } from 'electron-updater'; interface Updater { checkForUpdates(): Promise; } export function setupAutoUpdater(): Updater { + const autoUpdater = getAutoUpdater(); + autoUpdater.logger = ElectronLogger; // Auto-downloads are disabled to allow separate handling of 'check' and 'download' actions, diff --git a/tests/checks/desktop-runtime-errors/main.spec.ts b/tests/checks/desktop-runtime-errors/main.spec.ts index e98e7d3c5..7e49fadfc 100644 --- a/tests/checks/desktop-runtime-errors/main.spec.ts +++ b/tests/checks/desktop-runtime-errors/main.spec.ts @@ -1,6 +1,7 @@ import { describe, it, beforeAll, afterAll, } from 'vitest'; +import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage'; import { main } from './check-desktop-runtime-errors/main'; import { COMMAND_LINE_FLAGS, CommandLineFlag } from './check-desktop-runtime-errors/cli-args'; @@ -14,7 +15,10 @@ describe('desktop runtime error checks', () => { () => main(), ); // assert - expect(exitCode).to.equal(0); + expect(exitCode).to.equal(0, formatAssertionMessage([ + `Test failed with exit code ${exitCode}; expected 0.`, + 'Examine preceding logs to identify errors.', + ])); }, { timeout: 60 /* minutes */ * 60000, }); diff --git a/vite-config-helper.ts b/vite-config-helper.ts index 08afbc286..ed4f3a765 100644 --- a/vite-config-helper.ts +++ b/vite-config-helper.ts @@ -55,7 +55,7 @@ function getPathAliasesFromTsConfig(): ViteAliasDefinitions { } function getElectronProcessSpecificModuleAliases(): ViteAliasDefinitions { - // Workaround for scoped Electron module imports due to https://github.com/alex8088/electron-vite/issues/372 + // Workaround for Vite not being able to build tests with scoped Electron module imports. const electronProcessScopedModuleAliases = [ 'electron/main', 'electron/renderer',