Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2 from 2skydev/dev
Browse files Browse the repository at this point in the history
전체적인 패키지 업데이트 및 속도 개선
  • Loading branch information
2skydev authored Feb 25, 2023
2 parents ca673fe + 74876d1 commit 81ccf22
Show file tree
Hide file tree
Showing 30 changed files with 2,139 additions and 2,105 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ yarn-error.log*
dist
/resources/windows/chromium
chrome_data
release
release
dist-electron
10 changes: 9 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,13 @@
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"typescript.preferences.importModuleSpecifier": "shortest",
"typescript.tsdk": "node_modules/typescript/lib"
"typescript.tsdk": "node_modules/typescript/lib",
"json.schemas": [
{
"fileMatch": [
"/*electron-builder.json"
],
"url": "https://json.schemastore.org/electron-builder"
}
]
}
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
![electron-vite-template-github-card](https://user-images.githubusercontent.com/43225384/196135599-585afdc5-9905-4400-bb02-ab0e7720da50.png)


# Electron + Vite + React + TypeScript Template

A template for using electron quickly.<br/>
Expand All @@ -9,6 +8,7 @@ Please understand that the code and explanation are mainly written in Korean.
<br />

## 특징들 둘러보기

- electron & vite를 사용해 빠른 개발, 빌드가 가능한 TypeScript 환경
- 앱에 필수적인 요소 자동 업데이트, 저장소, 로그 등 사전구성
- 파일 시스템 라우팅 기능 (Next.js에서 사용하던 방식)
Expand All @@ -32,7 +32,6 @@ Please understand that the code and explanation are mainly written in Korean.
- CSS: [`styled-components`](https://styled-components.com/)
- State management library: [`recoil`](https://hookstate.js.org/)
- Date: [`dayjs`](https://day.js.org/)
- Form value handle: [`formik`](https://formik.org/)

<br />

Expand Down Expand Up @@ -61,7 +60,7 @@ yarn build:all
<br />

## 스크린샷들

<img width="1718" alt="image" src="https://user-images.githubusercontent.com/43225384/196127143-2fd2fb65-5858-4bda-87a8-97c6e0487d8f.png">
<img width="1718" alt="image" src="https://user-images.githubusercontent.com/43225384/196126603-388acf2c-760b-45f2-8738-5c1d2a4b4892.png">
<img width="1718" alt="image" src="https://user-images.githubusercontent.com/43225384/196126770-08f75a7c-653d-4264-8c38-eb147c55193d.png">

32 changes: 15 additions & 17 deletions app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import { app, BrowserWindow, Menu, nativeImage, Tray } from 'electron';

import { join } from 'path';

import { productName, protocols } from '../electron-builder.json';
import { globImport } from './utils/import';

export type MyAppType = InstanceType<typeof MyApp>;
export type ModuleFunction = (app: MyAppType) => void | Promise<void>;
export type AppContextType = InstanceType<typeof AppContext>;
export type ModuleFunction = (context: AppContextType) => void | Promise<void>;

class MyApp {
const { productName, protocols } = require(app.isPackaged
? './app.json'
: '../electron-builder.json');

class AppContext {
// deep link protocol
readonly PROTOCOL = protocols.name;

Expand All @@ -18,7 +22,7 @@ class MyApp {
readonly DEV_URL = `http://localhost:3000/#`;

// production mode - load file
readonly PROD_LOAD_FILE_PATH = join(__dirname, '../index.html');
readonly PROD_LOAD_FILE_PATH = join(__dirname, '../dist/index.html');
readonly PROD_LOAD_FILE_HASH = '#';

// resources directory
Expand All @@ -37,6 +41,7 @@ class MyApp {
async bootstrap() {
await this.initliazeElectron();
await this.autoload();
await this.createWindow();
}

async initliazeElectron() {
Expand All @@ -58,7 +63,6 @@ class MyApp {
});

await app.whenReady();
await this.createWindow();
await this.createTray();
}

Expand Down Expand Up @@ -88,11 +92,9 @@ class MyApp {
this.window.loadFile(this.PROD_LOAD_FILE_PATH, {
hash: this.PROD_LOAD_FILE_HASH,
});

this.window.webContents.openDevTools(); // FIXME: Remove this line
} else {
this.window.loadURL(this.DEV_URL);
this.window.webContents.openDevTools(); // FIXME: Remove this line
await this.window.loadURL(this.DEV_URL);
this.window.webContents.openDevTools();
}

this.window.on('ready-to-show', () => {
Expand All @@ -119,14 +121,10 @@ class MyApp {
}

async autoload() {
const modules = import.meta.glob<{ default: ModuleFunction }>('./modules/**/index.ts', {
eager: true,
});
const modules = await globImport('./modules/**/index.js', { cwd: __dirname });

for (const module of Object.values(modules)) {
await this.register(module.default);
}
await Promise.all(modules.map(({ default: module }) => this.register(module)));
}
}

export default MyApp;
export default AppContext;
1 change: 1 addition & 0 deletions app/electron-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite-electron-plugin/electron-env" />
6 changes: 3 additions & 3 deletions app/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MyApp from './app';
import AppContext from './app';

(async () => {
const myApp = new MyApp();
await myApp.bootstrap();
const context = new AppContext();
await context.bootstrap();
})();
32 changes: 13 additions & 19 deletions app/modules/deepLink/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,44 @@ import { app } from 'electron';

import { match, MatchResult } from 'path-to-regexp';

import { ModuleFunction, MyAppType } from '@app/app';
import { ModuleFunction, AppContextType } from '@app/app';
import { globImport } from '@app/utils/import';

export type DeepLinkResolvers = Record<
string,
(matchResult: MatchResult<any>, app: MyAppType) => void
(matchResult: MatchResult<any>, app: AppContextType) => void
>;

const DeepLinkModule: ModuleFunction = myapp => {
let resolvers: DeepLinkResolvers = {};
const DeepLinkModule: ModuleFunction = async context => {
const modules = await globImport('./resolvers/**/*.resolver.js', { cwd: __dirname });

const resolverFiles = import.meta.glob<{ default: DeepLinkResolvers }>(
'./resolvers/**/*.resolver.ts',
{
eager: true,
},
);

for (const resolverFile of Object.values(resolverFiles)) {
resolvers = { ...resolvers, ...resolverFile.default };
}
const resolvers: DeepLinkResolvers = modules.reduce((resolvers, module) => {
return { ...resolvers, ...module.default };
}, {});

const runDeepLinkResolver = (url: string) => {
const pathname = url.replace(`${myapp.PROTOCOL}://`, '/');
const pathname = url.replace(`${context.PROTOCOL}://`, '/');

for (const path in resolvers) {
const data = match(path)(pathname);

if (data) {
resolvers[path](data, myapp);
resolvers[path](data, context);
break;
}
}
};

app.on('second-instance', (_, argv) => {
if (!myapp.IS_MAC) {
const url = argv.find(arg => arg.startsWith(`${myapp.PROTOCOL}://`));
if (!context.IS_MAC) {
const url = argv.find(arg => arg.startsWith(`${context.PROTOCOL}://`));

if (url) {
runDeepLinkResolver(url);
}
}

myapp.createWindow();
context.createWindow();
});

app.on('open-url', (_, url) => {
Expand Down
4 changes: 3 additions & 1 deletion app/modules/general/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { configStore } from '@app/stores/config';

export type AppControlAction = 'devtools' | 'minimize' | 'maximize' | 'close';

const GeneralModule: ModuleFunction = ({ window }) => {
const GeneralModule: ModuleFunction = context => {
// 창 닫기, 최대화, 최소화 같은 컨트롤 기능
ipcMain.on('appControl', async (_, action: AppControlAction) => {
const { window } = context;

if (!window) return;

switch (action) {
Expand Down
6 changes: 3 additions & 3 deletions app/modules/update/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type UpdateEvent =
| 'download-progress'
| 'update-downloaded';

const UpdateModule: ModuleFunction = ({ window }) => {
const UpdateModule: ModuleFunction = context => {
const handleUpdateEvent = (event: UpdateEvent) => {
return (data?: any) => {
if (event !== 'download-progress') {
Expand All @@ -30,8 +30,8 @@ const UpdateModule: ModuleFunction = ({ window }) => {
});
}

if (window) {
window.webContents.send('update', event, data);
if (context.window) {
context.window.webContents.send('update', event, data);
}
};
};
Expand Down
27 changes: 2 additions & 25 deletions app/preload/index.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,6 @@
import { contextBridge, ipcRenderer } from 'electron';
import { ElectronRendererContext } from '@app/types/preload';

import { Log } from '../modules/developers';
import { AppControlAction } from '../modules/general';
import { UpdateEvent, UpdateStatus } from '../modules/update';
import { ConfigStoreValues } from '../stores/config';

export interface ElectronRendererContext {
onUpdate: (callback: (event: UpdateEvent, data: any) => void) => void;

initlizeUpdater: () => void;
appControl: (action: AppControlAction) => void;
openExternal: (link: string) => void;
checkForUpdate: () => void;
quitAndInstall: () => void;

getConfig: () => Promise<ConfigStoreValues>;
setConfig: (config: ConfigStoreValues) => Promise<ConfigStoreValues>;

getVersion: () => Promise<string>;
getUpdaterStatus: () => Promise<UpdateStatus>;

getStorePath: () => Promise<string>;
getLogs: () => Promise<Log[]>;
clearLogs: () => Promise<boolean>;
}
const { contextBridge, ipcRenderer } = require('electron');

const electronContext: ElectronRendererContext = {
onUpdate: callback => ipcRenderer.on('update', (_, event, data) => callback(event, data)),
Expand Down
2 changes: 0 additions & 2 deletions app/stores/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Store from 'electron-store';

export interface ConfigStoreValues {
general: {
theme: 'light' | 'dark';
developerMode: boolean;
};
}
Expand All @@ -12,7 +11,6 @@ export const configStore = new Store<ConfigStoreValues>({
accessPropertiesByDotNotation: false,
defaults: {
general: {
theme: 'dark',
developerMode: false,
},
},
Expand Down
24 changes: 24 additions & 0 deletions app/types/preload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Log } from '../modules/developers';
import { AppControlAction } from '../modules/general';
import { UpdateEvent, UpdateStatus } from '../modules/update';
import { ConfigStoreValues } from '../stores/config';

export interface ElectronRendererContext {
onUpdate: (callback: (event: UpdateEvent, data: any) => void) => void;

initlizeUpdater: () => void;
appControl: (action: AppControlAction) => void;
openExternal: (link: string) => void;
checkForUpdate: () => void;
quitAndInstall: () => void;

getConfig: () => Promise<ConfigStoreValues>;
setConfig: (config: ConfigStoreValues) => Promise<ConfigStoreValues>;

getVersion: () => Promise<string>;
getUpdaterStatus: () => Promise<UpdateStatus>;

getStorePath: () => Promise<string>;
getLogs: () => Promise<Log[]>;
clearLogs: () => Promise<boolean>;
}
14 changes: 14 additions & 0 deletions app/utils/import.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import glob from 'glob';
import { resolve as pathResolve } from 'path';

export interface GlobImportOptions extends glob.IOptions {
cwd: string;
}

export const globImport = (pattern: string, options: GlobImportOptions) =>
new Promise<any[]>((resolve, reject) => {
glob(pattern, options, async (err, paths) => {
if (err) return reject(err);
resolve(paths.map(path => require(pathResolve(options.cwd, path))));
});
});
1 change: 0 additions & 1 deletion app/vite-env.d.ts

This file was deleted.

Loading

0 comments on commit 81ccf22

Please sign in to comment.