From cf23e60c17763123caa77f1194e6efd913692ea1 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Thu, 23 Dec 2021 00:43:55 +0100 Subject: feat: Add shared package for electron ipc --- .gitignore | 1 + package.json | 5 ++- packages/main/package.json | 3 +- packages/main/src/index.ts | 15 +++++++- packages/main/tsconfig.json | 6 +++ packages/preload/package.json | 4 +- packages/preload/src/index.ts | 12 ++++-- packages/preload/tsconfig.json | 8 ++++ packages/renderer/package.json | 3 +- packages/renderer/src/index.tsx | 5 ++- packages/renderer/tsconfig.json | 9 ++++- packages/renderer/types/sophieRenderer.d.ts | 7 ++++ packages/shared/package.json | 15 ++++++++ .../shared/src/contextBridge/SophieRenderer.ts | 3 ++ packages/shared/src/index.ts | 3 ++ packages/shared/src/ipc/RendererIpcMessage.ts | 3 ++ packages/shared/tsconfig.json | 13 +++++++ packages/shared/vite.config.js | 44 ++++++++++++++++++++++ scripts/watch.js | 20 ++++++++-- yarn.lock | 12 ++++++ 20 files changed, 177 insertions(+), 14 deletions(-) create mode 100644 packages/renderer/types/sophieRenderer.d.ts create mode 100644 packages/shared/package.json create mode 100644 packages/shared/src/contextBridge/SophieRenderer.ts create mode 100644 packages/shared/src/index.ts create mode 100644 packages/shared/src/ipc/RendererIpcMessage.ts create mode 100644 packages/shared/tsconfig.json create mode 100644 packages/shared/vite.config.js diff --git a/.gitignore b/.gitignore index e8336af..0b6997b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ !.yarn/releases !.yarn/versions dist/ +*.tsbuildinfo diff --git a/package.json b/package.json index 143ecca..cf271bd 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,14 @@ "precompile": "cross-env MODE=production yarn run build", "compile": "yarn precompile && electron-builder build --config .electron-builder.config.js --dir --config.asar=false", "watch": "node scripts/watch.js", - "typecheck": "yarn workspaces foreach -vp run typecheck", + "typecheck": "yarn workspaces foreach -vpt run typecheck", "update-electron-vendors": "node scripts/update-electron-vendors.js" }, "workspaces": [ "packages/main", "packages/preload", - "packages/renderer" + "packages/renderer", + "packages/shared" ], "devDependencies": { "@typescript-eslint/eslint-plugin": "5.8.0", diff --git a/packages/main/package.json b/packages/main/package.json index 11a6270..63da432 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -5,9 +5,10 @@ "main": "dist/index.cjs", "scripts": { "build": "vite build", - "typecheck": "tsc --noEmit" + "typecheck": "tsc" }, "dependencies": { + "@sophie/shared": "workspace:*", "electron": "^16.0.5" }, "devDependencies": { diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts index ef954e1..cd04276 100644 --- a/packages/main/src/index.ts +++ b/packages/main/src/index.ts @@ -1,5 +1,6 @@ import { app, BrowserWindow } from 'electron'; import { join } from 'path'; +import { RendererIpcMessage } from '@sophie/shared'; import { URL } from 'url'; const isSingleInstance = app.requestSingleInstanceLock(); @@ -49,9 +50,10 @@ function createWindow(): Promise { } }); + const { webContents } = mainWindow; + // See https://github.com/MarshallOfSound/electron-devtools-installer/issues/195#issuecomment-998872878 if (isDevelopment) { - const { webContents } = mainWindow; webContents.once('dom-ready', () => { webContents.once('devtools-opened', () => { mainWindow?.focus(); @@ -64,6 +66,17 @@ function createWindow(): Promise { mainWindow?.show(); }); + webContents.on('ipc-message', (_event, channel, ...args) => { + switch (channel) { + case RendererIpcMessage.ButtonClicked: + console.log('Button clicked'); + break; + default: + console.warn('Unknown IPC message:', channel, args); + break; + } + }); + const pageUrl = (isDevelopment && import.meta.env.VITE_DEV_SERVER_URL !== undefined) ? import.meta.env.VITE_DEV_SERVER_URL : new URL('../renderer/dist/index.html', `file://${__dirname}`).toString(); diff --git a/packages/main/tsconfig.json b/packages/main/tsconfig.json index 1a569d2..970215c 100644 --- a/packages/main/tsconfig.json +++ b/packages/main/tsconfig.json @@ -1,11 +1,17 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "noEmit": true, "types": [ "node", "vite/client" ] }, + "references": [ + { + "path": "../shared" + } + ], "include": [ "src/**/*.ts", "types/**/*.d.ts" diff --git a/packages/preload/package.json b/packages/preload/package.json index 5417ec0..5556c10 100644 --- a/packages/preload/package.json +++ b/packages/preload/package.json @@ -2,12 +2,14 @@ "name": "@sophie/preload", "version": "0.1.0", "private": true, + "sideEffects": false, "main": "dist/index.cjs", "scripts": { "build": "vite build", - "typecheck": "tsc --noEmit" + "typecheck": "tsc" }, "dependencies": { + "@sophie/shared": "workspace:*", "electron": "^16.0.5" }, "devDependencies": { diff --git a/packages/preload/src/index.ts b/packages/preload/src/index.ts index 7d5eff5..830901a 100644 --- a/packages/preload/src/index.ts +++ b/packages/preload/src/index.ts @@ -1,4 +1,10 @@ -import { contextBridge } from 'electron'; +import { contextBridge, ipcRenderer } from 'electron'; +import { RendererIpcMessage, SophieRenderer } from '@sophie/shared'; -contextBridge.exposeInMainWorld('sophieRenderer', { -}); +const sophieRenderer: SophieRenderer = { + buttonClicked() { + ipcRenderer.send(RendererIpcMessage.ButtonClicked); + } +}; + +contextBridge.exposeInMainWorld('sophieRenderer', sophieRenderer); diff --git a/packages/preload/tsconfig.json b/packages/preload/tsconfig.json index 6bb6145..8bfa0ec 100644 --- a/packages/preload/tsconfig.json +++ b/packages/preload/tsconfig.json @@ -1,5 +1,13 @@ { "extends": "../../tsconfig.json", + "compilerOptions": { + "noEmit": true + }, + "references": [ + { + "path": "../shared" + } + ], "include": [ "src/**/*.ts" ] diff --git a/packages/renderer/package.json b/packages/renderer/package.json index b18b2fe..559e668 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -5,7 +5,7 @@ "main": "dist/index.html", "scripts": { "build": "vite build", - "typecheck": "tsc --noEmit" + "typecheck": "tsc" }, "dependencies": { "@emotion/react": "^11.7.1", @@ -13,6 +13,7 @@ "@fontsource/roboto": "^4.5.1", "@mui/icons-material": "^5.2.5", "@mui/material": "^5.2.5", + "@sophie/shared": "workspace:*", "react": "^17.0.2", "react-dom": "^17.0.2" }, diff --git a/packages/renderer/src/index.tsx b/packages/renderer/src/index.tsx index 67bdf93..452448c 100644 --- a/packages/renderer/src/index.tsx +++ b/packages/renderer/src/index.tsx @@ -22,7 +22,10 @@ function App() { - diff --git a/packages/renderer/tsconfig.json b/packages/renderer/tsconfig.json index 4a80025..668356c 100644 --- a/packages/renderer/tsconfig.json +++ b/packages/renderer/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "noEmit": true, "jsx": "react", "lib": [ "dom", @@ -8,8 +9,14 @@ "esnext" ] }, + "references": [ + { + "path": "../shared" + } + ], "include": [ "src/**/*.ts", - "src/**/*.tsx" + "src/**/*.tsx", + "types/**/*.d.ts" ] } diff --git a/packages/renderer/types/sophieRenderer.d.ts b/packages/renderer/types/sophieRenderer.d.ts new file mode 100644 index 0000000..b5b5da1 --- /dev/null +++ b/packages/renderer/types/sophieRenderer.d.ts @@ -0,0 +1,7 @@ +import type { SophieRenderer } from '@sophie/shared'; + +declare global { + interface Window { + readonly sophieRenderer: SophieRenderer; + } +} diff --git a/packages/shared/package.json b/packages/shared/package.json new file mode 100644 index 0000000..ccde705 --- /dev/null +++ b/packages/shared/package.json @@ -0,0 +1,15 @@ +{ + "name": "@sophie/shared", + "version": "0.1.0", + "private": true, + "main": "dist/index.cjs", + "types": "dist/index.d.ts", + "scripts": { + "build": "vite build", + "typecheck": "tsc" + }, + "devDependencies": { + "typescript": "^4.5.4", + "vite": "^2.7.6" + } +} diff --git a/packages/shared/src/contextBridge/SophieRenderer.ts b/packages/shared/src/contextBridge/SophieRenderer.ts new file mode 100644 index 0000000..91a0a3c --- /dev/null +++ b/packages/shared/src/contextBridge/SophieRenderer.ts @@ -0,0 +1,3 @@ +export interface SophieRenderer { + buttonClicked(): void; +} diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts new file mode 100644 index 0000000..f95675d --- /dev/null +++ b/packages/shared/src/index.ts @@ -0,0 +1,3 @@ +export type { SophieRenderer } from './contextBridge/SophieRenderer'; + +export { RendererIpcMessage } from './ipc/RendererIpcMessage'; diff --git a/packages/shared/src/ipc/RendererIpcMessage.ts b/packages/shared/src/ipc/RendererIpcMessage.ts new file mode 100644 index 0000000..cfb87ae --- /dev/null +++ b/packages/shared/src/ipc/RendererIpcMessage.ts @@ -0,0 +1,3 @@ +export enum RendererIpcMessage { + ButtonClicked = "button-clicked" +} diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json new file mode 100644 index 0000000..d441cc8 --- /dev/null +++ b/packages/shared/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "declaration": true, + "declarationDir": "dist", + "emitDeclarationOnly": true, + "rootDir": "src" + }, + "include": [ + "src/**/*.ts" + ] +} diff --git a/packages/shared/vite.config.js b/packages/shared/vite.config.js new file mode 100644 index 0000000..cbebb8a --- /dev/null +++ b/packages/shared/vite.config.js @@ -0,0 +1,44 @@ +// @ts-check + +import { builtinModules } from 'module'; + +// `resolveJsonModule` is disabled for this package, but vite will load the json nevertheless. +// @ts-expect-error +import { chrome, node } from '../../.electron-vendors.cache.json'; + +/** @type string */ +const PACKAGE_ROOT = __dirname; + +/** + * @type {import('vite').UserConfig} + * @see https://vitejs.dev/config/ + */ +const config = { + mode: process.env.MODE, + root: PACKAGE_ROOT, + envDir: process.cwd(), + build: { + sourcemap: 'inline', + target: [ + `chrome${chrome}`, + `node${node}` + ], + outDir: 'dist', + lib: { + entry: 'src/index.ts', + formats: ['cjs'], + }, + rollupOptions: { + external: [ + ...builtinModules, + ], + output: { + entryFileNames: '[name].cjs', + }, + }, + emptyOutDir: false, // Do not remove `.d.ts` files. + brotliSize: false, + }, +}; + +export default config; diff --git a/scripts/watch.js b/scripts/watch.js index 7ec07ff..7f5f42c 100644 --- a/scripts/watch.js +++ b/scripts/watch.js @@ -37,10 +37,10 @@ const stderrFilterPatterns = [ ]; /** - * @param {{name: string; configFile: string; writeBundle: import('rollup').OutputPlugin['writeBundle'] }} config + * @param {{name: string; configFile: string; writeBundle?: import('rollup').OutputPlugin['writeBundle'] }} config * @returns {Promise | import('rollup').RollupWatcher>} */ -function getWatcher({name, configFile, writeBundle}) { +function getWatcher({ name, configFile, writeBundle }) { return build({ ...sharedConfig, configFile, @@ -110,7 +110,7 @@ function setupMainPackageWatcher(viteDevServer) { } /** - * Start or restart App when source files are changed. + * Reload App when source files are changed. * * @param {import('vite').ViteDevServer} viteDevServer * @returns {Promise | import('rollup').RollupWatcher>} @@ -127,10 +127,24 @@ function setupPreloadPackageWatcher(viteDevServer) { }); } +/** + * Rebuild package when source files are changed. + * + * @returns {Promise | import('rollup').RollupWatcher>} + */ +function setupSharedPackageWatcher() { + return getWatcher({ + name: 'rebuild-package-on-shared-package-change', + configFile: 'packages/shared/vite.config.js', + }); +} + /** * @returns Promise */ async function setupDevEnvironment() { + await setupSharedPackageWatcher(); + const viteDevServer = await createServer({ ...sharedConfig, configFile: 'packages/renderer/vite.config.js', diff --git a/yarn.lock b/yarn.lock index 9730c32..5a61262 100644 --- a/yarn.lock +++ b/yarn.lock @@ -822,6 +822,7 @@ __metadata: version: 0.0.0-use.local resolution: "@sophie/main@workspace:packages/main" dependencies: + "@sophie/shared": "workspace:*" "@types/electron-devtools-installer": ^2.2.0 "@types/node": ^16.11.15 electron: ^16.0.5 @@ -835,6 +836,7 @@ __metadata: version: 0.0.0-use.local resolution: "@sophie/preload@workspace:packages/preload" dependencies: + "@sophie/shared": "workspace:*" electron: ^16.0.5 typescript: ^4.5.4 vite: ^2.7.6 @@ -850,6 +852,7 @@ __metadata: "@fontsource/roboto": ^4.5.1 "@mui/icons-material": ^5.2.5 "@mui/material": ^5.2.5 + "@sophie/shared": "workspace:*" "@types/react": ^17.0.37 "@types/react-dom": ^17.0.11 "@vitejs/plugin-react": ^1.1.3 @@ -860,6 +863,15 @@ __metadata: languageName: unknown linkType: soft +"@sophie/shared@workspace:*, @sophie/shared@workspace:packages/shared": + version: 0.0.0-use.local + resolution: "@sophie/shared@workspace:packages/shared" + dependencies: + typescript: ^4.5.4 + vite: ^2.7.6 + languageName: unknown + linkType: soft + "@szmarczak/http-timer@npm:^1.1.2": version: 1.1.2 resolution: "@szmarczak/http-timer@npm:1.1.2" -- cgit v1.2.3-54-g00ecf