├── docs ├── src │ ├── ko │ │ ├── project-structures │ │ │ ├── index.md │ │ │ ├── pre-configured-components.md │ │ │ └── project-structure.md │ │ ├── electron-how-to │ │ │ ├── index.md │ │ │ ├── main-and-renderer-process.md │ │ │ └── preload-script.md │ │ ├── installation-and-build │ │ │ ├── index.md │ │ │ ├── install-local-documentation.md │ │ │ ├── automated-testing.md │ │ │ ├── getting-started.md │ │ │ ├── npm-scripts.md │ │ │ └── build-configuration.md │ │ ├── other-projects.md │ │ ├── introduction.md │ │ └── index.md │ ├── en │ │ ├── electron-how-to │ │ │ ├── index.md │ │ │ ├── main-and-renderer-process.md │ │ │ └── preload-script.md │ │ ├── project-structures │ │ │ ├── index.md │ │ │ ├── pre-configured-components.md │ │ │ └── project-structure.md │ │ ├── installation-and-build │ │ │ ├── index.md │ │ │ ├── install-local-documentation.md │ │ │ ├── automated-testing.md │ │ │ ├── getting-started.md │ │ │ ├── npm-scripts.md │ │ │ └── build-configuration.md │ │ ├── other-projects.md │ │ ├── introduction.md │ │ └── index.md │ ├── zhHans │ │ ├── project-structures │ │ │ ├── index.md │ │ │ ├── pre-configured-components.md │ │ │ └── project-structure.md │ │ ├── electron-how-to │ │ │ ├── index.md │ │ │ ├── main-and-renderer-process.md │ │ │ └── preload-script.md │ │ ├── installation-and-build │ │ │ ├── index.md │ │ │ ├── install-local-documentation.md │ │ │ ├── automated-testing.md │ │ │ ├── getting-started.md │ │ │ ├── npm-scripts.md │ │ │ └── build-configuration.md │ │ ├── other-projects.md │ │ ├── introduction.md │ │ └── index.md │ ├── public │ │ ├── icon.png │ │ └── favicon.ico │ └── .vitepress │ │ └── config.mts ├── pnpm-workspace.yaml ├── .gitignore ├── tsconfig.json └── package.json ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── fix_typo.yml │ ├── feature_request.yml │ └── bug_report.yml ├── resources │ └── vutron-sample.webp ├── FUNDING.yml ├── pull_request_template.md └── workflows │ ├── app-test.yml │ └── documents.yml ├── src ├── renderer │ ├── screens │ │ ├── ErrorScreen.vue │ │ ├── index.ts │ │ ├── SecondScreen.vue │ │ └── MainScreen.vue │ ├── plugins │ │ ├── pinia.ts │ │ ├── i18n.ts │ │ └── vuetify.ts │ ├── components │ │ └── layout │ │ │ ├── index.ts │ │ │ ├── DefaultLayout.vue │ │ │ └── HeaderLayout.vue │ ├── index.html │ ├── store │ │ └── counter.ts │ ├── utils │ │ └── index.ts │ ├── App.vue │ ├── main.ts │ ├── locales │ │ ├── zh-hans.json │ │ ├── zh-hant.json │ │ ├── ko.json │ │ ├── ja.json │ │ ├── en.json │ │ ├── nl.json │ │ ├── pt.json │ │ ├── ru.json │ │ ├── es.json │ │ ├── fr.json │ │ └── de.json │ └── router │ │ └── index.ts ├── public │ └── images │ │ ├── vutron-logo.webp │ │ └── vutron-tray-icon.png ├── vue-shim.d.ts ├── main │ ├── index.dev.ts │ ├── IPCs.ts │ ├── utils │ │ └── Constants.ts │ ├── index.ts │ ├── tray.ts │ └── MainRunner.ts └── preload │ └── index.ts ├── pnpm-workspace.yaml ├── .vscode ├── extensions.json ├── settings.json └── launch.json ├── .prettierignore ├── .editorconfig ├── playwright.config.ts ├── .prettierrc ├── tsconfig.node.json ├── tsconfig.json ├── SECURITY.md ├── .gitignore ├── tests ├── testUtil.mts ├── specs │ └── app.spec.ts └── fixtures.mts ├── LICENSE ├── README.md ├── eslint.config.ts ├── vite.config.mts ├── package.json ├── CONTRIBUTING.md └── CODE_OF_CONDUCT.md /docs/src/ko/project-structures/index.md: -------------------------------------------------------------------------------- 1 | # 프로젝트 구조 2 | -------------------------------------------------------------------------------- /docs/src/en/electron-how-to/index.md: -------------------------------------------------------------------------------- 1 | # Electron How-to 2 | -------------------------------------------------------------------------------- /docs/src/ko/electron-how-to/index.md: -------------------------------------------------------------------------------- 1 | # Electron 개요 2 | -------------------------------------------------------------------------------- /docs/src/zhHans/project-structures/index.md: -------------------------------------------------------------------------------- 1 | # 项目结构 2 | -------------------------------------------------------------------------------- /docs/src/ko/installation-and-build/index.md: -------------------------------------------------------------------------------- 1 | # 설치 그리고 빌드 2 | -------------------------------------------------------------------------------- /docs/src/zhHans/electron-how-to/index.md: -------------------------------------------------------------------------------- 1 | # Electron 操作方法 2 | -------------------------------------------------------------------------------- /docs/src/zhHans/installation-and-build/index.md: -------------------------------------------------------------------------------- 1 | # 安装和构建 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | -------------------------------------------------------------------------------- /docs/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | onlyBuiltDependencies: 2 | - esbuild 3 | -------------------------------------------------------------------------------- /docs/src/en/project-structures/index.md: -------------------------------------------------------------------------------- 1 | # Project Structures 2 | -------------------------------------------------------------------------------- /docs/src/en/installation-and-build/index.md: -------------------------------------------------------------------------------- 1 | # Installation and Build 2 | -------------------------------------------------------------------------------- /docs/src/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jooy2/vutron/HEAD/docs/src/public/icon.png -------------------------------------------------------------------------------- /docs/src/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jooy2/vutron/HEAD/docs/src/public/favicon.ico -------------------------------------------------------------------------------- /src/renderer/screens/ErrorScreen.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/public/images/vutron-logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jooy2/vutron/HEAD/src/public/images/vutron-logo.webp -------------------------------------------------------------------------------- /.github/resources/vutron-sample.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jooy2/vutron/HEAD/.github/resources/vutron-sample.webp -------------------------------------------------------------------------------- /src/public/images/vutron-tray-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jooy2/vutron/HEAD/src/public/images/vutron-tray-icon.png -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: jooy2 4 | custom: ["https://cdget.com/donate"] 5 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - . 3 | onlyBuiltDependencies: 4 | - electron 5 | - electron-winstaller 6 | - esbuild 7 | -------------------------------------------------------------------------------- /src/renderer/plugins/pinia.ts: -------------------------------------------------------------------------------- 1 | import { createPinia } from 'pinia' 2 | 3 | const pinia = createPinia() 4 | 5 | export default pinia 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "esbenp.prettier-vscode", 5 | "Vue.volar" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Lock files 2 | *-lock.json 3 | *-lock.yaml 4 | 5 | # IDEs 6 | .idea/ 7 | .vscode/ 8 | 9 | # Project files 10 | .github/ 11 | buildAssets/icons/ 12 | dist/ 13 | release/ 14 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Node artifact files 2 | node_modules/ 3 | 4 | # VitePress files 5 | dist 6 | dist/* 7 | src/.vitepress/.temp 8 | src/.vitepress/.temp/* 9 | src/.vitepress/cache 10 | src/.vitepress/cache/* 11 | -------------------------------------------------------------------------------- /src/vue-shim.d.ts: -------------------------------------------------------------------------------- 1 | // For fix typescript import errors 2 | declare module '*.vue' { 3 | import { defineComponent } from 'vue' 4 | const component: ReturnType 5 | export default component 6 | } 7 | -------------------------------------------------------------------------------- /src/renderer/components/layout/index.ts: -------------------------------------------------------------------------------- 1 | import DefaultLayout from '@/renderer/components/layout/DefaultLayout.vue' 2 | import HeaderLayout from '@/renderer/components/layout/HeaderLayout.vue' 3 | 4 | export { DefaultLayout, HeaderLayout } 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_style = space 8 | indent_size = 2 9 | insert_final_newline = true 10 | max_line_length = 100 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /src/renderer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /src/renderer/screens/index.ts: -------------------------------------------------------------------------------- 1 | import ErrorScreen from '@/renderer/screens/ErrorScreen.vue' 2 | import MainScreen from '@/renderer/screens/MainScreen.vue' 3 | import SecondScreen from '@/renderer/screens/SecondScreen.vue' 4 | 5 | export { ErrorScreen, MainScreen, SecondScreen } 6 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "NodeNext", 5 | "moduleResolution": "NodeNext", 6 | "resolveJsonModule": true, 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["src/.vitepress/config.mts", "package.json"] 10 | } 11 | -------------------------------------------------------------------------------- /playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@playwright/test' 2 | 3 | export default defineConfig({ 4 | outputDir: 'tests/results', 5 | retries: process.env.CI ? 2 : 0, 6 | workers: process.env.CI ? 1 : undefined, 7 | timeout: 60000, 8 | expect: { 9 | timeout: 10000 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /src/renderer/components/layout/DefaultLayout.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | -------------------------------------------------------------------------------- /src/renderer/store/counter.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | import { ref } from 'vue' 3 | 4 | export const useCounterStore = defineStore('counter', () => { 5 | const count = ref(0) 6 | 7 | function increaseCount(amount: number) { 8 | count.value += amount 9 | } 10 | 11 | return { 12 | count, 13 | increaseCount 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /src/renderer/utils/index.ts: -------------------------------------------------------------------------------- 1 | export function getCurrentLocale(): string { 2 | return navigator?.language?.split('-')[0] || 'en' 3 | } 4 | 5 | export async function openExternal(url: string): Promise { 6 | await window.mainApi.send('msgOpenExternalLink', url) 7 | } 8 | 9 | export async function openFile(type: string): Promise { 10 | return window.mainApi.invoke('msgOpenFile', type) 11 | } 12 | -------------------------------------------------------------------------------- /docs/src/zhHans/other-projects.md: -------------------------------------------------------------------------------- 1 | # 其他项目 2 | 3 | ## 寻找使用 React 制作的 Electron 模板? 4 | 5 | 还可以查看由 Vite + React + Material-UI + Electron 组成的 "Retron" 项目。 6 | 7 | https://github.com/jooy2/retron 8 | 9 | ## (已废弃)在寻找使用 Webpack 5 编译器的 `Vutron`? 10 | 11 | 通过使用 Vite 编译器,我们实现了减少项目和软件包大小、改善开发环境和提高构建速度的目标。 12 | 13 | 使用 Webpack 5 编译器的旧版**Vutron**已被分割到以下软件源中,并将很快结束支持。 14 | 15 | https://github.com/jooy2/vutron-webpack 16 | -------------------------------------------------------------------------------- /src/renderer/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 22 | -------------------------------------------------------------------------------- /docs/src/ko/other-projects.md: -------------------------------------------------------------------------------- 1 | # 기타 프로젝트 2 | 3 | ## React로 만든 Electron 템플릿을 찾고 계신가요? 4 | 5 | Vite + React + Material-UI + Electron으로 구성된 'Retron' 프로젝트도 확인해 보세요. 6 | 7 | https://github.com/jooy2/retron 8 | 9 | ## (사용 중단) Webpack 5 컴파일러로 `Vutron`을 찾고 계신가요? 10 | 11 | Vite 컴파일러를 사용하여 프로젝트 및 번들 크기를 줄이고 개발 환경과 빌드 속도를 개선한다는 목표를 달성했습니다. 12 | 13 | Webpack 5 컴파일러를 사용하는 기존 **Vutron**은 아래 리포지토리로 분리되었으며 곧 지원이 종료될 예정입니다. 14 | 15 | https://github.com/jooy2/vutron-webpack 16 | -------------------------------------------------------------------------------- /docs/src/zhHans/introduction.md: -------------------------------------------------------------------------------- 1 | # 导言 2 | 3 | **Vutron** 是一个预配置的模板,用于开发 `Electron` 跨平台桌面应用。它使用 `Vue 3`,使您能够轻松构建快速的开发环境。 4 | 5 | ## 使用优势 6 | 7 | - ✅ 无需任何预设,即可立即构建,快速开发。 8 | - ✅ 快速维护,与最新的 `Vue` 和 `Electron` 以及许多模块兼容。 9 | - ✅ 通过使用各种附加模板,无需担心布局和数据管理。 10 | 11 | ## 特点 12 | 13 | - ⚡️ 通过热重载实现快速开发 14 | - ⚡️ 跨平台开发和构建支持 15 | - ⚡️ 支持自动化应用程序测试 16 | - ⚡️ 支持 TypeScript 17 | - ⚡️ 多语言支持 18 | - ⚡️ 支持主题(暗色和亮色) 19 | - ⚡️ 基本布局管理器 20 | - ⚡️ 通过 Pinia 存储进行全局状态管理 21 | - ⚡️ 通过 GitHub 社区和官方文档提供快速支持 22 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "semi": false, 4 | "vueIndentScriptAndStyle": false, 5 | "singleQuote": true, 6 | "quoteProps": "as-needed", 7 | "trailingComma": "none", 8 | "bracketSpacing": true, 9 | "bracketSameLine": false, 10 | "jsxSingleQuote": false, 11 | "arrowParens": "always", 12 | "insertPragma": false, 13 | "requirePragma": false, 14 | "proseWrap": "never", 15 | "singleAttributePerLine": true, 16 | "htmlWhitespaceSensitivity": "strict", 17 | "endOfLine": "lf", 18 | "printWidth": 80 19 | } 20 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vutron-docs", 3 | "private": true, 4 | "version": "1.0.0", 5 | "scripts": { 6 | "dev": "vitepress dev src", 7 | "build": "vitepress build src", 8 | "serve": "vitepress serve src" 9 | }, 10 | "author": "CDGet ", 11 | "license": "MIT", 12 | "engines": { 13 | "node": ">=18.0.0" 14 | }, 15 | "dependencies": { 16 | "vitepress": "^1.6.4", 17 | "vitepress-i18n": "^1.3.5", 18 | "vitepress-sidebar": "^1.33.1", 19 | "vue": "^3.5.26" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/renderer/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | 3 | import App from '@/renderer/App.vue' 4 | import router from '@/renderer/router' 5 | import vuetify from '@/renderer/plugins/vuetify' 6 | import i18n from '@/renderer/plugins/i18n' 7 | import pinia from '@/renderer/plugins/pinia' 8 | 9 | // Add API key defined in contextBridge to window object type 10 | declare global { 11 | interface Window { 12 | mainApi?: any 13 | } 14 | } 15 | 16 | const app = createApp(App) 17 | 18 | app.use(vuetify).use(i18n).use(router).use(pinia) 19 | 20 | app.mount('#app') 21 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "Preserve", 5 | "moduleDetection": "force", 6 | "jsx": "preserve", 7 | "composite": true, 8 | "resolveJsonModule": true, 9 | "esModuleInterop": true, 10 | "allowSyntheticDefaultImports": true 11 | }, 12 | "include": [ 13 | "src/main", 14 | "src/preload", 15 | "package.json", 16 | "eslint.config.ts", 17 | "vite.config.mts", 18 | "buildAssets/builder", 19 | "tests/**/*.ts", 20 | "tests/**/*.mts", 21 | "tests/**/*.spec.ts" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /docs/src/zhHans/installation-and-build/install-local-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 5 3 | --- 4 | 5 | # 管理本地文档 6 | 7 | Vutron 中的文档可以通过 VitePress 查看器在本地环境中查看。 8 | 9 | 此功能仅在克隆整个项目时可用。如果您使用 npm init vutron 创建项目,则不会包含 docs 文件夹。 10 | 11 | ## 安装 12 | 13 | 以下说明中的所有操作均应在"文档"文件夹中完成。 14 | 15 | ```shell 16 | $ cd docs 17 | ``` 18 | 19 | 使用以下命令安装相关软件包: 20 | 21 | ```shell 22 | # via npm 23 | $ npm i 24 | 25 | # via yarn (https://yarnpkg.com) 26 | $ yarn install 27 | 28 | # via pnpm (https://pnpm.io) 29 | $ pnpm i 30 | ``` 31 | 32 | 您可以通过以下命令运行托管文档的本地服务器。 33 | 34 | ```shell 35 | $ npm run dev 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/src/ko/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | **Vutron** 템플릿은 `Electron`으로 사전 설정 된 크로스 플랫폼 데스크톱 앱입니다. 이 프로젝트는 `Vue 3`을 사용하여 적은 노력으로 빠른 빌드를 가능하게 해줍니다. 4 | 5 | ## 사용상의 이점 6 | 7 | - ✅ 복잡한 사전 설정 없이도 즉시 빌드할 수 있어 빠른 프로젝트 개발이 가능합니다. 8 | - ✅ 최신 `Vue`와 `Electron` 및 여러 모듈에 대해 신속하게 대응하여 유지 관리되고 있습니다. 9 | - ✅ 레이아웃, 데이터 상태 관리와 같은 다양한 사전 구성에 대해 걱정할 필요가 없습니다. 10 | 11 | ## 주요 기능 12 | 13 | - ⚡️ 핫 리로드 기능을 통한 빠른 개발 14 | - ⚡️ 크로스 플랫폼 개발 및 빌드 지원 15 | - ⚡️ 자동화된 GUI 테스팅 지원 16 | - ⚡️ TypeScript 지원 17 | - ⚡️ 다국어 지원 18 | - ⚡️ 테마 지원 (다크 & 라이트) 19 | - ⚡️ 기본적인 레이아웃 관리 20 | - ⚡️ Pinia 스토어를 활용한 글로벌 상태 관리 21 | - ⚡️ GitHub 커뮤니티와 공식 문서를 통한 프로젝트 기술지원 22 | -------------------------------------------------------------------------------- /src/main/index.dev.ts: -------------------------------------------------------------------------------- 1 | // Warning: This file is only used in the development environment 2 | // and is removed at build time. 3 | // Do not edit the file unless necessary. 4 | import { installExtension } from 'electron-extension-installer' 5 | import { app } from 'electron' 6 | 7 | const vue3DevTools = { 8 | id: 'nhdogjmejiglipccpnnnanhbledajbpd', 9 | version: '7.7.0' 10 | } 11 | 12 | try { 13 | app.on('ready', async () => { 14 | await installExtension(vue3DevTools, { 15 | loadExtensionOptions: { 16 | allowFileAccess: true 17 | } 18 | }) 19 | }) 20 | } catch { 21 | // Do nothing 22 | } 23 | -------------------------------------------------------------------------------- /src/renderer/locales/zh-hans.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "你好武特龙! 一切都准备好了。", 4 | "welcome-desc": "您现在可以编写跨平台的 Web 应用程序。 实时查看更改并使用一个命令构建到多个平台。 如果您还不熟悉它,可以从下面的文档页面获得帮助,或者运行一些预先编写的示例代码。", 5 | "second-desc": "您已移至第二个屏幕! 这里什么都没有!", 6 | "selected-file": "选定的文件:{filePath}." 7 | }, 8 | "title": { 9 | "main": "主屏幕", 10 | "second": "第二屏", 11 | "error": "未知错误" 12 | }, 13 | "menu": { 14 | "change-theme": "改变主题", 15 | "change-language": "改变语言", 16 | "increase-count": "计数 1 个增量", 17 | "documentation": "文档", 18 | "github": "源代码", 19 | "open-file": "打开文本文件" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/renderer/locales/zh-hant.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "你好武特龍! 一切都準備好了。", 4 | "welcome-desc": "您現在可以編寫跨平台的 Web 應用程序。 實時查看更改並使用一個命令構建到多個平台。 如果您還不熟悉它,可以從下面的文檔頁面獲得幫助,或者運行一些預先編寫的示例代碼。", 5 | "second-desc": "您已移至第二個屏幕! 這裡什麼都沒有!", 6 | "selected-file": "選定的文件:{filePath}." 7 | }, 8 | "title": { 9 | "main": "主屏幕", 10 | "second": "第二屏", 11 | "error": "未知錯誤" 12 | }, 13 | "menu": { 14 | "change-theme": "改變主題", 15 | "change-language": "改變語言", 16 | "increase-count": "計數 1 個增量", 17 | "documentation": "文檔", 18 | "github": "源代碼", 19 | "open-file": "開啟文字文件" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docs/src/en/other-projects.md: -------------------------------------------------------------------------------- 1 | # Other Projects 2 | 3 | ## Looking for Electron templates made with React? 4 | 5 | Also check out the `Retron` project, which consists of Vite + React + Material-UI + Electron. 6 | 7 | https://github.com/jooy2/retron 8 | 9 | ## (Deprecated) Looking for `Vutron` with Webpack 5 compiler? 10 | 11 | By using the Vite compiler, we achieved our goals of reducing project and bundle size, and improving development environment and build speed. 12 | 13 | The old **Vutron** using the Webpack 5 compiler has been split into the repositories below and will end support soon. 14 | 15 | https://github.com/jooy2/vutron-webpack 16 | -------------------------------------------------------------------------------- /docs/src/ko/installation-and-build/install-local-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 5 3 | --- 4 | 5 | # 로컬 문서 관리 6 | 7 | `Vutron`의 문서는 `VitePress` 뷰어를 통해 로컬 환경에서 볼 수 있습니다. 8 | 9 | 이 함수는 전체 프로젝트가 복제된 경우에만 작동합니다. `npm init vutron`으로 프로젝트를 생성한 경우 `docs` 폴더는 포함되지 않습니다. 10 | 11 | ## Installation 12 | 13 | 아래 지침의 모든 작업은 `docs` 폴더에서 수행해야 합니다. 14 | 15 | ```shell 16 | $ cd docs 17 | ``` 18 | 19 | 다음 명령을 사용하여 관련 패키지를 설치합니다: 20 | 21 | ```shell 22 | # via npm 23 | $ npm i 24 | 25 | # via yarn (https://yarnpkg.com) 26 | $ yarn install 27 | 28 | # via pnpm (https://pnpm.io) 29 | $ pnpm i 30 | ``` 31 | 32 | 아래 명령을 통해 문서가 호스팅되는 로컬 서버를 실행할 수 있습니다. 33 | 34 | ```shell 35 | $ npm run dev 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/src/zhHans/installation-and-build/automated-testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 4 3 | --- 4 | 5 | # 自动测试 6 | 7 | **Vutron**包括自动测试。测试框架使用微软的\*\*[Playwright](https://playwright.dev)。 8 | 9 | **Playwright**针对网络应用测试进行了优化,并完全支持**Electron**框架。它易于安装,无需配置即可立即开始测试,并且是跨平台的。您可以在此处了解有关**Playwright**的更多信息:https://github.com/microsoft/playwright 10 | 11 | 此模板仅对模板主屏幕进行了非常简单的启动和行为测试。高级测试取决于您的应用程序范围。 12 | 13 | 目前,测试规范文件位于`tests`目录中,测试结果文件位于`tests/results`中。(内置测试规范文件不会生成单独的结果文件。) 14 | 15 | Playwright配置文件位于项目根目录下的playwright.config.ts,更多信息请参阅以下文档:https://playwright.dev/docs/test-configuration 16 | 17 | 完成所有配置后,您可以使用以下命令进行测试。 18 | 19 | ```shell 20 | $ npm run test 21 | ``` 22 | 23 | 在运行测试之前,请清空构建目录(`dist`)并编译测试包。 24 | -------------------------------------------------------------------------------- /src/renderer/screens/SecondScreen.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 30 | -------------------------------------------------------------------------------- /src/renderer/locales/ko.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "안녕 Vutron! 모든 준비를 마쳤습니다.", 4 | "welcome-desc": "이제 크로스플랫폼 웹 애플리케이션을 작성할 수 있습니다. 변경사항을 실시간으로 확인하고 한 번의 명령으로 여러 플랫폼으로 빌드하세요. 아직 익숙하지 않다면, 아래 문서 페이지에서 도움을 받아보거나 사전에 작성된 예제 코드를 실행해볼 수 있습니다.", 5 | "second-desc": "두번째 화면으로 이동하였습니다! 여기는 아무 것도 없습니다!", 6 | "selected-file": "선택한 파일: {filePath}." 7 | }, 8 | "title": { 9 | "main": "메인 화면", 10 | "second": "두번째 화면", 11 | "error": "에러 발생" 12 | }, 13 | "menu": { 14 | "change-theme": "테마 변경", 15 | "change-language": "언어 변경", 16 | "increase-count": "카운트 1 증가", 17 | "documentation": "문서", 18 | "github": "소스코드", 19 | "open-file": "텍스트 파일 열기" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/renderer/locales/ja.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "こんにちはVutron! すべての準備が完了しました。", 4 | "welcome-desc": "これで、クロスプラットフォームのWebアプリケーションを作成できます。 変更内容をリアルタイムで確認し、一度のコマンドで複数のプラットフォームにビルドします。 まだ慣れていない場合は、以下のドキュメントページでヘルプを入手するか、事前に作成されたサンプルコードを実行してみてください。", 5 | "second-desc": "2番目の画面に移動しました! ここには何もありません!", 6 | "selected-file": "選択したファイル: {filePath}." 7 | }, 8 | "title": { 9 | "main": "メイン画面", 10 | "second": "2番目の画面", 11 | "error": "エラー発生" 12 | }, 13 | "menu": { 14 | "change-theme": "テーマの変更", 15 | "change-language": "言語の変更", 16 | "increase-count": "カウント1増加", 17 | "documentation": "文書", 18 | "github": "ソースコード", 19 | "open-file": "テキストファイルを開く" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docs/src/zhHans/project-structures/pre-configured-components.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 2 3 | --- 4 | 5 | # 预配置组件 6 | 7 | ## 网络应用框架 8 | 9 | - [Vite](https://vitejs.dev) 10 | - [Electron](https://www.electronjs.org) 11 | - [Electron Builder](https://www.electron.build) 12 | 13 | ## 开发帮助工具 14 | 15 | - [TypeScript](https://www.typescriptlang.org) 16 | - [ESLint](https://eslint.org) 17 | - [Prettier](https://prettier.io) 18 | 19 | ## 前端框架(Vue) 20 | 21 | - [Vue](https://vuejs.org) 22 | - [Vue-i18n](https://kazupon.github.io/vue-i18n) 23 | - [Vue-router](https://router.vuejs.org) 24 | - [Pinia](https://pinia.vuejs.org) 25 | 26 | ## 设计框架 27 | 28 | - [Vuetify](https://vuetifyjs.com) 29 | 30 | ## 测试 31 | 32 | - [Playwright](https://playwright.dev) 33 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "outDir": "./dist", 5 | "target": "esnext", 6 | "module": "Preserve", 7 | "moduleDetection": "force", 8 | "jsx": "preserve", 9 | "noImplicitAny": false, 10 | "allowSyntheticDefaultImports": true, 11 | "declaration": true, 12 | "resolveJsonModule": true, 13 | "esModuleInterop": true, 14 | "sourceMap": true, 15 | "strict": true, 16 | "skipLibCheck": true, 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "lib": ["esnext", "dom"] 21 | }, 22 | "include": ["src/*.ts", "src/*.d.ts", "src/renderer"], 23 | "references": [ 24 | { 25 | "path": "./tsconfig.node.json" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /docs/src/ko/project-structures/pre-configured-components.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 2 3 | --- 4 | 5 | # 사전 구성된 구성 요소 6 | 7 | ## 웹 앱 프레임워크 8 | 9 | - [Vite](https://vitejs.dev) 10 | - [Electron](https://www.electronjs.org) 11 | - [Electron Builder](https://www.electron.build) 12 | 13 | ## 개발 도움 도구 14 | 15 | - [TypeScript](https://www.typescriptlang.org) 16 | - [ESLint](https://eslint.org) 17 | - [Prettier](https://prettier.io) 18 | 19 | ## 프론트엔드 프레임워크 (Vue) 20 | 21 | - [Vue](https://vuejs.org) 22 | - [Vue-i18n](https://kazupon.github.io/vue-i18n) 23 | - [Vue-router](https://router.vuejs.org) 24 | - [Pinia](https://pinia.vuejs.org) 25 | 26 | ## 디자인 프레임워크 27 | 28 | - [Vuetify](https://vuetifyjs.com) 29 | 30 | ## 테스트 31 | 32 | - [Playwright](https://playwright.dev) 33 | -------------------------------------------------------------------------------- /docs/src/en/project-structures/pre-configured-components.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 2 3 | --- 4 | 5 | # Pre-configured Components 6 | 7 | ## Web app frameworks 8 | 9 | - [Vite](https://vitejs.dev) 10 | - [Electron](https://www.electronjs.org) 11 | - [Electron Builder](https://www.electron.build) 12 | 13 | ## Development help tools 14 | 15 | - [TypeScript](https://www.typescriptlang.org) 16 | - [ESLint](https://eslint.org) 17 | - [Prettier](https://prettier.io) 18 | 19 | ## Front-end frameworks (Vue) 20 | 21 | - [Vue](https://vuejs.org) 22 | - [Vue-i18n](https://kazupon.github.io/vue-i18n) 23 | - [Vue-router](https://router.vuejs.org) 24 | - [Pinia](https://pinia.vuejs.org) 25 | 26 | ## Design frameworks 27 | 28 | - [Vuetify](https://vuetifyjs.com) 29 | 30 | ## Testing 31 | 32 | - [Playwright](https://playwright.dev) 33 | -------------------------------------------------------------------------------- /docs/src/zhHans/electron-how-to/main-and-renderer-process.md: -------------------------------------------------------------------------------- 1 | # 主流程与渲染器流程 2 | 3 | 一个**Vutron**应用程序被分为代码,分为主进程和渲染器进程。 4 | 5 | **“主”**是`src/main`的代码,主要是由Electron处理的进程代码。**“渲染器”**是`src/renderer`的代码,主要用于前端渲染过程,如Vue。 6 | 7 | 一般来说,**Node.js**脚本无法在渲染器进程中运行。例如,包含Node.js使用的API的模块,或**Node.js**的本机模块,如`path`或`net`、`os`或`crypto`。 8 | 9 | 预加载脚本在渲染器加载之前运行。它为主进程创建了一个桥梁,出于安全考虑,将Node.js脚本的执行与渲染器区域分开并隔离。 10 | 11 | 为了安全执行脚本,建议主进程执行Node脚本,渲染器通过消息传递接收执行结果。这可以通过**IPC通信**来实现。 12 | 13 | 欲了解更多信息,请参阅以下文章: https://www.electronjs.org/docs/latest/tutorial/ipc 14 | 15 | ### 如何在渲染器上运行Node.js? 16 | 17 | 如果您想跳过安全问题并在渲染器中使用 Node.js 脚本,需要在 `vite.config.ts` 文件中将 `nodeIntegration` 设置为 `true`。 18 | 19 | ```javascript 20 | rendererPlugin({ 21 | nodeIntegration: true 22 | }) 23 | ``` 24 | 25 | 欲了解更多信息,请参阅以下文章: https://github.com/electron-vite/vite-plugin-electron-renderer 26 | -------------------------------------------------------------------------------- /src/renderer/router/index.ts: -------------------------------------------------------------------------------- 1 | import { MainScreen } from '@/renderer/screens' 2 | import { createRouter, createWebHashHistory } from 'vue-router' 3 | 4 | export default createRouter({ 5 | history: createWebHashHistory(), 6 | routes: [ 7 | { 8 | path: '/', 9 | component: MainScreen, 10 | meta: { 11 | titleKey: 'title.main' 12 | } 13 | }, 14 | { 15 | path: '/second', 16 | component: () => import('@/renderer/screens/SecondScreen.vue'), 17 | meta: { 18 | titleKey: 'title.second' 19 | } 20 | }, 21 | { 22 | path: '/error', 23 | component: () => import('@/renderer/screens/ErrorScreen.vue'), 24 | meta: { 25 | titleKey: 'title.error' 26 | } 27 | }, 28 | { 29 | path: '/:pathMatch(.*)*', 30 | redirect: '/' 31 | } 32 | ] 33 | }) 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/fix_typo.yml: -------------------------------------------------------------------------------- 1 | name: 'Fix typo request' 2 | description: Request to fix a typo or bad translation in this project 3 | labels: ['typo'] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Before creating an issue, please read the following: 9 | 10 | - Search to see if the same issue already exists, and keep the title concise and accurate so that it's easy for others to understand and search for. 11 | - Please create a separate issue for each type of issue. 12 | - Please be as detailed as possible and write in English so that we can handle your issue quickly. 13 | - type: textarea 14 | attributes: 15 | label: Describe the issue 16 | description: Please describe where the typo occurs and a list of text that needs to be corrected. 17 | validations: 18 | required: true 19 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.settings.useSplitJSON": true, 3 | "eslint.format.enable": true, 4 | "eslint.lintTask.enable": false, 5 | "eslint.codeActionsOnSave.rules": null, 6 | "editor.codeActionsOnSave": { 7 | "source.fixAll.eslint": "explicit" 8 | }, 9 | "eslint.validate": ["javascript", "vue"], 10 | "files.autoSave": "afterDelay", 11 | "editor.formatOnSave": true, 12 | "editor.wordWrap": "on", 13 | "editor.defaultFormatter": "esbenp.prettier-vscode", 14 | "[javascript]": { 15 | "editor.defaultFormatter": "esbenp.prettier-vscode" 16 | }, 17 | "editor.tabSize": 2, 18 | "prettier.embeddedLanguageFormatting": "off", 19 | "prettier.enable": true, 20 | "files.associations": { 21 | "*.mjs": "javascript", 22 | "*.cjs": "javascript", 23 | "*.mts": "typescript" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting Security Issues 4 | 5 | To report a security vulnerability, create an issue on GitHub on the "Open a draft security advisory " page on GitHub: https://github.com/jooy2/vutron/security/advisories/new 6 | 7 | Also, send private instructions in advance via maintainer email. Do not submit vulnerability-related content as a general issue. 8 | 9 | ## Security compliance 10 | 11 | Project maintainers are quickly addressing reported security vulnerabilities in the project and providing relevant patches. 12 | 13 | We report these to the relevant users and handle the correspondence to prevent the issue from recurring. 14 | 15 | ## Security recommendations 16 | 17 | We recommend that users of project sources use the latest version, which addresses possible security vulnerabilities. 18 | 19 | ## Contact 20 | 21 | - Administrator: jooy2.contact@gmail.com 22 | -------------------------------------------------------------------------------- /docs/src/en/installation-and-build/install-local-documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 5 3 | --- 4 | 5 | # Manage Local Documentation 6 | 7 | Documents from `Vutron` can be viewed in the local environment through the `VitePress` viewer. 8 | 9 | This function works only when the entire project is cloned. If you created the project with `npm init vutron`, the `docs` folder is not included. 10 | 11 | ## Installation 12 | 13 | Everything in the instructions below should be done in the `docs` folder. 14 | 15 | ```shell 16 | $ cd docs 17 | ``` 18 | 19 | Install the relevant packages using the following commands: 20 | 21 | ```shell 22 | # via npm 23 | $ npm i 24 | 25 | # via yarn (https://yarnpkg.com) 26 | $ yarn install 27 | 28 | # via pnpm (https://pnpm.io) 29 | $ pnpm i 30 | ``` 31 | 32 | You can run the local server where the documents are hosted via the command below. 33 | 34 | ```shell 35 | $ npm run dev 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/src/ko/installation-and-build/automated-testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 4 3 | --- 4 | 5 | # 자동화 테스트 6 | 7 | **Vutron**에는 자동화된 테스트가 포함되어 있습니다. 테스트 프레임워크는 Microsoft의 **[Playwright](https://playwright.dev)** 모듈을 사용합니다. 8 | 9 | **Playwright**는 웹 애플리케이션 테스트에 최적화되어 있으며 **Electron** 프레임워크를 완벽하게 지원합니다. 설치가 간단하고, 별도의 설정 없이 바로 테스트를 시작할 수 있으며, 크로스 플랫폼을 지원합니다. 여기에서 **Playwright**에 대해 자세히 알아보세요: https://github.com/microsoft/playwright 10 | 11 | 이 템플릿에는 템플릿 메인 화면에 대한 매우 간단한 실행 및 동작 테스트만 구현되어 있습니다. 고급 테스트는 애플리케이션의 범위에 따라 달라집니다. 12 | 13 | 현재 테스트 사양 파일은 `tests` 디렉터리에, 테스트 결과 파일은 `tests/results`에 있습니다. (기본 제공 테스트 사양 파일은 별도의 결과 파일을 생성하지 않습니다.) 14 | 15 | Playwright 설정은 프로젝트 루트에 있는 `playwright.config.ts`이며, 이에 대한 자세한 내용은 다음 문서를 참조하세요: https://playwright.dev/docs/test-configuration 16 | 17 | 모든 구성이 완료되면 다음 명령어로 테스트를 실행할 수 있습니다. 18 | 19 | ```shell 20 | $ npm run test 21 | ``` 22 | 23 | 테스트를 실행하기 전에 빌드 디렉터리(`dist`)를 비우고 테스트용 패키지를 컴파일합니다. 24 | -------------------------------------------------------------------------------- /src/renderer/locales/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "Hello Vutron! Everything is ready.", 4 | "welcome-desc": "You can now write cross-platform web applications. See changes in real time and build to multiple platforms with one command. If you're not already familiar with it, you can get help from the documentation page below, or run some pre-written example code.", 5 | "second-desc": "You have moved to the second screen! There is nothing here!", 6 | "selected-file": "Selected file: {filePath}." 7 | }, 8 | "title": { 9 | "main": "Main Screen", 10 | "second": "Second Screen", 11 | "error": "Unknown Error" 12 | }, 13 | "menu": { 14 | "change-theme": "Change Theme", 15 | "change-language": "Change Language", 16 | "increase-count": "Count 1 increment", 17 | "documentation": "Documentation", 18 | "github": "Source Code", 19 | "open-file": "Open a text file" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: 'Feature request' 2 | description: Report a feature request in this project. 3 | labels: ['enhancement'] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Before creating an issue, please read the following: 9 | 10 | - Search to see if the same issue already exists, and keep the title concise and accurate so that it's easy for others to understand and search for. 11 | - Please create a separate issue for each type of issue. 12 | - Please be as detailed as possible and write in English so that we can handle your issue quickly. 13 | - type: textarea 14 | attributes: 15 | label: Describe the feature 16 | description: Feel free to describe any features or improvements you would like to see. You can attach text or images of examples, behavior, etc. from other projects to elaborate. 17 | validations: 18 | required: true 19 | -------------------------------------------------------------------------------- /src/renderer/locales/nl.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "Hallo Vutron! Alles is klaar.", 4 | "welcome-desc": "U kunt nu platformonafhankelijke webapplicaties schrijven. Bekijk wijzigingen in realtime en bouw met één opdracht naar meerdere platforms. Als u hiermee nog niet bekend bent, kunt u hulp krijgen via de onderstaande documentatiepagina, of een vooraf geschreven voorbeeldcode uitvoeren.", 5 | "second-desc": "U bent naar het tweede scherm gegaan! Hier is niks!", 6 | "selected-file": "Geselecteerde bestand: {filePath}." 7 | }, 8 | "title": { 9 | "main": "Hoofdscherm", 10 | "second": "Tweede scherm", 11 | "error": "Onbekende Error" 12 | }, 13 | "menu": { 14 | "change-theme": "Thema veranderen", 15 | "change-language": "Taal wijzigen", 16 | "increase-count": "Één stap optellen", 17 | "documentation": "Documentatie", 18 | "github": "Broncode", 19 | "open-file": "Open een bestand" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docs/src/zhHans/electron-how-to/preload-script.md: -------------------------------------------------------------------------------- 1 | # 预加载脚本 2 | 3 | Electron.js中的预加载脚本是一个安全区域,用于主进程和渲染器进程之间的通信。它通常用于 **[IPC通信](https://www.electronjs.org/docs/latest/tutorial/ipc)**。 4 | 5 | 更多信息,请参阅以下文章: https://www.electronjs.org/docs/latest/tutorial/tutorial-preload 6 | 7 | 为了与最新版本的Electron兼容并确保安全,我们不建议使用旧的`electron/remote`模块。如果您想使用系统事件或Node脚本,建议在主进程中使用,而不是在渲染器中。 8 | 9 | Vutron的预加载脚本位于`src/preload`文件夹中。要创建新的IPC通信通道,请将通道名称添加到以下变量中,将其列入通信白名单。 10 | 11 | - `mainAvailChannels`: 从主程序发送事件到渲染程序。 (`window.mainApi.send('channelName')`) 12 | - `rendererAvailChannels`: 将事件从渲染器发送到主程序。 (`mainWindow.webContents.send('channelName')`) 13 | 14 | 当从渲染器向主程序发送事件时,应访问`window.mainApi`对象,而不是`ipcRenderer.send`。`mainApi`是您在自己的Vutron模板中设置的名称,可以更改。 15 | 16 | 以下是mainApi支持的功能: 17 | 18 | - `send`: 将活动发送至主页面。 19 | - `on`: 一个接收主发送事件的听众。 20 | - `once`: 接听主叫方发送的事件。(仅处理一个呼叫) 21 | - `off`: 移除事件监听器 22 | - `invoke`: 可异步发送事件和接收数据的功能。 23 | 24 | 要更改和修改此设置,您需要修改 `src/preload/index.ts` 中的 `exposeInMainWorld`。 25 | -------------------------------------------------------------------------------- /src/renderer/plugins/i18n.ts: -------------------------------------------------------------------------------- 1 | import { createI18n } from 'vue-i18n' 2 | import en from '@/renderer/locales/en.json' 3 | import ko from '@/renderer/locales/ko.json' 4 | import zhHans from '@/renderer/locales/zh-hans.json' 5 | import zhHant from '@/renderer/locales/zh-hant.json' 6 | import de from '@/renderer/locales/de.json' 7 | import es from '@/renderer/locales/es.json' 8 | import ja from '@/renderer/locales/ja.json' 9 | import fr from '@/renderer/locales/fr.json' 10 | import ru from '@/renderer/locales/ru.json' 11 | import pt from '@/renderer/locales/pt.json' 12 | import nl from '@/renderer/locales/nl.json' 13 | import { getCurrentLocale } from '@/renderer/utils' 14 | 15 | export default createI18n({ 16 | locale: getCurrentLocale(), 17 | fallbackLocale: 'en', 18 | globalInjection: true, 19 | messages: { 20 | en, 21 | ko, 22 | zhHans, 23 | zhHant, 24 | de, 25 | es, 26 | ja, 27 | fr, 28 | ru, 29 | pt, 30 | nl 31 | } 32 | }) 33 | -------------------------------------------------------------------------------- /src/renderer/locales/pt.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "Olá Vutron! Tudo está pronto.", 4 | "welcome-desc": "Agora você pode escrever aplicativos da Web de plataforma cruzada. Veja suas alterações em tempo real e crie para várias plataformas com um único comando. Se ainda não estiver familiarizado com ele, você pode obter ajuda na página de documentação abaixo ou executar algum código de exemplo pré-escrito.", 5 | "second-desc": "Movido para a segunda tela! Não há nenhum aqui!", 6 | "selected-file": "Arquivo selecionado: {filePath}." 7 | }, 8 | "title": { 9 | "main": "Tela principal", 10 | "second": "Segunda tela", 11 | "error": "Erro desconhecido" 12 | }, 13 | "menu": { 14 | "change-theme": "Mudar Tema", 15 | "change-language": "Mudar Idioma", 16 | "increase-count": "Aumentar a contagem em 1", 17 | "documentation": "Documento", 18 | "github": "Código fonte", 19 | "open-file": "Abra um arquivo de texto" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/renderer/locales/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "Привет Vutron! Все готово.", 4 | "welcome-desc": "Теперь вы можете писать кроссплатформенные веб-приложения. Просматривайте свои изменения в режиме реального времени и выполняйте сборку для нескольких платформ с помощью одной команды. Если вы еще не знакомы с ним, вы можете получить помощь на странице документации ниже или запустить предварительно написанный пример кода.", 5 | "second-desc": "Перенесено на второй экран! Здесь их нет!", 6 | "selected-file": "Выбранный файл: {filePath}." 7 | }, 8 | "title": { 9 | "main": "Главный экран", 10 | "second": "Второй экран", 11 | "error": "Неизвестная ошибка" 12 | }, 13 | "menu": { 14 | "change-theme": "Поменять тему", 15 | "change-language": "Изменить язык", 16 | "increase-count": "Увеличить количество на 1", 17 | "documentation": "Документ", 18 | "github": "Исходный код", 19 | "open-file": "Открыть текстовый файл" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/renderer/locales/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "Hola Vutron! Todo está listo.", 4 | "welcome-desc": "Ahora puede escribir aplicaciones web multiplataforma. Vea sus cambios en tiempo real y cree en múltiples plataformas con un solo comando. Si aún no está familiarizado con él, puede obtener ayuda en la página de documentación a continuación o ejecutar un código de ejemplo preescrito.", 5 | "second-desc": "¡Se ha movido a la segunda pantalla! ¡Aquí no hay nada!", 6 | "selected-file": "Archivo seleccionado: {filePath}." 7 | }, 8 | "title": { 9 | "main": "Pantalla Principal", 10 | "second": "Segunda Pantalla", 11 | "error": "Se produjo un error" 12 | }, 13 | "menu": { 14 | "change-theme": "Cambiar de Tema", 15 | "change-language": "Cambiar Idioma", 16 | "increase-count": "Aumentar la cuenta en 1", 17 | "documentation": "Documentación", 18 | "github": "Código Fuente", 19 | "open-file": "Abrir un archivo de texto" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docs/src/en/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | **Vutron** is a preconfigured template for developing `Electron` cross-platform desktop apps. It uses `Vue 3` and allows you to build a fast development environment with little effort. 4 | 5 | ## Advantages of use 6 | 7 | - ✅ You can build immediately without any presets, so you can develop quickly. 8 | - ✅ It is being maintained quickly to be compatible with the latest `Vue` and `Electron`, as well as many modules. 9 | - ✅ There is no need to worry about layout and data management by using various additional templates. 10 | 11 | ## Features 12 | 13 | - ⚡️ Rapid development through hot-reload 14 | - ⚡️ Cross-platform development and build support 15 | - ⚡️ Support for automated application testing 16 | - ⚡️ TypeScript support 17 | - ⚡️ Multilingual support 18 | - ⚡️ Support for themes (dark & light) 19 | - ⚡️ Basic layout manager 20 | - ⚡️ Global state management through the Pinia store 21 | - ⚡️ Quick support through the GitHub community and official documentation 22 | -------------------------------------------------------------------------------- /docs/src/zhHans/installation-and-build/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | --- 4 | 5 | # 入门 6 | 7 | ## 克隆项目 8 | 9 | ### 方法 1: `npm init` (推荐) 10 | 11 | 只需使用 npm 命令,就能轻松克隆一个版本库。 12 | 13 | ```shell 14 | $ npm init vutron 15 | ``` 16 | 17 | 上述方法不会为项目创建不必要的文档和`.github`相关文件。 18 | 19 | ### 方法 2: 使用此模板 20 | 21 | 点击 **[使用此模板](https://github.com/jooy2/vutron/generate)**,立即创建自己的项目。 22 | 23 | 此方法可立即在 GitHub 上创建一个仓库,但在使用之前,您需要在本地克隆该项目。 24 | 25 | ### 方法 3: 克隆该版本库 26 | 27 | 使用以下命令克隆该 repo。此方法适用于直接向 Vutron 代码库投稿。 28 | 29 | ```shell 30 | $ git clone https://github.com/jooy2/vutron 31 | ``` 32 | 33 | ## 安装 34 | 35 | 克隆项目后,在终端运行以下命令: 36 | 37 | ```shell 38 | # via npm 39 | $ npm i 40 | 41 | # via yarn (https://yarnpkg.com) 42 | $ yarn install 43 | 44 | # via pnpm (https://pnpm.io) 45 | $ pnpm i 46 | ``` 47 | 48 | ## 在开发环境中运行 49 | 50 | 开发环境中的应用程序通过 **[Vite](https://vitejs.dev)** 运行。 51 | 52 | ```shell 53 | $ npm run dev 54 | ``` 55 | 56 | 如果运行命令行命令后应用程序没有出现,您可能需要检查默认端口是否被其他应用程序使用。 57 | 58 | Vite 默认使用端口 `5173`。 59 | -------------------------------------------------------------------------------- /src/renderer/locales/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "Bonjour Vutron ! Tout est prêt.", 4 | "welcome-desc": "Vous pouvez maintenant écrire des applications Web multiplateformes. Visualisez vos modifications en temps réel et créez sur plusieurs plates-formes avec une seule commande. Si vous ne le connaissez pas encore, vous pouvez obtenir de l'aide sur la page de documentation ci-dessous ou exécuter un exemple de code pré-écrit.", 5 | "second-desc": "Déplacé vers le deuxième écran! Il n'y en a pas ici !", 6 | "selected-file": "Fichier sélectionné: {filePath}." 7 | }, 8 | "title": { 9 | "main": "écran principal", 10 | "second": "Deuxième écran", 11 | "error": "Erreur est survenue" 12 | }, 13 | "menu": { 14 | "change-theme": "Change le thème", 15 | "change-language": "Changer de langue", 16 | "increase-count": "Augmenter le nombre de 1", 17 | "documentation": "Document", 18 | "github": "Code source", 19 | "open-file": "Ouvrir un fichier texte" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/renderer/locales/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": { 3 | "welcome-title": "Hallo Vutron! Alles ist bereit.", 4 | "welcome-desc": "Sie können jetzt plattformübergreifende Webanwendungen schreiben. Sehen Sie Ihre Änderungen in Echtzeit und erstellen Sie mit einem einzigen Befehl auf mehreren Plattformen. Wenn Sie damit noch nicht vertraut sind, können Sie Hilfe von der Dokumentationsseite unten erhalten oder vorgefertigten Beispielcode ausführen.", 5 | "second-desc": "Auf den zweiten Bildschirm verschoben! Hier gibt es keine!", 6 | "selected-file": "Ausgewählte Datei: {filePath}." 7 | }, 8 | "title": { 9 | "main": "Hauptbildschirm", 10 | "second": "Zweiter Bildschirm", 11 | "error": "Ein Fehler ist aufgetreten" 12 | }, 13 | "menu": { 14 | "change-theme": "Thema wechseln", 15 | "change-language": "Sprache ändern", 16 | "increase-count": "Zählerstand um 1 erhöhen", 17 | "documentation": "dokumentieren", 18 | "github": "Quellcode", 19 | "open-file": "Öffnen Sie eine Textdatei" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docs/src/ko/electron-how-to/main-and-renderer-process.md: -------------------------------------------------------------------------------- 1 | # 메인과 렌더러 프로세스 2 | 3 | **Vutron** 애플리케이션은 메인(Main) 프로세스와 렌더러(Renderer) 프로세스로 코드가 나뉩니다. 4 | 5 | **Main**은 `src/main`의 코드로 주로 Electron이 처리하는 프로세스 코드입니다. **렌더러**는 `src/renderer`의 코드로 주로 Vue와 같은 프론트엔드 렌더링 프로세스를 위한 코드입니다. 6 | 7 | 일반적으로 **Node.js** 스크립트는 렌더러 프로세스에서 실행할 수 없습니다. 예를 들어 Node.js에서 사용하는 API를 포함하는 모듈이나 `path` 또는 `net`, `os` 또는 `crypto`와 같은 **Node.js**의 네이티브 모듈이 있습니다. 8 | 9 | 사전 로드 스크립트는 렌더러가 로드되기 전에 실행됩니다. 이는 보안상의 이유로 렌더러 영역에서 Node.js 스크립트의 실행을 분리하고 격리하기 위해 메인 프로세스에 대한 브릿지를 생성합니다. 10 | 11 | 안전한 스크립트 실행을 위해 메인 프로세스에서 노드 스크립트를 실행하고 렌더러는 메시징을 통해 실행 결과를 수신하는 것이 좋습니다. 이는 **IPC 통신**을 통해 구현할 수 있습니다. 12 | 13 | 이에 대한 자세한 내용은 다음 문서를 참조하세요: https://www.electronjs.org/docs/latest/tutorial/ipc 14 | 15 | ### 렌더러에서 Node.js를 실행하는 방법은 무엇인가요? 16 | 17 | 보안 문제를 건너뛰고 렌더러에서 Node.js 스크립트를 사용하려면 `vite.config.ts` 파일에서 `nodeIntegration`을 `true`로 설정해야 합니다. 18 | 19 | ```javascript 20 | rendererPlugin({ 21 | nodeIntegration: true 22 | }) 23 | ``` 24 | 25 | 이에 대한 자세한 내용은 다음 문서를 참조하세요: https://github.com/electron-vite/vite-plugin-electron-renderer 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # .gitignore for Node.js Projects 2 | # ---------- Start of common ignore files 3 | 4 | # Node artifact files 5 | node_modules/ 6 | 7 | # Log files 8 | *.log 9 | 10 | # dotenv environment variables file 11 | .env 12 | 13 | # JetBrains IDEs 14 | .idea/ 15 | *.iml 16 | 17 | # Visual Studio Code IDE 18 | .vscode/* 19 | !.vscode/settings.json 20 | !.vscode/tasks.json 21 | !.vscode/launch.json 22 | !.vscode/extensions.json 23 | !.vscode/*.code-snippets 24 | 25 | # Local History for Visual Studio Code 26 | .history/ 27 | 28 | # Built Visual Studio Code Extensions 29 | *.vsix 30 | 31 | # Generated by MacOS 32 | .DS_Store 33 | .AppleDouble 34 | .LSOverride 35 | 36 | # Generated by Windows 37 | Thumbs.db 38 | [Dd]esktop.ini 39 | $RECYCLE.BIN/ 40 | 41 | # Applications 42 | *.app 43 | *.pkg 44 | *.dmg 45 | *.exe 46 | *.war 47 | *.deb 48 | 49 | # Large media files 50 | *.mp4 51 | *.tiff 52 | *.avi 53 | *.flv 54 | *.mov 55 | *.wmv 56 | 57 | # ---------- End of common ignore files 58 | 59 | # Project Files 60 | dist/ 61 | release/ 62 | tests/results/ 63 | npm-debug.log 64 | npm-debug.log.* 65 | vite-plugin-electron.log 66 | -------------------------------------------------------------------------------- /tests/testUtil.mts: -------------------------------------------------------------------------------- 1 | import { Page } from 'playwright' 2 | import { TestInfo } from 'playwright/test' 3 | 4 | export default class TestUtil { 5 | _page: Page 6 | 7 | _testInfo: TestInfo 8 | 9 | _testScreenshotPath: string 10 | 11 | constructor(page: Page, testInfo: TestInfo, testScreenshotPath: string) { 12 | this._page = page 13 | this._testInfo = testInfo 14 | this._testScreenshotPath = testScreenshotPath 15 | } 16 | 17 | async captureScreenshot(pageInstance: Page, screenshotName: string) { 18 | if (!pageInstance) { 19 | return 20 | } 21 | 22 | try { 23 | const screenshotPath = `${this._testScreenshotPath}/${screenshotName || `unknown_${Date.now()}`}.png` 24 | 25 | await pageInstance.screenshot({ path: screenshotPath }) 26 | } catch { 27 | // Do nothing 28 | } 29 | } 30 | 31 | async onTestError(error: Error) { 32 | const titleLists = [...this._testInfo.titlePath] 33 | titleLists.shift() 34 | const title = titleLists.join('-') 35 | 36 | await this.captureScreenshot(this._page, `${title}_${Date.now()}`) 37 | 38 | return new Error(error.message) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2026 CDGet (https://cdget.com). 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /docs/src/ko/installation-and-build/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | --- 4 | 5 | # 시작하기 6 | 7 | ## 프로젝트 복제하기 8 | 9 | ### 방법 1: `npm init` (권장) 10 | 11 | npm 명령만으로 리포지토리를 쉽게 복제할 수 있습니다. 12 | 13 | ```shell 14 | $ npm init vutron 15 | ``` 16 | 17 | 위의 방법은 프로젝트에 불필요한 문서와 '.github' 관련 파일을 만들지 않습니다. 18 | 19 | ### 방법 2: 템플릿 사용 20 | 21 | **[이 템플릿 사용](https://github.com/jooy2/vutron/generate)** 버튼을 클릭하면 나만의 프로젝트를 즉시 만들 수 있습니다. 22 | 23 | 이 방법을 사용하면 GitHub에 리포지토리가 즉시 생성되지만 프로젝트를 로컬에 복제해야 사용할 수 있습니다. 24 | 25 | ### 방법 3: 리포지토리 복제 26 | 27 | 아래 명령어를 사용하여 이 리포지토리를 복제합니다. 이 방법은 Vutron 리포지토리에 직접 기여하는 경우에 적합합니다. 28 | 29 | ```shell 30 | $ git clone https://github.com/jooy2/vutron 31 | ``` 32 | 33 | ## 설치하기 34 | 35 | 프로젝트를 복제한 후 터미널에서 다음 명령을 실행합니다: 36 | 37 | ```shell 38 | # via npm 39 | $ npm i 40 | 41 | # via yarn (https://yarnpkg.com) 42 | $ yarn install 43 | 44 | # via pnpm (https://pnpm.io) 45 | $ pnpm i 46 | ``` 47 | 48 | ## 개발 환경에서 실행 49 | 50 | 개발 환경의 애플리케이션은 **[Vite](https://vitejs.dev)** 환경에서 실행됩니다. 51 | 52 | ```shell 53 | $ npm run dev 54 | ``` 55 | 56 | 명령줄 명령을 실행한 후에도 애플리케이션이 나타나지 않는다면 다른 앱에서 기본 포트를 사용하고 있는지 확인해야 할 수 있습니다. 57 | 58 | Vite는 기본적으로 포트 `5173`을 사용합니다. 59 | -------------------------------------------------------------------------------- /docs/src/ko/electron-how-to/preload-script.md: -------------------------------------------------------------------------------- 1 | # 프리로드 스크립트 2 | 3 | Electron.js의 프리로드 스크립트는 메인 프로세스와 렌더러 프로세스 간의 통신을 위해 설계된 보안 영역입니다. 일반적으로 **[IPC 통신](https://www.electronjs.org/docs/latest/tutorial/ipc)**에 사용됩니다. 4 | 5 | 자세한 내용은 다음 문서를 참고하세요: https://www.electronjs.org/docs/latest/tutorial/tutorial-preload 6 | 7 | 최신 버전의 Electron과의 호환성 및 보안을 위해 이전 버전의 `electron/remote` 모듈은 사용하지 않는 것이 좋습니다. 시스템 이벤트나 노드 스크립트를 활용하려면 렌더러가 아닌 메인 프로세스에서 사용하는 것이 좋습니다. 8 | 9 | Vutron의 프리로드 스크립트는 `src/preload` 폴더에 있습니다. 새 IPC 통신 채널을 생성하려면 다음 변수에 채널 이름을 추가하여 통신을 허용하도록 화이트리스트에 추가합니다. 10 | 11 | - `mainAvailChannels`: 메인에서 렌더러로 이벤트를 전송합니다. (`window.mainApi.send('channelName')`) 12 | - `rendererAvailChannels`: 렌더러에서 메인으로 이벤트를 전송합니다. (`mainWindow.webContents.send('channelName')`) 13 | 14 | 렌더러에서 메인으로 이벤트를 전송할 때는 `ipcRenderer.send` 대신 `window.mainApi` 객체에 액세스합니다. `mainApi`는 Vutron 템플릿에서 설정한 이름이며 변경할 수 있습니다. 15 | 16 | 다음은 mainApi에서 지원되는 함수입니다: 17 | 18 | - `send`: 메인으로 이벤트를 보냅니다. 19 | - `on`: 메인에서 보낸 이벤트를 수신할 리스너입니다. 20 | - `once`: 메인에서 보낸 이벤트를 수신할 리스너입니다. (하나의 호출만 처리) 21 | - `off`: 이벤트 리스너를 제거합니다. 22 | - `invoke`: 메인에 이벤트를 보내고 비동기적으로 데이터를 수신할 수 있는 함수입니다. 23 | 24 | 이를 변경하고 수정하려면 `src/preload/index.ts`에서 `exposeInMainWorld`를 수정해야 합니다. 25 | -------------------------------------------------------------------------------- /src/main/IPCs.ts: -------------------------------------------------------------------------------- 1 | import { ipcMain, shell, IpcMainEvent, dialog } from 'electron' 2 | import Constants from './utils/Constants' 3 | 4 | /* 5 | * IPC Communications 6 | * */ 7 | export default class IPCs { 8 | static initialize(): void { 9 | // Get application version 10 | ipcMain.handle('msgRequestGetVersion', () => { 11 | return Constants.APP_VERSION 12 | }) 13 | 14 | // Open url via web browser 15 | ipcMain.on( 16 | 'msgOpenExternalLink', 17 | async (event: IpcMainEvent, url: string) => { 18 | await shell.openExternal(url) 19 | } 20 | ) 21 | 22 | // Open file 23 | ipcMain.handle( 24 | 'msgOpenFile', 25 | async (event: IpcMainEvent, filter: string) => { 26 | const filters = [] 27 | if (filter === 'text') { 28 | filters.push({ name: 'Text', extensions: ['txt', 'json'] }) 29 | } else if (filter === 'zip') { 30 | filters.push({ name: 'Zip', extensions: ['zip'] }) 31 | } 32 | const dialogResult = await dialog.showOpenDialog({ 33 | properties: ['openFile'], 34 | filters 35 | }) 36 | return dialogResult 37 | } 38 | ) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/renderer/plugins/vuetify.ts: -------------------------------------------------------------------------------- 1 | import { createVuetify } from 'vuetify' 2 | import { 3 | ko, 4 | en, 5 | zhHans, 6 | zhHant, 7 | de, 8 | es, 9 | ja, 10 | fr, 11 | ru, 12 | pt, 13 | nl 14 | } from 'vuetify/locale' 15 | import { aliases, mdi } from 'vuetify/iconsets/mdi-svg' 16 | import 'vuetify/styles' 17 | 18 | import colors from 'vuetify/util/colors' 19 | 20 | export default createVuetify({ 21 | locale: { 22 | messages: { ko, en, zhHans, zhHant, de, es, ja, fr, ru, pt, nl }, 23 | locale: 'en', 24 | fallback: 'en' 25 | }, 26 | defaults: { 27 | VBtn: { 28 | style: [ 29 | { 30 | // Do not force capitalization of a button text 31 | textTransform: 'none' 32 | } 33 | ] 34 | } 35 | }, 36 | icons: { 37 | defaultSet: 'mdi', 38 | aliases, 39 | sets: { 40 | mdi 41 | } 42 | }, 43 | theme: { 44 | themes: { 45 | light: { 46 | dark: false, 47 | colors: { 48 | primary: colors.green.darken2 49 | } 50 | }, 51 | dark: { 52 | dark: true, 53 | colors: { 54 | primary: colors.green.darken4 55 | } 56 | } 57 | } 58 | } 59 | }) 60 | -------------------------------------------------------------------------------- /tests/specs/app.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect, beforeAll, afterAll } from '../fixtures.mjs' 2 | 3 | test.beforeAll(beforeAll) 4 | test.afterAll(afterAll) 5 | 6 | // @ts-expect-error: `util` is not using types in playwright 7 | test('Document element check', async ({ page, util }) => { 8 | try { 9 | await expect( 10 | page.getByTestId('main-logo').first(), 11 | `Confirm main logo is visible` 12 | ).toBeVisible() 13 | await expect( 14 | page.getByTestId('select-language').first(), 15 | `Confirm language selector is visible` 16 | ).toBeVisible() 17 | 18 | await util.captureScreenshot(page, 'result') 19 | } catch (error) { 20 | throw await util.onTestError(error) 21 | } 22 | }) 23 | 24 | // @ts-expect-error: `util` is not using types in playwright 25 | test('Counter button click check', async ({ page, util }) => { 26 | try { 27 | await page.getByTestId('btn-counter').click({ clickCount: 10, delay: 50 }) 28 | 29 | const counterValueElement = await page 30 | .getByTestId('counter-badge') 31 | .getByRole('status') 32 | .innerHTML() 33 | 34 | expect(counterValueElement).toBe('10') 35 | } catch (error) { 36 | throw await util.onTestError(error) 37 | } 38 | }) 39 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ## Pull request checklist 8 | 9 | You should familiarize yourself with the files `README.md`, `CONTRIBUTING.md`, and `CODE_OF_CONDUCT.md` in the root of your project. 10 | 11 | - If an issue has been created for this, add `(fixes #{ISSUE_NUMBER})` to the end of the commit description. In `{ISSUE_NUMBER}`, please include the relevant issue number. 12 | - If you need to update or add to the article, please update the relevant content. If a multilingual article exists, you should update all relevant content in your own language, except for translations. 13 | - Add or update test code if it exists and is needed. Also, verify that the tests pass. 14 | - If this PR is not yet complete, keep the PR in draft status. If it's no longer valid, close the PR with an explanation. 15 | 16 | 19 | 20 | ### What did you change? 21 | 22 | ### Why did you make the change? 23 | 24 | ### How does this work? 25 | -------------------------------------------------------------------------------- /docs/src/zhHans/installation-and-build/npm-scripts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: NPM Scripts 3 | order: 3 4 | --- 5 | 6 | # Npm 脚本 7 | 8 | > $ npm run %SCRIPT_NAME% 9 | 10 | ## 一般情况 11 | 12 | | 脚本名称 | 说明 | 13 | | --- | --- | 14 | | `dev` | 启动电子作为开发环境 | 15 | | `dev:debug` | 将 Electron 作为开发环境启动(使用 vite debug) | 16 | | `dev:debug:force` | 以Electron作为开发环境启动(使用vite调试+清理vite缓存) | 17 | | `build:pre` | 通常在编译时运行的命令。此脚本无需单独运行。 | 18 | | `build` | 为当前操作系统打包。 | 19 | | `build:all` | 为整个操作系统构建指定软件包(需要跨平台构建配置) | 20 | | `build:dir` | `electron-builder`目录构建 | 21 | | `build:mac` | 为macOS构建预配置软件包 | 22 | | `build:linux` | 为Linux构建预配置软件包 | 23 | | `build:win` | 为Windows构建预配置软件包 | 24 | | `lint` | ESLint代码检查。它不会修改代码。 | 25 | | `lint:fix` | ESLint代码检查。使用自动修复功能修复代码。 | 26 | | `format` | 更漂亮的代码检查。它不会修改代码。 | 27 | | `format:fix` | 更漂亮的代码检查。使用自动修复功能修复代码。 | 28 | | `test` | 根据测试规范文件构建测试包并运行测试。 | 29 | | `test:linux` | 根据测试规范文件构建测试包并运行测试。(仅适用于linux ci) | 30 | 31 | ## 文档 32 | 33 | 仅用于为项目文档提供素材。必须从“文档”目录位置运行。 34 | 35 | | Script Name | Description | 36 | | ----------- | ---------------------------------------------- | 37 | | `dev` | 启动本地文档服务器。(开发中) | 38 | | `build` | 构建本地文档服务器。仅用于 GitHub 页面构建器。 | 39 | | `serve` | 启动本地文档服务器。 | 40 | -------------------------------------------------------------------------------- /docs/src/en/installation-and-build/automated-testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 4 3 | --- 4 | 5 | # Automated Testing 6 | 7 | **Vutron** includes automated testing. The testing framework uses Microsoft's **[Playwright](https://playwright.dev)**. 8 | 9 | **Playwright** is optimized for web application testing and has full support for the **Electron** framework. It is simple to install, requires no configuration to start testing immediately, and is cross-platform. You can learn more about **Playwright** here: https://github.com/microsoft/playwright 10 | 11 | Only very simple launch and behavioral tests for the template main screen have been implemented in this template. Advanced testing will depend on the scope of your application. 12 | 13 | Currently, the test specification file is located in the `tests` directory and the test results file is located in `tests/results`. (The built-in test specification file does not generate a separate results file.) 14 | 15 | The Playwright configuration is `playwright.config.ts` in the project root, see the following documentation for more information on this: https://playwright.dev/docs/test-configuration 16 | 17 | Once everything is configured, you can run a test with the following command. 18 | 19 | ```shell 20 | $ npm run test 21 | ``` 22 | 23 | Before running the test, empty the build directory (`dist`) and compile the package for the test. 24 | -------------------------------------------------------------------------------- /docs/src/en/electron-how-to/main-and-renderer-process.md: -------------------------------------------------------------------------------- 1 | # Main vs Renderer Process 2 | 3 | A **Vutron** application is divided into code into a Main process and a Renderer process. 4 | 5 | **"Main"** is the code of `src/main` and is mainly the process code handled by Electron. **"Renderer"** is the code of `src/renderer`, mainly for front-end rendering process like Vue. 6 | 7 | In general, **Node.js** scripts cannot be run in the renderer process. Examples include modules that contain APIs used by Node.js, or native modules of **Node.js** such as `path` or `net`, `os` or `crypto`. 8 | 9 | Preload scripts are run before the renderer is loaded. It creates a bridge to the main process to keep the execution of Node.js scripts in the renderer area separate and isolated for security reasons. 10 | 11 | For secure script execution, it is recommended that the main process executes the Node scripts, and the renderer receives the execution results via messaging. This can be implemented via **IPC communication**. 12 | 13 | For more information on this, see the following articles: https://www.electronjs.org/docs/latest/tutorial/ipc 14 | 15 | ### How to run Node.js on a renderer? 16 | 17 | If you want to skip the security issues and use Node.js scripts in your renderer, you need to set `nodeIntegration` to `true` in your `vite.config.ts` file. 18 | 19 | ```javascript 20 | rendererPlugin({ 21 | nodeIntegration: true 22 | }) 23 | ``` 24 | 25 | For more information on this, see the following articles: https://github.com/electron-vite/vite-plugin-electron-renderer 26 | -------------------------------------------------------------------------------- /src/renderer/components/layout/HeaderLayout.vue: -------------------------------------------------------------------------------- 1 | 37 | 57 | 65 | -------------------------------------------------------------------------------- /docs/src/en/installation-and-build/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | --- 4 | 5 | # Getting Started 6 | 7 | ## Clone project 8 | 9 | ### Method 1: `npm init` (Recommend) 10 | 11 | You can easily clone a repository with just the npm command. 12 | 13 | ```shell 14 | $ npm init vutron 15 | ``` 16 | 17 | The above method will not create unnecessary documentation and `.github` related files for your project. 18 | 19 | ### Method 2: Use this template 20 | 21 | Click **[Use this template](https://github.com/jooy2/vutron/generate)** to instantly create your own project. 22 | 23 | This method creates a repository on GitHub immediately, but you will need to clone the project locally before you can use it. 24 | 25 | ### Method 3: Clone this repository 26 | 27 | Clone this repo using below command. This method is suitable for direct contributions to the Vutron repository. 28 | 29 | ```shell 30 | $ git clone https://github.com/jooy2/vutron 31 | ``` 32 | 33 | ## Installation 34 | 35 | After cloning the project, run the following command in the terminal: 36 | 37 | ```shell 38 | # via npm 39 | $ npm i 40 | 41 | # via yarn (https://yarnpkg.com) 42 | $ yarn install 43 | 44 | # via pnpm (https://pnpm.io) 45 | $ pnpm i 46 | ``` 47 | 48 | ## Run in development environment 49 | 50 | Applications in the development environment run through **[Vite](https://vitejs.dev)**. 51 | 52 | ```shell 53 | $ npm run dev 54 | ``` 55 | 56 | If your application doesn't appear after running command line commands, you may need to review if the default port is being used by another app. 57 | 58 | Vite uses port `5173` by default. 59 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "compounds": [ 4 | { 5 | "name": "Debug Everything", 6 | "configurations": [ 7 | "Launch App", 8 | "Attach to Main Process", 9 | "Attach to Renderer Process" 10 | ], 11 | "presentation": { 12 | "hidden": false, 13 | "group": "", 14 | "order": 1 15 | }, 16 | "stopAll": true 17 | } 18 | ], 19 | "configurations": [ 20 | { 21 | "name": "Launch App", 22 | "request": "launch", 23 | "type": "node", 24 | "timeout": 60000, 25 | "runtimeArgs": [ 26 | "run-script", 27 | "dev" 28 | ], 29 | "cwd": "${workspaceRoot}", 30 | "runtimeExecutable": "npm", 31 | "console": "integratedTerminal", 32 | "env": { 33 | "REMOTE_DEBUGGING_PORT": "9229" 34 | }, 35 | "outputCapture": "std", 36 | "sourceMaps": true 37 | }, 38 | { 39 | "name": "Attach to Main Process", 40 | "type": "node", 41 | "request": "attach", 42 | "port": 9228, 43 | "restart": false, 44 | "timeout": 10000, 45 | "skipFiles": ["/**"], 46 | "sourceMaps": true, 47 | "outFiles": ["${workspaceFolder}/dist/**/*.js"], 48 | "outputCapture": "std", 49 | "env": { 50 | "REMOTE_DEBUGGING_PORT": "9228" 51 | } 52 | }, 53 | { 54 | "name": "Attach to Renderer Process", 55 | "type": "chrome", 56 | "request": "attach", 57 | "port": 9229, 58 | "webRoot": "${workspaceFolder}/src/renderer", 59 | "timeout": 30000 60 | } 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /docs/src/en/electron-how-to/preload-script.md: -------------------------------------------------------------------------------- 1 | # Preload Script 2 | 3 | The preload script in Electron.js is a secure area designed for communication between the main and renderer processes. It is typically used for **[IPC communication](https://www.electronjs.org/docs/latest/tutorial/ipc)**. 4 | 5 | For more information, see the following articles https://www.electronjs.org/docs/latest/tutorial/tutorial-preload 6 | 7 | For compatibility and security with the latest version of Electron, we do not recommend using the old `electron/remote` module. If you want to utilize system events or Node scripts, it is recommended to do so in the main process, not the renderer. 8 | 9 | Vutron's preload script is located in the `src/preload` folder. To create a new IPC communication channel, add the channel name to the following variable to whitelist it for communication. 10 | 11 | - `mainAvailChannels`: Send an event from main to renderer. (`window.mainApi.send('channelName')`) 12 | - `rendererAvailChannels`: Send an event from renderer to main. (`mainWindow.webContents.send('channelName')`) 13 | 14 | When sending events from renderer to main, you access the `window.mainApi` object instead of `ipcRenderer.send`. The `mainApi` is the name you set in your Vutron template and can be changed. 15 | 16 | Here are the supported functions for mainApi: 17 | 18 | - `send`: Send an event to main. 19 | - `on`: A listener to receive events sent by main. 20 | - `once`: A listener to receive events sent by main. (Handle only one call) 21 | - `off`: Remove an event listener 22 | - `invoke`: Functions that can send events to main and receive data asynchronously. 23 | 24 | To change and modify this, you need to modify `exposeInMainWorld` in `src/preload/index.ts`. 25 | -------------------------------------------------------------------------------- /docs/src/ko/installation-and-build/npm-scripts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: NPM Scripts 3 | order: 3 4 | --- 5 | 6 | # Npm 스크립트 7 | 8 | > $ npm run %SCRIPT_NAME% 9 | 10 | ## 일반 11 | 12 | | Script Name | Description | 13 | | --- | --- | 14 | | `dev` | Start Electron as a development environment | 15 | | `dev:debug` | Start Electron as a development environment (with vite debug) | 16 | | `dev:debug:force` | Start Electron as a development environment (with vite debug + clean vite cache) | 17 | | `build:pre` | Commands commonly run at build time. This script does not need to be run separately. | 18 | | `build` | Build the package for the current operating system. | 19 | | `build:all` | Build a specified package for the entire operating system (Requires cross-platform build configuration) | 20 | | `build:dir` | `electron-builder` directory build | 21 | | `build:mac` | Build preconfigured packages for macOS | 22 | | `build:linux` | Build preconfigured packages for Linux | 23 | | `build:win` | Build preconfigured packages for Windows | 24 | | `lint` | ESLint code inspection. It does not modify the code. | 25 | | `lint:fix` | ESLint code inspection. Use auto-fix to fix your code. | 26 | | `format` | Prettier code inspection. It does not modify the code. | 27 | | `format:fix` | Prettier code inspection. Use auto-fix to fix your code. | 28 | | `test` | Build a package for testing and run tests against the test specification file. | 29 | | `test:linux` | Build a package for testing and run tests against the test specification file. (for linux ci only) | 30 | 31 | ## 문서용 32 | 33 | 프로젝트 문서에 기여하는 경우에만 사용됩니다. `docs` 디렉토리 위치에서 실행해야 합니다. 34 | 35 | | Script Name | Description | 36 | | --- | --- | 37 | | `dev` | Start the local document server. (For development) | 38 | | `build` | Build a local document server. Used only for GitHub page builders. | 39 | | `serve` | Start the local document server. | 40 | -------------------------------------------------------------------------------- /.github/workflows/app-test.yml: -------------------------------------------------------------------------------- 1 | name: app-test 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | paths: 7 | - '**' 8 | - '!LICENSE' 9 | - '!*.md' 10 | - '!docs/**' 11 | - '!.github/**' 12 | - '.github/workflows/app-test.yml' 13 | pull_request: 14 | branches: [main] 15 | workflow_dispatch: 16 | 17 | jobs: 18 | app-test: 19 | runs-on: ${{ matrix.os }} 20 | name: Test Node.js ${{ matrix.node_version }} on ${{ matrix.os }} 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | node_version: ['20', '22', '24'] 25 | os: [windows-latest, macos-latest, ubuntu-latest] 26 | 27 | steps: 28 | - uses: actions/checkout@v4 29 | with: 30 | fetch-depth: 0 31 | 32 | - name: Install xvfb 33 | if: runner.os == 'Linux' 34 | run: | 35 | sudo apt install -y -q --no-install-recommends xvfb 36 | 37 | - name: Setup Node.js ${{ matrix.node_version }} 38 | uses: actions/setup-node@v4 39 | with: 40 | node-version: ${{ matrix.node_version }} 41 | cache: npm 42 | cache-dependency-path: '**/package-lock.json' 43 | 44 | - name: Cache dependencies 45 | uses: actions/cache@v4 46 | id: npm-cache 47 | with: 48 | path: | 49 | **/node_modules 50 | key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} 51 | restore-keys: | 52 | ${{ runner.os }}-npm- 53 | 54 | - name: Install dependencies 55 | if: steps.npm-cache.outputs.cache-hit != 'true' 56 | run: npm i 57 | 58 | - name: Test module script (Windows or macOS) 59 | if: runner.os != 'Linux' 60 | run: | 61 | npm run test 62 | 63 | - name: Test module script (Linux) 64 | if: runner.os == 'Linux' 65 | run: | 66 | npm run test:linux 67 | -------------------------------------------------------------------------------- /docs/src/en/installation-and-build/npm-scripts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: NPM Scripts 3 | order: 3 4 | --- 5 | 6 | # Npm Scripts 7 | 8 | > $ npm run %SCRIPT_NAME% 9 | 10 | ## General 11 | 12 | | Script Name | Description | 13 | | --- | --- | 14 | | `dev` | Start Electron as a development environment | 15 | | `dev:debug` | Start Electron as a development environment (with vite debug) | 16 | | `dev:debug:force` | Start Electron as a development environment (with vite debug + clean vite cache) | 17 | | `build:pre` | Commands commonly run at build time. This script does not need to be run separately. | 18 | | `build` | Build the package for the current operating system. | 19 | | `build:all` | Build a specified package for the entire operating system (Requires cross-platform build configuration) | 20 | | `build:dir` | `electron-builder` directory build | 21 | | `build:mac` | Build preconfigured packages for macOS | 22 | | `build:linux` | Build preconfigured packages for Linux | 23 | | `build:win` | Build preconfigured packages for Windows | 24 | | `lint` | ESLint code inspection. It does not modify the code. | 25 | | `lint:fix` | ESLint code inspection. Use auto-fix to fix your code. | 26 | | `format` | Prettier code inspection. It does not modify the code. | 27 | | `format:fix` | Prettier code inspection. Use auto-fix to fix your code. | 28 | | `test` | Build a package for testing and run tests against the test specification file. | 29 | | `test:linux` | Build a package for testing and run tests against the test specification file. (for linux ci only) | 30 | 31 | ## For Documentation 32 | 33 | Used only for contributing to project documentation. Must be run from the `docs` directory location. 34 | 35 | | Script Name | Description | 36 | | --- | --- | 37 | | `dev` | Start the local document server. (For development) | 38 | | `build` | Build a local document server. Used only for GitHub page builders. | 39 | | `serve` | Start the local document server. | 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: 'Bug report' 2 | description: Report a bug in this project. 3 | labels: ['bug'] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Before creating an issue, please read the following: 9 | 10 | - Read the `README.md` file on the project page or the documentation file and compare your code to the intent of the project. 11 | - Search to see if the same issue already exists, and keep the title concise and accurate so that it's easy for others to understand and search for. 12 | - Please create a separate issue for each type of issue. 13 | - For modular projects, make sure you're using the latest version of the module. 14 | - Please be as detailed as possible and write in English so that we can handle your issue quickly. 15 | - type: textarea 16 | attributes: 17 | label: Describe the bug 18 | description: | 19 | For the issue you are experiencing, please describe in detail what you are seeing, the error message, and the impact of the issue. If you are able to reproduce the issue, please list the steps in order. You can attach an image or video if necessary. 20 | validations: 21 | required: true 22 | - type: textarea 23 | attributes: 24 | label: Expected behavior 25 | description: Describe how it should be handled when it's normal behavior or what needs to be fixed. 26 | validations: 27 | - type: input 28 | attributes: 29 | label: Your environment - System OS 30 | description: Please describe the full range of OSes you are experiencing the issue with, preferably including the version. 31 | placeholder: Windows 11, macOS 15.x, Linux Ubuntu 24.04, Android 15, iOS 16... 32 | validations: 33 | - type: input 34 | attributes: 35 | label: Your environment - Web Browser 36 | description: If relevant, please describe the web browser you are currently using. 37 | placeholder: Google Chrome, Microsoft Edge, Mozilla Firefox... 38 | validations: 39 | -------------------------------------------------------------------------------- /.github/workflows/documents.yml: -------------------------------------------------------------------------------- 1 | name: documents 2 | 3 | on: 4 | # run every time a push occurs in the docs folder 5 | push: 6 | branches: [main] 7 | paths: 8 | - docs/** 9 | - README.md 10 | # trigger deployment manually 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build-documentation-pages: 15 | runs-on: ubuntu-latest 16 | defaults: 17 | run: 18 | working-directory: ./docs 19 | 20 | steps: 21 | - uses: actions/checkout@v4 22 | with: 23 | # fetch all commits to get last updated time or other git log info 24 | fetch-depth: 0 25 | 26 | - name: Setup Node.js 27 | uses: actions/setup-node@v4 28 | with: 29 | node-version: '24' 30 | 31 | # cache node_modules 32 | - name: Cache dependencies 33 | uses: actions/cache@v4 34 | id: npm-cache 35 | with: 36 | path: | 37 | **/node_modules 38 | key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} 39 | restore-keys: | 40 | ${{ runner.os }}-npm- 41 | 42 | # install dependencies if the cache did not hit 43 | - name: Install dependencies 44 | if: steps.npm-cache.outputs.cache-hit != 'true' 45 | run: npm install 46 | 47 | # run build script 48 | - name: Build VitePress site 49 | run: npm run build 50 | 51 | # please check out the docs of the workflow for more details 52 | # @see https://github.com/crazy-max/ghaction-github-pages 53 | - name: Deploy to GitHub Pages 54 | uses: crazy-max/ghaction-github-pages@v4 55 | with: 56 | # deploy to gh-pages branch 57 | target_branch: gh-pages 58 | # deploy the default output dir of VitePress 59 | build_dir: docs/dist 60 | jekyll: false 61 | fqdn: 'vutron.cdget.com' 62 | env: 63 | # @see https://docs.github.com/en/actions/reference/authentication-in-a-workflow#about-the-github_token-secret 64 | GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} 65 | -------------------------------------------------------------------------------- /src/preload/index.ts: -------------------------------------------------------------------------------- 1 | import log from 'electron-log/renderer' 2 | import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron' 3 | 4 | // Initialize renderer logger 5 | log.transports.console.level = 'silly' 6 | log.transports.console.format = '{h}:{i}:{s}.{ms} {text}' 7 | 8 | // Whitelist of valid channels used for IPC communication (Send message from Renderer to Main) 9 | const mainAvailChannels: string[] = [ 10 | 'msgRequestGetVersion', 11 | 'msgOpenExternalLink', 12 | 'msgOpenFile' 13 | ] 14 | const rendererAvailChannels: string[] = [] 15 | 16 | contextBridge.exposeInMainWorld('mainApi', { 17 | send: (channel: string, ...data: any[]): void => { 18 | if (mainAvailChannels.includes(channel)) { 19 | ipcRenderer.send.apply(null, [channel, ...data]) 20 | } else { 21 | throw new Error(`Unknown ipc channel name: ${channel}`) 22 | } 23 | }, 24 | on: ( 25 | channel: string, 26 | listener: (event: IpcRendererEvent, ...args: any[]) => void 27 | ): void => { 28 | if (rendererAvailChannels.includes(channel)) { 29 | ipcRenderer.on(channel, listener) 30 | } else { 31 | throw new Error(`Unknown ipc channel name: ${channel}`) 32 | } 33 | }, 34 | once: ( 35 | channel: string, 36 | listener: (event: IpcRendererEvent, ...args: any[]) => void 37 | ): void => { 38 | if (rendererAvailChannels.includes(channel)) { 39 | ipcRenderer.once(channel, listener) 40 | } else { 41 | throw new Error(`Unknown ipc channel name: ${channel}`) 42 | } 43 | }, 44 | off: ( 45 | channel: string, 46 | listener: (event: IpcRendererEvent, ...args: any[]) => void 47 | ): void => { 48 | if (rendererAvailChannels.includes(channel)) { 49 | ipcRenderer.off(channel, listener) 50 | } else { 51 | throw new Error(`Unknown ipc channel name: ${channel}`) 52 | } 53 | }, 54 | invoke: async (channel: string, ...data: any[]): Promise => { 55 | if (mainAvailChannels.includes(channel)) { 56 | const result = await ipcRenderer.invoke.apply(null, [channel, ...data]) 57 | return result 58 | } 59 | 60 | throw new Error(`Unknown ipc channel name: ${channel}`) 61 | } 62 | }) 63 | -------------------------------------------------------------------------------- /src/main/utils/Constants.ts: -------------------------------------------------------------------------------- 1 | import { join, dirname, resolve } from 'path' 2 | import { name, version, debug } from '../../../package.json' 3 | import { fileURLToPath } from 'url' 4 | 5 | const __dirname = dirname(fileURLToPath(import.meta.url)) 6 | 7 | export interface TrayOptions { 8 | enabled: boolean 9 | trayWindow: boolean 10 | menu: boolean 11 | tooltip: string 12 | margin: { x: number; y: number } 13 | showAtStartup: boolean 14 | } 15 | 16 | export default class Constants { 17 | /* ------------------------------------------------------ 18 | * Vutron app feature list 19 | * 20 | * This template includes examples so you can try out several Electron features. 21 | * To remove them from your project, you'll need to disable the features below, or find and delete the related code. 22 | * ------------------------------------------------------ */ 23 | // To show devtools at startup. It requires IS_DEV_ENV=true. 24 | // Note: For debugging purpose, window won't be closed if click elsewhere, if devtools is open. 25 | static FEAT_OPEN_DEV_TOOLS_AT_START = true 26 | /* ------------------------------------------------------ 27 | * END OF FEATURES 28 | * ------------------------------------------------------ */ 29 | 30 | // Display app name (uppercase first letter) 31 | static APP_NAME = name.charAt(0).toUpperCase() + name.slice(1) 32 | 33 | static APP_VERSION = version 34 | 35 | static IS_DEV_ENV = process.env.NODE_ENV === 'development' 36 | 37 | static PUBLIC_PATH = Constants.IS_DEV_ENV 38 | ? resolve(__dirname, '../../src/public') 39 | : resolve(__dirname, '..') 40 | 41 | static IS_MAC = process.platform === 'darwin' 42 | 43 | static DEFAULT_WEB_PREFERENCES = { 44 | nodeIntegration: false, 45 | contextIsolation: true, 46 | enableRemoteModule: false, 47 | preload: join(__dirname, '../preload/index.js') 48 | } 49 | 50 | static DEFAULT_TRAY_OPTIONS: TrayOptions = { 51 | enabled: false, 52 | trayWindow: false, 53 | menu: false, 54 | tooltip: 'Vutron App', 55 | margin: { x: 0, y: 0 }, 56 | showAtStartup: false 57 | } 58 | 59 | static APP_INDEX_URL_DEV = `${debug.env.VITE_DEV_SERVER_URL}/index.html` 60 | static APP_INDEX_URL_PROD = join(__dirname, '../index.html') 61 | } 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ![vutron-logo](src/public/images/vutron-logo.webp) 4 | 5 | --- 6 | 7 | Quick Start Templates for **[Vite](https://vitejs.dev)** + **[Vue 3](https://vuejs.org)** + **[Electron](https://www.electronjs.org)** 8 | 9 | [![awesome-vite](https://awesome.re/mentioned-badge.svg)](https://github.com/vitejs/awesome-vite) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jooy2/vutron/blob/main/LICENSE) ![Stars](https://img.shields.io/github/stars/jooy2/vutron?style=social) ![Commit Count](https://img.shields.io/github/commit-activity/y/jooy2/vutron) [![Followers](https://img.shields.io/github/followers/jooy2?style=social)](https://github.com/jooy2) 10 | 11 | ![vutron-logo](.github/resources/vutron-sample.webp) 12 | 13 | **Vutron** is a preconfigured template for developing `Electron` cross-platform desktop apps. It uses `Vue 3` and allows you to build a fast development environment with little effort. 14 | 15 |
16 | 17 | ## Advantages of use 18 | 19 | - ✅ You can build immediately without any presets, so you can develop quickly. 20 | - ✅ It is being maintained quickly to be compatible with the latest `Vue` and `Electron`, as well as many modules. 21 | - ✅ There is no need to worry about layout and data management by using various additional templates. 22 | 23 | ## Features 24 | 25 | - ⚡️ Rapid development through hot-reload 26 | - ⚡️ Cross-platform development and build support 27 | - ⚡️ Support for automated application testing 28 | - ⚡️ TypeScript support 29 | - ⚡️ Multilingual support 30 | - ⚡️ Support for themes (dark & light) 31 | - ⚡️ Basic layout manager 32 | - ⚡️ Global state management through the Pinia store 33 | - ⚡️ Quick support through the GitHub community and official documentation 34 | 35 | ## [Documentation (Getting Started)](https://vutron.cdget.com/installation-and-build/getting-started) 36 | 37 | For complete documentation including installation instructions and basic usage, please refer to each item in the link below: https://vutron.cdget.com/installation-and-build/getting-started 38 | 39 | ## Contributing 40 | 41 | Anyone can contribute to the project by reporting new issues or submitting a pull request. For more information, please see [CONTRIBUTING.md](CONTRIBUTING.md). 42 | 43 | ## License 44 | 45 | Please see the [LICENSE](LICENSE) file for more information about project owners, usage rights, and more. 46 | -------------------------------------------------------------------------------- /docs/src/zhHans/project-structures/project-structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | --- 4 | 5 | # 项目结构 6 | 7 | ``` 8 | / 9 | ├─ .github - GitHub文件(仅用于Vutron GitHub项目贡献) 10 | │ └─ ISSUE_TEMPLATE/ 11 | │ └─ resources/ - 用于自述文件(README.md)等的GitHub资源。 12 | │ └─ workflows/ - GitHub工作流程定义 13 | │ └─ dependabot.yml 14 | │ └─ FUNDING.yml 15 | ├─ .vscode - Visual Studio Code IDE使用的通用项目配置文件 16 | ├─ buildAssets/ - 用于Electron构建的资源包(图标、徽标等)文件 17 | │ └─ builder/ 18 | │ │ │ └─ config.ts - `electron-builder`动态配置文件 19 | │ └─ icons/ 20 | ├─ dist/ - 用于生成软件包的输出目录 21 | ├─ docs/ - 项目文件(可选) 22 | │ └─ .vitepress/ 23 | │ │ │ └─ config.mts - 用于文档托管的VitePress配置文件 24 | │ └─ public/ - VitePress文档页面的根目录 25 | ├─ node_modules/ 26 | ├─ src/ 27 | │ ├─ main/ - 主(电子)处理源代码 28 | │ │ ├─ utils/ - 主要工艺设备 29 | │ │ │ └─ Constants.ts - 全球主要定义 30 | │ │ │ └─ Menus.ts - 全球主菜单定义 31 | │ │ └─ index.ts - 主要流程入口 32 | │ │ └─ IPCs.ts - 主要流程 ipc 处理程序定义 33 | │ │ └─ MainRunner.ts - 主流程主窗口处理 34 | │ ├─ preload/ - 预加载(Electron-Vue通信桥)过程源代码 35 | │ │ └─ index.ts 36 | │ ├─ public/ - Main + Renderer静态资源 37 | │ │ └─ images/ 38 | │ ├─ renderer/ - 渲染器(Vue)处理源代码 39 | │ │ ├─ components/ - Vue组件集合 40 | │ │ │ └─ layout/ - 布局组件 41 | │ │ ├─ locales/ - Vue i18n 语言资源文件 42 | │ │ ├─ plugins/ - Vue插件定义 43 | │ │ ├─ router/ - 视图路由定义 44 | │ │ ├─ screens/ - 屏幕组件 45 | │ │ │ └─ ErrorScreen.vue - 当渲染程序出现错误时,屏幕上会显示错误信息 46 | │ │ │ └─ MainScreen.vue 47 | │ │ │ └─ SecondScreen.vue - 屏幕截图 48 | │ │ ├─ store/ - Pinia商店(全球状态管理)定义 49 | │ │ ├─ utils/ - 渲染器进程实用程序 50 | │ │ ├─ App.vue - Vue应用程序的根组件 51 | │ │ ├─ index.html - 由电子渲染器进程加载的根静态索引 52 | │ └─ └─ main.ts - 渲染器进程入口点 53 | ├─ tests/ - 应用程序测试配置 54 | │ ├─ results/ - PlayWright测试结果文件和屏幕截图的保存位置 55 | │ ├─ specs/ - PlayWright测试规格文件 56 | │ ├─ fixtures.ts - 测试公共执行API 57 | │ └─ testUtil.ts - 测试实用程序 58 | ├─ .editorconfig - 编辑器推荐的IDE配置文件 59 | ├─ .eslintignore - ESLint忽略的文件列表 60 | ├─ .gitignore - 不上传到Git的文件列表 61 | ├─ .prettierignore - 要禁用的文件列表 更美观的文件格式 62 | ├─ .prettierrc - 更漂亮的规则配置 63 | ├─ CODE_OF_CONDUCT.md - 仅在GitHub上使用的文件 64 | ├─ eslint.config.ts - ESLint规则配置 65 | ├─ LICENSE - 项目许可证文件 66 | ├─ package.json - Node.js 包配置 67 | ├─ package-lock.json 68 | ├─ playwright.config.ts - 编剧测试规则配置 69 | ├─ pnpm-lock.yaml - PNPM 相关文件 70 | ├─ pnpm-workspace.yaml - PNPM 相关文件 71 | ├─ tsconfig.json - TypeScript配置 72 | ├─ tsconfig.node.json - TypeScript配置 73 | ├─ vite.config.mts - Vite编译器构建配置 74 | └─ README.md - 仅在GitHub上使用的文件 75 | ``` 76 | -------------------------------------------------------------------------------- /tests/fixtures.mts: -------------------------------------------------------------------------------- 1 | import * as base from '@playwright/test' 2 | import { _electron as electron, Page, ElectronApplication } from 'playwright' 3 | import { join } from 'path' 4 | import { main } from '../package.json' 5 | import TestUtil from './testUtil.mjs' 6 | 7 | let appElectron: ElectronApplication 8 | let page: Page 9 | 10 | const __cwd = process.cwd() 11 | const __isCiProcess = process.env.CI === 'true' 12 | const __testPath = join(__cwd, 'tests') 13 | const __testResultPath = join(__testPath, 'results') 14 | const __testScreenshotPath = join(__testResultPath, 'screenshots') 15 | 16 | export const beforeAll = async () => { 17 | // Open Electron app from build directory 18 | appElectron = await electron.launch({ 19 | args: [ 20 | main, 21 | ...(__isCiProcess ? ['--no-sandbox'] : []), 22 | '--enable-logging', 23 | '--ignore-certificate-errors', 24 | '--ignore-ssl-errors', 25 | '--ignore-blocklist', 26 | '--ignore-gpu-blocklist' 27 | ], 28 | locale: 'en-US', 29 | colorScheme: 'light', 30 | env: { 31 | ...process.env, 32 | NODE_ENV: 'production' 33 | } 34 | }) 35 | page = await appElectron.firstWindow() 36 | 37 | await page.waitForEvent('load') 38 | 39 | page.on('console', console.log) 40 | page.on('pageerror', console.log) 41 | 42 | const evaluateResult = await appElectron.evaluate( 43 | async ({ app, BrowserWindow }) => { 44 | const currentWindow = BrowserWindow.getFocusedWindow() 45 | 46 | // Fix window position for testing 47 | currentWindow.setPosition(50, 50) 48 | currentWindow.setSize(1080, 560) 49 | 50 | return { 51 | packaged: app.isPackaged, 52 | dataPath: app.getPath('userData') 53 | } 54 | } 55 | ) 56 | 57 | base.expect(evaluateResult.packaged, 'app is not packaged').toBe(false) 58 | } 59 | 60 | export const afterAll = async () => { 61 | await appElectron.close() 62 | } 63 | 64 | export const test = base.test.extend({ 65 | // eslint-disable-next-line no-empty-pattern 66 | page: async ({}, use) => { 67 | await use(page) 68 | }, 69 | // @ts-expect-error: `util` is not using types in playwright 70 | util: async ({ page }, use, testInfo) => { 71 | await use(new TestUtil(page, testInfo, __testScreenshotPath)) 72 | } 73 | }) 74 | 75 | export const expect = base.expect 76 | 77 | export default { 78 | test, 79 | expect, 80 | beforeAll, 81 | afterAll 82 | } 83 | -------------------------------------------------------------------------------- /src/main/index.ts: -------------------------------------------------------------------------------- 1 | import { app, WebContents, RenderProcessGoneDetails } from 'electron' 2 | import Constants from './utils/Constants' 3 | import { createErrorWindow, createMainWindow } from './MainRunner' 4 | import log from 'electron-log/main' 5 | import { join } from 'path' 6 | 7 | let mainWindow 8 | let errorWindow 9 | 10 | const initializeMainLogger = () => { 11 | log.initialize({ 12 | includeFutureSessions: false, 13 | preload: true 14 | }) 15 | 16 | const appLogFilePath = join(app.getPath('userData'), 'logs', 'applog.log') 17 | 18 | log.transports.file.resolvePathFn = () => 19 | join(app.getPath('userData'), 'logs', 'applog.log') 20 | log.transports.file.level = 'silly' 21 | log.transports.file.format = '[{y}{m}{d} {h}:{i}:{s}.{ms}|{level}]{text}' 22 | log.transports.console.format = '{h}:{i}:{s}.{ms} {text}' 23 | log.transports.console.level = 'silly' 24 | 25 | log.silly(`Start logging... (Path: ${appLogFilePath}) App is ready.`) 26 | } 27 | 28 | const installDevTron = async () => { 29 | if (!Constants.IS_DEV_ENV) { 30 | return 31 | } 32 | 33 | try { 34 | const { devtron } = await import('@electron/devtron') 35 | await devtron.install() 36 | } catch { 37 | // Do nothing 38 | } 39 | } 40 | 41 | app.on('ready', async () => { 42 | if (Constants.IS_DEV_ENV) { 43 | import('./index.dev') 44 | } 45 | 46 | // Disable special menus on macOS by uncommenting the following, if necessary 47 | /* 48 | if (Constants.IS_MAC) { 49 | systemPreferences.setUserDefault('NSDisabledDictationMenuItem', 'boolean', true) 50 | systemPreferences.setUserDefault('NSDisabledCharacterPaletteMenuItem', 'boolean', true) 51 | } 52 | */ 53 | initializeMainLogger() 54 | 55 | await installDevTron() 56 | 57 | mainWindow = await createMainWindow() 58 | }) 59 | 60 | app.on('activate', async () => { 61 | if (!mainWindow) { 62 | mainWindow = await createMainWindow() 63 | } 64 | }) 65 | 66 | app.on('window-all-closed', () => { 67 | mainWindow = null 68 | errorWindow = null 69 | 70 | if (!Constants.IS_MAC) { 71 | app.quit() 72 | } 73 | }) 74 | 75 | app.on( 76 | 'render-process-gone', 77 | ( 78 | event: Event, 79 | webContents: WebContents, 80 | details: RenderProcessGoneDetails 81 | ) => { 82 | errorWindow = createErrorWindow(errorWindow, mainWindow, details) 83 | } 84 | ) 85 | 86 | process.on('uncaughtException', () => { 87 | errorWindow = createErrorWindow(errorWindow, mainWindow) 88 | }) 89 | -------------------------------------------------------------------------------- /eslint.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, globalIgnores } from 'eslint/config' 2 | import pluginJs from '@eslint/js' 3 | import pluginTypeScriptESLint from 'typescript-eslint' 4 | import parserVue from 'vue-eslint-parser' 5 | import parserTypeScript from '@typescript-eslint/parser' 6 | import pluginVue from 'eslint-plugin-vue' 7 | import pluginNode from 'eslint-plugin-n' 8 | import pluginImport from 'eslint-plugin-import' 9 | import pluginPrettier from 'eslint-plugin-prettier/recommended' 10 | 11 | import globals from 'globals' 12 | 13 | export default defineConfig( 14 | pluginPrettier, 15 | pluginJs.configs.recommended, 16 | pluginTypeScriptESLint.configs.recommended, 17 | pluginImport.flatConfigs.electron, 18 | pluginNode.configs['flat/recommended-script'], 19 | ...pluginVue.configs['flat/strongly-recommended'], 20 | globalIgnores([ 21 | '**/node_modules', 22 | '**/dist', 23 | '**/release', 24 | '**/docs', 25 | '**/.idea', 26 | '**/.vscode', 27 | '**/buildAssets/builder', 28 | '**/tests/results', 29 | '**/package-lock.json' 30 | ]), 31 | { 32 | files: ['**/*.{js,mjs,cjs,ts,vue}'], 33 | languageOptions: { 34 | ecmaVersion: 'latest', 35 | sourceType: 'module', 36 | globals: { 37 | ...globals.browser, 38 | ...globals.node 39 | }, 40 | parser: parserVue, 41 | parserOptions: { 42 | parser: parserTypeScript, 43 | ecmaVersion: 2022, 44 | ecmaFeatures: { 45 | jsx: true 46 | }, 47 | requireConfigFile: false 48 | } 49 | }, 50 | rules: { 51 | // override/add rules settings here, such as: 52 | eqeqeq: 'error', 53 | 'no-unused-vars': 'off', 54 | 'no-case-declarations': 'off', 55 | 'no-trailing-spaces': 'error', 56 | 'no-unsafe-optional-chaining': 'off', 57 | 'no-control-regex': 'off', 58 | 'n/no-missing-import': 'off', 59 | 'n/no-unsupported-features/node-builtins': 'off', 60 | 'vue/v-on-event-hyphenation': 'off', 61 | 'vue/no-v-text-v-html-on-component': 'off', 62 | 'vue/attribute-hyphenation': 'off', 63 | 'vue/max-attributes-per-line': [ 64 | 'error', 65 | { 66 | singleline: { 67 | max: 1 68 | }, 69 | multiline: { 70 | max: 1 71 | } 72 | } 73 | ], 74 | '@typescript-eslint/no-unused-vars': [ 75 | 'error', 76 | { 77 | argsIgnorePattern: '^_', 78 | varsIgnorePattern: '^_', 79 | caughtErrorsIgnorePattern: '^_' 80 | } 81 | ], 82 | '@typescript-eslint/no-explicit-any': 'off' 83 | } 84 | } 85 | ) 86 | -------------------------------------------------------------------------------- /docs/src/ko/project-structures/project-structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | --- 4 | 5 | # 프로젝트 구조 6 | 7 | ``` 8 | / 9 | ├─ .github - GitHub 파일들 (Vutron 프로젝트 기여에만 사용) 10 | │ └─ ISSUE_TEMPLATE/ 11 | │ └─ resources/ - README.md 등에 사용되는 GitHub 리소스 12 | │ └─ workflows/ - GitHub 워크플로우 정의 13 | │ └─ dependabot.yml 14 | │ └─ FUNDING.yml 15 | ├─ .vscode - Visual Studio Code IDE에서 사용하는 일반적인 프로젝트 구성 파일 16 | ├─ buildAssets/ - Electron 빌드에 사용되는 패키지 리소스(아이콘, 로고 등) 파일 17 | │ └─ builder/ 18 | │ │ │ └─ config.ts - `electron-builder` 동적 구성 파일 19 | │ └─ icons/ 20 | ├─ dist/ - 패키지 빌드에 사용되는 출력 디렉토리 21 | ├─ docs/ - 프로젝트 문서(선택적으로 활성화) 22 | │ └─ .vitepress/ 23 | │ │ │ └─ config.mts - 문서 호스팅에 사용되는 VitePress 구성 파일 24 | │ └─ public/ - VitePress 문서 페이지의 루트 리소스 디렉토리 25 | ├─ node_modules/ 26 | ├─ src/ 27 | │ ├─ main/ - 메인(Electron) 프로세스 소스 코드 28 | │ │ ├─ utils/ - 메인 프로세스 유틸리티 29 | │ │ │ └─ Constants.ts - 메인 글로벌 정의 30 | │ │ │ └─ Menus.ts - 메인 글로벌 메뉴 정의 31 | │ │ └─ index.ts - 메인 프로세스 진입점 32 | │ │ └─ IPCs.ts - 메인 프로세스 IPC 핸들러 정의 33 | │ │ └─ MainRunner.ts - 메인 프로세스 메인 윈도우 프로세스 34 | │ ├─ preload/ - 프리로드 (Electron-Vue 커뮤니케이션 브릿지) 프로세스 35 | │ │ └─ index.ts 36 | │ ├─ public/ - Main + Renderer 정적 리소스 37 | │ │ └─ images/ 38 | │ ├─ renderer/ - 렌더러 (Vue) 프로세스 소스 코드 39 | │ │ ├─ components/ - Vue 컴포넌트 콜렉션 40 | │ │ │ └─ layout/ - 레이아웃 컴포넌트 41 | │ │ ├─ locales/ - Vue i18n 언어 리소스 파일 42 | │ │ ├─ plugins/ - Vue 플러그인 정의 43 | │ │ ├─ router/ - Vue 라우팅 정의 44 | │ │ ├─ screens/ - Vue 화면 컴포넌트 45 | │ │ │ └─ ErrorScreen.vue - 렌더링 프로세스 및 라우팅 오류 발생 시 표시되는 화면 46 | │ │ │ └─ MainScreen.vue 47 | │ │ │ └─ SecondScreen.vue - 샘플 화면 48 | │ │ ├─ store/ - Pinia 스토어 (글로벌 상태 관리) 정의 49 | │ │ ├─ utils/ - 렌더러 프로세스 유틸리티 50 | │ │ ├─ App.vue - Vue 앱 루트 컴포넌트 51 | │ │ ├─ index.html - Electron 렌더러 프로세스에 의해 로드된 루트 정적 인덱스 52 | │ └─ └─ main.ts - 렌더러 프로세스 엔트리 포인트 53 | ├─ tests/ - 애플리케이션 테스트 구성 54 | │ ├─ results/ - PlayWright 테스트 결과 파일 및 스크린샷 저장 위치 55 | │ ├─ specs/ - PlayWright 테스트 사양 파일 56 | │ ├─ fixtures.ts - 공통 실행 API 테스트 57 | │ └─ testUtil.ts - 테스트 유틸리티 58 | ├─ .editorconfig - IDE용 에디터 권장 구성 파일 59 | ├─ .eslintignore - ESLint에서 무시할 파일 목록 60 | ├─ .gitignore - Git에 업로드하지 않을 파일 목록 61 | ├─ .prettierignore - Prettier 파일 서식을 비활성화할 파일 목록 62 | ├─ .prettierrc - Prettier 규칙 설정 63 | ├─ CODE_OF_CONDUCT.md - GitHub에서만 사용되는 파일 64 | ├─ eslint.config.ts - ESLint 규칙 구성 65 | ├─ LICENSE - 프로젝트 라이선스 파일 66 | ├─ package.json - Node.js 패키지 구성 67 | ├─ package-lock.json 68 | ├─ playwright.config.ts - Playwright 테스트 규칙 구성 69 | ├─ pnpm-lock.yaml - PNPM 관련 파일 70 | ├─ pnpm-workspace.yaml - PNPM 관련 파일 71 | ├─ tsconfig.json - TypeScript 설정 72 | ├─ tsconfig.node.json - TypeScript 설정 73 | ├─ vite.config.mts - Vite 컴파일러 빌드 설정 74 | └─ README.md - GitHub에서만 사용되는 파일 75 | ``` 76 | -------------------------------------------------------------------------------- /docs/src/zhHans/installation-and-build/build-configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 2 3 | --- 4 | 5 | # 构建配置 6 | 7 | 模块安装完成后,只需执行以下命令即可构建平台软件包。 8 | 9 | ```shell 10 | # For Windows (.exe, .appx) 11 | $ npm run build:win 12 | 13 | # For macOS (.dmg) 14 | $ npm run build:mac 15 | 16 | # For Linux (.rpm, .deb, .snap) 17 | $ npm run build:linux 18 | 19 | # All platform (.exe, .appx, .dmg, .rpm, .deb, .snap) - see below description 20 | $ npm run build:all 21 | ``` 22 | 23 | 已构建的软件包可在 `release/{version}` 位置找到。 24 | 25 | 如需了解更多信息,请参阅以下文章: https://webpack.electron.build/dependency-management#installing-native-node-modules 26 | 27 | ## 多平台构建需要做些什么? 28 | 29 | 要为每个操作系统创建软件包,必须在相同的操作系统上构建。例如,macOS 的软件包必须在 macOS 机器上构建。 30 | 31 | 不过,你可以在一个操作系统上同时为 Windows、macOS 和 Linux 构建软件包。不过,这可能需要一些准备工作。 32 | 33 | 如果想在一个平台上同时构建多个平台,建议使用**macOS**。因为只需几个非常简单的设置就能对其进行配置。 34 | 35 | 您可以使用以下命令同时执行多平台构建。或者,你也可以通过上面的单独构建命令,只针对你想要的操作系统进行构建。 36 | 37 | ```shell 38 | $ npm run build:all 39 | ``` 40 | 41 | Linux 构建可能需要 "Multipass" 配置。通过以下链接了解有关 `Multipass` 的更多信息: https://multipass.run 42 | 43 | 要了解有关多平台构建的更多信息,请参阅以下文章: https://electron.build/multi-platform-build 44 | 45 | ## 通过排除开发文件减少软件包大小 46 | 47 | 您可以通过在 `buildAssets/builder/config.ts` 的 files 属性中添加文件模式,在构建时排除不需要的文件。这将节省捆绑包的容量。 48 | 49 | 下面是一个不必要的 `node_modules` 文件模式,可以进一步节省捆绑包。根据项目情况,使用下面的规则可能会导致问题,因此请在使用前进行审查。 50 | 51 | ```json 52 | [ 53 | "!**/.*", 54 | "!**/node_modules/**/{CONTRIBUTORS,CNAME,AUTHOR,TODO,CONTRIBUTING,COPYING,INSTALL,NEWS,PORTING,Makefile,htdocs,CHANGELOG,ChangeLog,changelog,README,Readme,readme,test,sample,example,demo,composer.json,tsconfig.json,jsdoc.json,tslint.json,typings.json,gulpfile,bower.json,package-lock,Gruntfile,CMakeLists,karma.conf,yarn.lock}*", 55 | "!**/node_modules/**/{man,benchmark,node_modules,spec,cmake,browser,vagrant,doxy*,bin,obj,obj.target,example,examples,test,tests,doc,docs,msvc,Xcode,CVS,RCS,SCCS}{,/**/*}", 56 | "!**/node_modules/**/*.{conf,png,pc,coffee,txt,spec.js,ts,js.flow,html,def,jst,xml,ico,in,ac,sln,dsp,dsw,cmd,vcproj,vcxproj,vcxproj.filters,pdb,exp,obj,lib,map,md,sh,gypi,gyp,h,cpp,yml,log,tlog,Makefile,mk,c,cc,rc,xcodeproj,xcconfig,d.ts,yaml,hpp}", 57 | "!**/node_modules/**/node-v*-x64{,/**/*}", 58 | "!**/node_modules/bluebird/js/browser{,/**/*}", 59 | "!**/node_modules/bluebird/js/browser{,/**/*}", 60 | "!**/node_modules/source-map/dist{,/**/*}", 61 | "!**/node_modules/lodash/fp{,/**/*}", 62 | "!**/node_modules/async/!(dist|package.json)", 63 | "!**/node_modules/async/internal{,/**/*}", 64 | "!**/node_modules/ajv/dist{,/**/*}", 65 | "!**/node_modules/ajv/scripts{,/**/*}", 66 | "!**/node_modules/node-pre-gyp/!(lib|package.json)", 67 | "!**/node_modules/node-pre-gyp/lib/!(util|pre-binding.js|node-pre-gyp.js)", 68 | "!**/node_modules/node-pre-gyp/lib/util/!(versioning.js|abi_crosswalk.json)", 69 | "!**/node_modules/source-map-support/browser-source-map-support.js", 70 | "!**/node_modules/json-schema/!(package.json|lib)" 71 | ] 72 | ``` 73 | 74 | ## 使用本地 Node 模块的项目的构建设置 75 | 76 | 对于使用 **Native Node Module**的项目,请将以下脚本添加到您的 `package.json`: 安装依赖项时,`electron-builder` 会处理任何需要重建的模块。 77 | 78 | ```json 79 | { 80 | "scripts": { 81 | "postinstall": "electron-builder install-app-deps" 82 | } 83 | } 84 | ``` 85 | -------------------------------------------------------------------------------- /vite.config.mts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'url' 2 | import { defineConfig, loadEnv } from 'vite' 3 | import ElectronPlugin, { ElectronOptions } from 'vite-plugin-electron' 4 | import RendererPlugin from 'vite-plugin-electron-renderer' 5 | import EslintPlugin from 'vite-plugin-eslint' 6 | import VuetifyPlugin from 'vite-plugin-vuetify' 7 | import VueJsx from '@vitejs/plugin-vue-jsx' 8 | import Vue from '@vitejs/plugin-vue' 9 | import { rmSync } from 'fs' 10 | import { resolve, dirname } from 'path' 11 | import { builtinModules } from 'module' 12 | 13 | const isDevEnv = process.env.NODE_ENV === 'development' 14 | 15 | export default defineConfig(({ mode }) => { 16 | process.env = { 17 | ...(isDevEnv 18 | ? { 19 | ELECTRON_ENABLE_LOGGING: 'true' 20 | } 21 | : {}), 22 | ...process.env, 23 | ...loadEnv(mode, process.cwd()) 24 | } 25 | 26 | rmSync('dist', { recursive: true, force: true }) 27 | 28 | const electronPluginConfigs: ElectronOptions[] = [ 29 | { 30 | entry: 'src/main/index.ts', 31 | onstart({ startup }) { 32 | const debugArgs = [ 33 | '.', 34 | '--inspect=9228', 35 | '--remote-debugging-port=9229' 36 | ] 37 | startup(debugArgs) 38 | }, 39 | vite: { 40 | root: resolve('.'), 41 | base: './', 42 | publicDir: resolve('./src/public'), 43 | build: { 44 | sourcemap: true, 45 | assetsDir: '.', 46 | outDir: 'dist/main', 47 | rollupOptions: { 48 | external: ['electron', ...builtinModules] 49 | } 50 | } 51 | } 52 | }, 53 | { 54 | entry: 'src/preload/index.ts', 55 | onstart({ reload }) { 56 | reload() 57 | }, 58 | vite: { 59 | root: resolve('.'), 60 | build: { 61 | outDir: 'dist/preload' 62 | } 63 | } 64 | } 65 | ] 66 | 67 | if (isDevEnv) { 68 | electronPluginConfigs.push({ 69 | entry: 'src/main/index.dev.ts', 70 | vite: { 71 | root: resolve('.'), 72 | build: { 73 | outDir: 'dist/main' 74 | } 75 | } 76 | }) 77 | } 78 | 79 | return { 80 | define: { 81 | __VUE_I18N_FULL_INSTALL__: true, 82 | __VUE_I18N_LEGACY_API__: false, 83 | __INTLIFY_PROD_DEVTOOLS__: false 84 | }, 85 | resolve: { 86 | extensions: ['.mjs', '.js', '.ts', '.vue', '.json', '.scss'], 87 | alias: { 88 | '@': resolve(dirname(fileURLToPath(import.meta.url)), 'src') 89 | } 90 | }, 91 | base: './', 92 | root: resolve('./src/renderer'), 93 | publicDir: resolve('./src/public'), 94 | clearScreen: false, 95 | build: { 96 | sourcemap: isDevEnv, 97 | minify: !isDevEnv, 98 | outDir: resolve('./dist') 99 | }, 100 | plugins: [ 101 | Vue(), 102 | VueJsx(), 103 | // Docs: https://github.com/vuetifyjs/vuetify-loader 104 | VuetifyPlugin({ 105 | autoImport: true 106 | }), 107 | // Docs: https://github.com/gxmari007/vite-plugin-eslint 108 | EslintPlugin(), 109 | // Docs: https://github.com/electron-vite/vite-plugin-electron 110 | ElectronPlugin(electronPluginConfigs), 111 | RendererPlugin() 112 | ] 113 | } 114 | }) 115 | -------------------------------------------------------------------------------- /src/main/tray.ts: -------------------------------------------------------------------------------- 1 | import { app, screen, Menu, Tray, BrowserWindow } from 'electron' 2 | import Constants from './utils/Constants' 3 | import { join } from 'path' 4 | import { debounce } from 'qsu' 5 | let tray 6 | let trayOptions 7 | 8 | export function createTray(window: BrowserWindow, options) { 9 | trayOptions = options || Constants.DEFAULT_TRAY_OPTIONS 10 | // menu or trayWindow, you need to choose 11 | if (trayOptions.trayWindow) { 12 | trayOptions.menu = false 13 | } 14 | 15 | tray = new Tray(join(Constants.PUBLIC_PATH, 'images/vutron-tray-icon.png')) 16 | tray.setToolTip(trayOptions.tooltip) 17 | if (trayOptions.menu) { 18 | const contextMenu = Menu.buildFromTemplate([ 19 | { 20 | label: 'Show App', 21 | click: () => { 22 | showWindow(window) 23 | } 24 | }, 25 | { 26 | label: 'Hide App', 27 | click: () => { 28 | hideWindow(window) 29 | } 30 | }, 31 | { 32 | label: 'Exit', 33 | click: () => { 34 | app.quit() 35 | } 36 | } 37 | ]) 38 | // tray icon only with classic window 39 | tray.setContextMenu(contextMenu) 40 | } else { 41 | // handle click on tray icon 42 | tray.on('right-click', function () { 43 | debounce(() => toggleWindow(window), 200) 44 | }) 45 | tray.on('click', function () { 46 | debounce(() => toggleWindow(window), 200) 47 | }) 48 | // no menu for tray window 49 | window.setMenu(null) 50 | tray.setContextMenu(null) 51 | } 52 | // align at startup 53 | alignWindow(window) 54 | return tray 55 | } 56 | 57 | export function hideWindow(window: BrowserWindow) { 58 | window.hide() 59 | // if (!trayOptions.trayWindow) return; 60 | // hide window when click elsewhere on screen 61 | window.on('blur', () => { 62 | // dont close if devtools 63 | if (!window.webContents.isDevToolsOpened()) { 64 | window.hide() 65 | } 66 | }) 67 | } 68 | 69 | export function toggleWindow(window: BrowserWindow) { 70 | if (window.isVisible()) { 71 | hideWindow(window) 72 | } else { 73 | showWindow(window) 74 | } 75 | } 76 | 77 | export function showWindow(window: BrowserWindow) { 78 | window.show() 79 | alignWindow(window) 80 | } 81 | 82 | export function alignWindow(window: BrowserWindow) { 83 | if (!trayOptions.trayWindow) return 84 | 85 | const b = window.getBounds() 86 | const position = calculateWindowPosition(b) 87 | window.setBounds({ 88 | width: b.width, 89 | height: b.height, 90 | x: position.x, 91 | y: position.y 92 | }) 93 | } 94 | 95 | function calculateWindowPosition(b) { 96 | const margin = trayOptions.margin 97 | const screenBounds = screen.getPrimaryDisplay().size 98 | const trayBounds = tray.getBounds() 99 | const bottom = trayBounds.y > screenBounds.height / 2 100 | const x = Math.floor( 101 | trayBounds.x - b.width / 2 - margin.x + trayBounds.width / 2 102 | ) 103 | const y = bottom 104 | ? Math.floor(trayBounds.y - b.height - margin.y + trayBounds.height / 2) 105 | : Math.floor(trayBounds.y + margin.y + trayBounds.height / 2) 106 | // constraint into screen 107 | return { 108 | x: Math.max(0, Math.min(screenBounds.width - b.width, x)), 109 | y: Math.max(0, Math.min(screenBounds.height - b.height, y)) 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vutron", 3 | "appId": "com.vutron.vutron", 4 | "version": "1.0.0", 5 | "description": "Quick Start Templates for Vite + Vue 3 + Electron", 6 | "homepage": "https://vutron.cdget.com", 7 | "author": "CDGet ", 8 | "license": "MIT", 9 | "main": "dist/main/index.js", 10 | "private": true, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/jooy2/vutron.git" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/jooy2/vutron/issues" 17 | }, 18 | "debug": { 19 | "env": { 20 | "VITE_DEV_SERVER_URL": "http://localhost:5173" 21 | } 22 | }, 23 | "scripts": { 24 | "dev": "vite", 25 | "dev:debug": "vite -d", 26 | "dev:debug:force": "vite -d --force", 27 | "build": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js", 28 | "build:pre": "npm run format:fix && vue-tsc --noEmit && vite build", 29 | "build:all": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js -wml", 30 | "build:dir": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js --dir", 31 | "build:mac": "npm run build:pre && CSC_IDENTITY_AUTO_DISCOVERY=false electron-builder --config=buildAssets/builder/config.js --mac", 32 | "build:linux": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js --linux", 33 | "build:win": "npm run build:pre && electron-builder --config=buildAssets/builder/config.js --windows", 34 | "lint": "eslint . --ext .js,.ts,.vue .", 35 | "lint:fix": "eslint . --ext .js,.ts,.vue --fix .", 36 | "format": "prettier .", 37 | "format:fix": "prettier . --write", 38 | "test": "npm run build:pre && playwright test", 39 | "test:linux": "npm run build:pre && xvfb-run --auto-servernum --server-args='-screen 0, 1280x960x24' -- playwright test" 40 | }, 41 | "engines": { 42 | "node": ">=20.0.0" 43 | }, 44 | "dependencies": { 45 | "electron-log": "^5.4.3", 46 | "pinia": "^3.0.4", 47 | "qsu": "^1.10.4", 48 | "vue": "^3.5.26", 49 | "vue-i18n": "^11.2.7", 50 | "vue-router": "^4.6.4" 51 | }, 52 | "devDependencies": { 53 | "@electron/devtron": "^2.1.1", 54 | "@eslint/js": "^9.39.2", 55 | "@mdi/js": "^7.4.47", 56 | "@playwright/test": "^1.57.0", 57 | "@typescript-eslint/parser": "^8.50.0", 58 | "@vitejs/plugin-vue": "^6.0.3", 59 | "@vitejs/plugin-vue-jsx": "^5.1.2", 60 | "dotenv": "^17.2.3", 61 | "electron": "^39.2.7", 62 | "electron-builder": "^26.0.14", 63 | "electron-extension-installer": "^2.0.1", 64 | "eslint": "^9.39.2", 65 | "eslint-config-prettier": "^10.1.8", 66 | "eslint-plugin-import": "^2.32.0", 67 | "eslint-plugin-n": "^17.23.1", 68 | "eslint-plugin-prettier": "^5.5.4", 69 | "eslint-plugin-vue": "^10.6.2", 70 | "globals": "^16.5.0", 71 | "jiti": "^2.6.1", 72 | "playwright": "^1.57.0", 73 | "prettier": "^3.7.4", 74 | "typescript": "^5.9.3", 75 | "typescript-eslint": "^8.50.0", 76 | "vite": "^7.3.0", 77 | "vite-plugin-electron": "^0.29.0", 78 | "vite-plugin-electron-renderer": "^0.14.6", 79 | "vite-plugin-eslint": "^1.8.1", 80 | "vite-plugin-vuetify": "^2.1.2", 81 | "vue-eslint-parser": "^10.2.0", 82 | "vue-tsc": "^3.2.0", 83 | "vuetify": "^3.11.4" 84 | }, 85 | "overrides": { 86 | "vite-plugin-electron": { 87 | "electron": "$electron" 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /docs/src/ko/installation-and-build/build-configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 2 3 | --- 4 | 5 | # 빌드 구성 6 | 7 | 모듈 설치가 완료되면 아래 명령어를 사용하여 플랫폼 패키지를 간단하게 빌드할 수 있습니다. 8 | 9 | ```shell 10 | # For Windows (.exe, .appx) 11 | $ npm run build:win 12 | 13 | # For macOS (.dmg) 14 | $ npm run build:mac 15 | 16 | # For Linux (.rpm, .deb, .snap) 17 | $ npm run build:linux 18 | 19 | # All platform (.exe, .appx, .dmg, .rpm, .deb, .snap) - see below description 20 | $ npm run build:all 21 | ``` 22 | 23 | 빌드된 패키지는 `release/{version}` 위치에서 찾을 수 있습니다. 24 | 25 | 자세한 내용은 다음 문서를 참조하세요: https://webpack.electron.build/dependency-management#installing-native-node-modules 26 | 27 | ## 멀티플랫폼 빌드를 하려면 어떻게 해야 하나요? 28 | 29 | 각 OS에 대한 패키지를 만들려면 동일한 OS에서 빌드해야 합니다. 예를 들어 macOS용 패키지는 macOS 컴퓨터에서 빌드해야 합니다. 30 | 31 | 하지만 하나의 OS에서 Windows, macOS, Linux용 패키지를 한 번에 빌드할 수 있습니다. 하지만 이를 위해서는 약간의 준비가 필요할 수 있습니다. 32 | 33 | 하나의 플랫폼에서 여러 플랫폼을 동시에 구축하려는 경우 **macOS**를 권장합니다. 몇 가지 간단한 설정만으로 구성할 수 있기 때문입니다. 34 | 35 | 다음 명령어를 사용하여 한 번에 여러 플랫폼 빌드를 수행할 수 있습니다. 또는 위의 개별 빌드 명령어를 통해 원하는 OS에 대해서만 빌드를 수행할 수도 있습니다. 36 | 37 | ```shell 38 | $ npm run build:all 39 | ``` 40 | 41 | Linux 빌드에는 `multipass` 구성이 필요할 수 있습니다. 다음 링크를 통해 `multipass`에 대해 자세히 알아보세요: https://multipass.run 42 | 43 | 멀티플랫폼 빌드에 대해 자세히 알아보려면 다음 문서를 참조하세요: https://electron.build/multi-platform-build 44 | 45 | ## 개발 파일을 제외하여 번들 크기 줄이기 46 | 47 | 빌드 시점에 필요하지 않은 파일은 `buildAssets/builder/config.ts`의 파일 속성에 파일 패턴을 추가하여 제외할 수 있습니다. 이렇게 하면 번들 용량을 절약할 수 있습니다. 48 | 49 | 아래는 불필요한 `node_modules` 파일 패턴으로 번들을 추가로 절약할 수 있는 예시입니다. 프로젝트에 따라 아래 규칙을 사용하면 문제가 발생할 수 있으므로 사용 전에 검토하시기 바랍니다. 50 | 51 | ```json 52 | [ 53 | "!**/.*", 54 | "!**/node_modules/**/{CONTRIBUTORS,CNAME,AUTHOR,TODO,CONTRIBUTING,COPYING,INSTALL,NEWS,PORTING,Makefile,htdocs,CHANGELOG,ChangeLog,changelog,README,Readme,readme,test,sample,example,demo,composer.json,tsconfig.json,jsdoc.json,tslint.json,typings.json,gulpfile,bower.json,package-lock,Gruntfile,CMakeLists,karma.conf,yarn.lock}*", 55 | "!**/node_modules/**/{man,benchmark,node_modules,spec,cmake,browser,vagrant,doxy*,bin,obj,obj.target,example,examples,test,tests,doc,docs,msvc,Xcode,CVS,RCS,SCCS}{,/**/*}", 56 | "!**/node_modules/**/*.{conf,png,pc,coffee,txt,spec.js,ts,js.flow,html,def,jst,xml,ico,in,ac,sln,dsp,dsw,cmd,vcproj,vcxproj,vcxproj.filters,pdb,exp,obj,lib,map,md,sh,gypi,gyp,h,cpp,yml,log,tlog,Makefile,mk,c,cc,rc,xcodeproj,xcconfig,d.ts,yaml,hpp}", 57 | "!**/node_modules/**/node-v*-x64{,/**/*}", 58 | "!**/node_modules/bluebird/js/browser{,/**/*}", 59 | "!**/node_modules/bluebird/js/browser{,/**/*}", 60 | "!**/node_modules/source-map/dist{,/**/*}", 61 | "!**/node_modules/lodash/fp{,/**/*}", 62 | "!**/node_modules/async/!(dist|package.json)", 63 | "!**/node_modules/async/internal{,/**/*}", 64 | "!**/node_modules/ajv/dist{,/**/*}", 65 | "!**/node_modules/ajv/scripts{,/**/*}", 66 | "!**/node_modules/node-pre-gyp/!(lib|package.json)", 67 | "!**/node_modules/node-pre-gyp/lib/!(util|pre-binding.js|node-pre-gyp.js)", 68 | "!**/node_modules/node-pre-gyp/lib/util/!(versioning.js|abi_crosswalk.json)", 69 | "!**/node_modules/source-map-support/browser-source-map-support.js", 70 | "!**/node_modules/json-schema/!(package.json|lib)" 71 | ] 72 | ``` 73 | 74 | ## 네이티브 노드 모듈을 사용하는 프로젝트의 빌드 설정 75 | 76 | **네이티브 노드 모듈**을 사용하는 프로젝트의 경우, `package.json`에 다음 스크립트를 추가하세요: 종속성을 설치할 때 `electron-builder`가 리빌드가 필요한 모듈을 처리합니다. 77 | 78 | ```json 79 | { 80 | "scripts": { 81 | "postinstall": "electron-builder install-app-deps" 82 | } 83 | } 84 | ``` 85 | -------------------------------------------------------------------------------- /docs/src/.vitepress/config.mts: -------------------------------------------------------------------------------- 1 | import { withSidebar } from 'vitepress-sidebar' 2 | import { name, repository, homepage } from '../../../package.json' 3 | import { defineConfig, UserConfig } from 'vitepress' 4 | import { withI18n } from 'vitepress-i18n' 5 | import type { VitePressSidebarOptions } from 'vitepress-sidebar/types' 6 | import type { VitePressI18nOptions } from 'vitepress-i18n/types' 7 | 8 | const capitalizeFirst = (str: string): string => 9 | str.charAt(0).toUpperCase() + str.slice(1) 10 | const supportLocales = ['en', 'ko', 'zhHans'] 11 | const defaultLocale: string = supportLocales[0] 12 | 13 | const vitePressI18nConfigs: VitePressI18nOptions = { 14 | locales: supportLocales, 15 | rootLocale: defaultLocale, 16 | searchProvider: 'local', 17 | description: { 18 | en: 'Vutron is a preconfigured template for developing Electron cross-platform desktop apps. It uses Vue 3 and allows you to build a fast development environment with little effort.', 19 | ko: 'Vutron은 Electron 크로스 플랫폼 데스크톱 앱 개발을 위해 미리 구성된 템플릿입니다. Vue 3을 사용하며 적은 노력으로 빠른 개발 환경을 구축할 수 있습니다.', 20 | zhHans: 21 | 'Vutron 是用于开发 Electron 跨平台桌面应用程序的预配置模板。它使用 Vue 3,可让您轻松构建快速开发环境。' 22 | }, 23 | themeConfig: { 24 | en: { 25 | nav: [ 26 | { 27 | text: 'Getting Started', 28 | link: '/installation-and-build/getting-started' 29 | } 30 | ] 31 | }, 32 | ko: { 33 | nav: [ 34 | { 35 | text: '시작하기', 36 | link: '/ko/installation-and-build/getting-started' 37 | } 38 | ] 39 | }, 40 | zhHans: { 41 | nav: [ 42 | { 43 | text: '入门', 44 | link: '/zhHans/installation-and-build/getting-started' 45 | } 46 | ] 47 | } 48 | } 49 | } 50 | 51 | const vitePressSidebarConfigs: VitePressSidebarOptions = [ 52 | ...supportLocales.map((lang) => { 53 | return { 54 | collapsed: false, 55 | useTitleFromFileHeading: true, 56 | useTitleFromFrontmatter: true, 57 | useFolderTitleFromIndexFile: true, 58 | sortMenusByFrontmatterOrder: true, 59 | hyphenToSpace: true, 60 | capitalizeEachWords: true, 61 | manualSortFileNameByPriority: [ 62 | 'introduction.md', 63 | 'installation-and-build', 64 | 'project-structures', 65 | 'electron-how-to' 66 | ], 67 | documentRootPath: `/src/${lang}`, 68 | resolvePath: defaultLocale === lang ? '/' : `/${lang}/`, 69 | ...(defaultLocale === lang ? {} : { basePath: `/${lang}/` }) 70 | } 71 | }) 72 | ] 73 | 74 | const vitePressConfigs: UserConfig = { 75 | title: capitalizeFirst(name), 76 | lastUpdated: true, 77 | outDir: '../dist', 78 | head: [ 79 | ['link', { rel: 'icon', href: '/logo.png' }], 80 | ['link', { rel: 'shortcut icon', href: '/favicon.ico' }] 81 | ], 82 | cleanUrls: true, 83 | metaChunk: true, 84 | rewrites: { 85 | 'en/:rest*': ':rest*' 86 | }, 87 | sitemap: { 88 | hostname: homepage 89 | }, 90 | themeConfig: { 91 | logo: { src: '/icon.png', width: 24, height: 24 }, 92 | editLink: { 93 | pattern: 'https://github.com/jooy2/vutron/edit/main/docs/src/:path' 94 | }, 95 | socialLinks: [{ icon: 'github', link: repository.url.replace('.git', '') }] 96 | } 97 | } 98 | 99 | export default defineConfig( 100 | withSidebar( 101 | withI18n(vitePressConfigs, vitePressI18nConfigs), 102 | vitePressSidebarConfigs 103 | ) 104 | ) 105 | -------------------------------------------------------------------------------- /docs/src/en/project-structures/project-structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | --- 4 | 5 | # Project Structure 6 | 7 | ``` 8 | / 9 | ├─ .github - GitHub files (only used for Vutron GitHub project contributions) 10 | │ └─ ISSUE_TEMPLATE/ 11 | │ └─ resources/ - GitHub resources used for README.md, etc. 12 | │ └─ workflows/ - GitHub workflows definition 13 | │ └─ dependabot.yml 14 | │ └─ FUNDING.yml 15 | ├─ .vscode - Common project configuration files used by Visual Studio Code IDE 16 | ├─ buildAssets/ - Package resource (icon, logo, etc.) file used for Electron build 17 | │ └─ builder/ 18 | │ │ │ └─ config.ts - `electron-builder` dynamic configuration file 19 | │ └─ icons/ 20 | ├─ dist/ - Output directory used to build the package 21 | ├─ docs/ - Project documents (optionally enabled) 22 | │ └─ .vitepress/ 23 | │ │ │ └─ config.mts - VitePress configuration file used for document hosting 24 | │ └─ public/ - Root resource directory for VitePress documentation pages 25 | ├─ node_modules/ 26 | ├─ src/ 27 | │ ├─ main/ - Main (Electron) process source code 28 | │ │ ├─ utils/ - Main process utilities 29 | │ │ │ └─ Constants.ts - Main global definition 30 | │ │ │ └─ Menus.ts - Main global menu definition 31 | │ │ └─ index.ts - Main process entry point 32 | │ │ └─ IPCs.ts - Main process ipc handlers definition 33 | │ │ └─ MainRunner.ts - Main process main window processing 34 | │ ├─ preload/ - Preload (Electron-Vue communication bridge) process source code 35 | │ │ └─ index.ts 36 | │ ├─ public/ - Main + Renderer static resources 37 | │ │ └─ images/ 38 | │ ├─ renderer/ - Renderer (Vue) process source code 39 | │ │ ├─ components/ - Vue components collection 40 | │ │ │ └─ layout/ - Layout components 41 | │ │ ├─ locales/ - Vue i18n language resource file 42 | │ │ ├─ plugins/ - Vue plugin definition 43 | │ │ ├─ router/ - Vue routing definition 44 | │ │ ├─ screens/ - Vue screen component 45 | │ │ │ └─ ErrorScreen.vue - Screen displayed when renderer process and routing errors occur 46 | │ │ │ └─ MainScreen.vue 47 | │ │ │ └─ SecondScreen.vue - Sample screen 48 | │ │ ├─ store/ - Pinia store (Global state management) definition 49 | │ │ ├─ utils/ - Renderer process utilities 50 | │ │ ├─ App.vue - Vue app's root component 51 | │ │ ├─ index.html - Root static index loaded by Electron renderer process 52 | │ └─ └─ main.ts - Renderer process entry point 53 | ├─ tests/ - Application test configuration 54 | │ ├─ results/ - Where to save PlayWright test result files and screenshots 55 | │ ├─ specs/ - PlayWright test spec file 56 | │ ├─ fixtures.ts - Test common execution API 57 | │ └─ testUtil.ts - Test utilities 58 | ├─ .editorconfig - Editor recommended configuration file for IDE 59 | ├─ .eslintignore - List of files to be ignored by ESLint 60 | ├─ .gitignore - List of files to not upload to Git 61 | ├─ .prettierignore - List of files to disable Prettier file formatting 62 | ├─ .prettierrc - Prettier rule configurations 63 | ├─ CODE_OF_CONDUCT.md - Files used only on GitHub 64 | ├─ eslint.config.ts - ESLint rule configurations 65 | ├─ LICENSE - Project license file 66 | ├─ package.json - Node.js package configurations 67 | ├─ package-lock.json 68 | ├─ playwright.config.ts - Playwright test rules configurations 69 | ├─ pnpm-lock.yaml - PNPM Related Files 70 | ├─ pnpm-workspace.yaml - PNPM Related Files 71 | ├─ tsconfig.json - TypeScript configurations 72 | ├─ tsconfig.node.json - TypeScript configurations 73 | ├─ vite.config.mts - Vite compiler build configurations 74 | └─ README.md - Files used only on GitHub 75 | ``` 76 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Project 2 | 3 | Thank you for contributing to the project. Your contributions will help us take the project to the next level. 4 | 5 | This project adheres to the Contributor Covenant code of conduct. Your contribution implies that you have read and agree to this policy. Any behavior that undermines the quality of the project community, including this policy, will be warned or restricted by the maintainers. 6 | 7 | ## Issues 8 | 9 | Issues can be created on the following page: https://github.com/jooy2/vutron/issues 10 | 11 | Alternatively, you can email the package maintainer. However, we prefer to track progress via GitHub Issues. 12 | 13 | When creating an issue, keep the following in mind: 14 | 15 | - Please specify the correct category selection based on the format of the issue (e.g., bug report, feature request). 16 | - Check to see if there are duplicate issues. 17 | - Describe in detail what is happening and what needs to be fixed. You may need additional materials such as images or video. 18 | - Use appropriate keyword titles to make it easy for others to search and understand. 19 | - Please use English in all content. 20 | - You may need to describe the environment in which the issue occurs. 21 | 22 | ## How to contribute (Pull Requests) 23 | 24 | ### Write the code you want to change 25 | 26 | Here's the process for contributing to the project: 27 | 28 | 1. Clone the project (or rebase to the latest commit in the main branch) 29 | 2. Install the package (if the package manager exists) 30 | 3. Setting up lint or code formatter in the IDE (if your project includes a linter) and installing the relevant plugins. Some projects may use specific commands to check rules and perform formatting after module installation and before committing. 31 | 4. Write the code that needs to be fixed 32 | 5. Update the documentation (if it exists) or create a new one. If your project supports multilingual documentation, update the documentation for all languages. You can fill in the content in your own language and not translate it. 33 | 6. Add or modify tests as needed (if test code exists). You should also verify that existing tests pass. 34 | 35 | ### Write a commit message 36 | 37 | While we don't have strict restrictions on commit messages, we recommend that you follow the recommendations below whenever possible: 38 | 39 | - Write in English. 40 | - Use the ` symbol to name functions, variables, or folders and files. 41 | - Use a format like `xxx: message (fixes #1)`. The content in parentheses is optional. 42 | - The message includes a summary of what was modified. 43 | - It's a good idea to separate multiple modifications into their own commit messages. 44 | 45 | It is recommended that you include a tag at the beginning of the commit message. Between the tag and the message, use `: ` between the tag and the message. 46 | 47 | tags conform to the ["Udacity Git Commit Message Style Guide"](https://udacity.github.io/git-styleguide). However, you are welcome to use tags not listed here for additional situations. 48 | 49 | - `feat`: A new feature 50 | - `fix`: A bug fix 51 | - `docs`: Changes to documentation 52 | - `style`: Formatting, missing semicolons, etc.; no code change 53 | - `refactor`: Refactoring production code 54 | - `test`: Adding tests, refactoring test; no production code change 55 | - `chore`: Updating build tasks, package manager configs, etc.; no production code change 56 | 57 | Informal tags: 58 | 59 | - `package`: Modifications to package settings, modules, or GitHub projects 60 | - `typo`: Fix typos 61 | 62 | ### Create a pull request 63 | 64 | When creating a pull request, keep the following in mind: 65 | 66 | - Include a specific description of what the modification is, why it needs to be made, and how it works. 67 | - Check to see if there are duplicate pull requests. 68 | - Please use English in all content. 69 | 70 | Typically, a project maintainer will review and test your code before merging it into the project. This process can take some time, and they may ask you for further edits or clarifications in the comments. 71 | -------------------------------------------------------------------------------- /docs/src/en/installation-and-build/build-configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 2 3 | --- 4 | 5 | # Build Configurations 6 | 7 | Once the module installation is complete, you can simply build the platform package with the command below. 8 | 9 | ```shell 10 | # For Windows (.exe, .appx) 11 | $ npm run build:win 12 | 13 | # For macOS (.dmg) 14 | $ npm run build:mac 15 | 16 | # For Linux (.rpm, .deb, .snap) 17 | $ npm run build:linux 18 | 19 | # All platform (.exe, .appx, .dmg, .rpm, .deb, .snap) - see below description 20 | $ npm run build:all 21 | ``` 22 | 23 | The built packages can be found in `release/{version}` location. 24 | 25 | For more information, please refer to the following article: https://webpack.electron.build/dependency-management#installing-native-node-modules 26 | 27 | ## What do I need to do for a multi-platform build? 28 | 29 | To create a package for each OS, you must build it on the same OS. For example, a package for macOS must be built on a macOS machine. 30 | 31 | However, you can build packages for Windows, macOS, and Linux all at once on one OS. However, this might require some preparation. 32 | 33 | **macOS** is recommended if you want to build multiple platforms simultaneously on one platform. Because it can be configured with just a few very simple settings. 34 | 35 | You can perform multi-platform builds at once with the following command. Alternatively, you can just do it for the OS you want via the individual build commands above. 36 | 37 | ```shell 38 | $ npm run build:all 39 | ``` 40 | 41 | `Multipass` configuration may be required for Linux builds. Learn more about `Multipass` through the following link: https://multipass.run 42 | 43 | To learn more about multiplatform builds, see the following articles: https://electron.build/multi-platform-build 44 | 45 | ## Reduce bundle size by excluding development files 46 | 47 | You can exclude files you don't need at build time by adding a file pattern to the files property of `buildAssets/builder/config.ts`. This will save bundle capacity. 48 | 49 | Below is an unnecessary `node_modules` file pattern that can further save bundles. Depending on the project, using the rules below may cause problems, so please review it before using. 50 | 51 | ```json 52 | [ 53 | "!**/.*", 54 | "!**/node_modules/**/{CONTRIBUTORS,CNAME,AUTHOR,TODO,CONTRIBUTING,COPYING,INSTALL,NEWS,PORTING,Makefile,htdocs,CHANGELOG,ChangeLog,changelog,README,Readme,readme,test,sample,example,demo,composer.json,tsconfig.json,jsdoc.json,tslint.json,typings.json,gulpfile,bower.json,package-lock,Gruntfile,CMakeLists,karma.conf,yarn.lock}*", 55 | "!**/node_modules/**/{man,benchmark,node_modules,spec,cmake,browser,vagrant,doxy*,bin,obj,obj.target,example,examples,test,tests,doc,docs,msvc,Xcode,CVS,RCS,SCCS}{,/**/*}", 56 | "!**/node_modules/**/*.{conf,png,pc,coffee,txt,spec.js,ts,js.flow,html,def,jst,xml,ico,in,ac,sln,dsp,dsw,cmd,vcproj,vcxproj,vcxproj.filters,pdb,exp,obj,lib,map,md,sh,gypi,gyp,h,cpp,yml,log,tlog,Makefile,mk,c,cc,rc,xcodeproj,xcconfig,d.ts,yaml,hpp}", 57 | "!**/node_modules/**/node-v*-x64{,/**/*}", 58 | "!**/node_modules/bluebird/js/browser{,/**/*}", 59 | "!**/node_modules/bluebird/js/browser{,/**/*}", 60 | "!**/node_modules/source-map/dist{,/**/*}", 61 | "!**/node_modules/lodash/fp{,/**/*}", 62 | "!**/node_modules/async/!(dist|package.json)", 63 | "!**/node_modules/async/internal{,/**/*}", 64 | "!**/node_modules/ajv/dist{,/**/*}", 65 | "!**/node_modules/ajv/scripts{,/**/*}", 66 | "!**/node_modules/node-pre-gyp/!(lib|package.json)", 67 | "!**/node_modules/node-pre-gyp/lib/!(util|pre-binding.js|node-pre-gyp.js)", 68 | "!**/node_modules/node-pre-gyp/lib/util/!(versioning.js|abi_crosswalk.json)", 69 | "!**/node_modules/source-map-support/browser-source-map-support.js", 70 | "!**/node_modules/json-schema/!(package.json|lib)" 71 | ] 72 | ``` 73 | 74 | ## Build settings for projects that use Native Node modules 75 | 76 | For projects that use the **Native Node Module**, add the following script to your `package.json`: When installing dependencies, `electron-builder` will take care of any modules that require rebuilding. 77 | 78 | ```json 79 | { 80 | "scripts": { 81 | "postinstall": "electron-builder install-app-deps" 82 | } 83 | } 84 | ``` 85 | -------------------------------------------------------------------------------- /docs/src/zhHans/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: Vutron 5 | titleTemplate: Vite + Vue 3 + Electron 快速入门模板 6 | 7 | hero: 8 | name: Vutron 9 | text: Vite + Vue 3 + Electron 快速入门模板 10 | tagline: Vutron是一个用于开发 "Electron" 跨平台桌面应用程序的预配置模板。它使用 "Vue 3",可让您轻松构建快速开发环境。 11 | actions: 12 | - theme: brand 13 | text: 入门 14 | link: /zhHans/installation-and-build/getting-started 15 | - theme: alt 16 | text: GitHub 17 | link: https://github.com/jooy2/vutron 18 | image: 19 | src: /icon.png 20 | alt: Vue 21 | 22 | features: 23 | - icon: 24 | title: 功能强大的网络应用程序开发模板 25 | details: Vutron 支持跨平台、多语言、布局和主题以及风格框架。 26 | - icon: 27 | title: 通过热加载实现快速开发 28 | details: 为开发人员提供最大程度的功能支持,缩短项目初始设置时间。 29 | - icon: 30 | title: 可靠的维护支持 31 | details: 我们有许多实际的使用案例,而且我们拥有快速的技术支持。 32 | --- 33 | -------------------------------------------------------------------------------- /docs/src/ko/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: Vutron 5 | titleTemplate: Vite + Vue 3 + Electron용 빠른 시작 템플릿 6 | 7 | hero: 8 | name: Vutron 9 | text: Vite + Vue 3 + Electron용 빠른 시작 템플릿 10 | tagline: Vutron은 Electron 크로스 플랫폼 데스크톱 앱 개발을 위해 미리 구성된 템플릿입니다. Vue 3을 사용하며 적은 노력으로 빠른 개발 환경을 구축할 수 있습니다. 11 | actions: 12 | - theme: brand 13 | text: 시작하기 14 | link: /ko/installation-and-build/getting-started 15 | - theme: alt 16 | text: GitHub 17 | link: https://github.com/jooy2/vutron 18 | image: 19 | src: /icon.png 20 | alt: Vue 21 | 22 | features: 23 | - icon: 24 | title: 강력한 웹 애플리케이션 개발 템플릿 25 | details: Vutron은 크로스 플랫폼, 다국어, 레이아웃 및 테마, 스타일 프레임워크를 지원합니다. 26 | - icon: 27 | title: 핫 리로드를 통한 빠른 개발 28 | details: 개발자를 위한 최대 기능 지원으로 초기 프로젝트 설정 시간을 단축하세요. 29 | - icon: 30 | title: 안정적인 유지 관리 지원 31 | details: 실제 사용 사례도 많고 기술 지원도 신속하게 제공합니다. 32 | --- 33 | -------------------------------------------------------------------------------- /src/main/MainRunner.ts: -------------------------------------------------------------------------------- 1 | import { 2 | app, 3 | BrowserWindow, 4 | RenderProcessGoneDetails, 5 | BrowserWindowConstructorOptions 6 | } from 'electron' 7 | import Constants, { TrayOptions } from './utils/Constants' 8 | import IPCs from './IPCs' 9 | import { createTray, hideWindow, showWindow } from './tray' 10 | import log from 'electron-log/main' 11 | 12 | const options = { 13 | width: Constants.IS_DEV_ENV ? 1500 : 1200, 14 | height: 650, 15 | tray: { 16 | // all optional values from DEFAULT_TRAY_OPTIONS can de defined here 17 | enabled: true, 18 | menu: false, // true, to use a tray menu ; false to toggle visibility on click on tray icon 19 | trayWindow: false // true, to use a tray floating window attached to top try icon 20 | } 21 | } 22 | 23 | const exitApp = (mainWindow: BrowserWindow): void => { 24 | if (mainWindow && !mainWindow.isDestroyed()) { 25 | mainWindow.hide() 26 | } 27 | mainWindow.destroy() 28 | app.exit() 29 | } 30 | 31 | export const createMainWindow = async (): Promise => { 32 | log.silly('Creating new window...') 33 | 34 | let opt: BrowserWindowConstructorOptions = { 35 | title: Constants.APP_NAME, 36 | show: false, 37 | width: options.width, 38 | height: options.height, 39 | useContentSize: true, 40 | webPreferences: Constants.DEFAULT_WEB_PREFERENCES, 41 | frame: true 42 | } 43 | const trayOptions: TrayOptions = options.tray?.enabled 44 | ? { 45 | ...Constants.DEFAULT_TRAY_OPTIONS, 46 | ...options.tray 47 | } 48 | : { 49 | ...Constants.DEFAULT_TRAY_OPTIONS, 50 | enabled: false 51 | } 52 | 53 | // trayWindow requires tray.enabled=true 54 | if (trayOptions.enabled && trayOptions.trayWindow) { 55 | opt = { 56 | ...opt, 57 | width: options.width, 58 | height: options.height, 59 | maxWidth: options.width, 60 | maxHeight: options.height, 61 | show: false, 62 | frame: false, 63 | fullscreenable: false, 64 | hiddenInMissionControl: true, 65 | resizable: false, 66 | transparent: true, 67 | alwaysOnTop: true, 68 | webPreferences: { 69 | ...Constants.DEFAULT_WEB_PREFERENCES, 70 | backgroundThrottling: false 71 | } 72 | } 73 | } 74 | const mainWindow = new BrowserWindow(opt) 75 | 76 | mainWindow.setMenu(null) 77 | 78 | mainWindow.on('close', (event: Event): void => { 79 | event.preventDefault() 80 | exitApp(mainWindow) 81 | }) 82 | 83 | mainWindow.webContents.on('did-frame-finish-load', (): void => { 84 | if (Constants.IS_DEV_ENV && Constants.FEAT_OPEN_DEV_TOOLS_AT_START) { 85 | mainWindow.webContents.openDevTools() 86 | } 87 | }) 88 | 89 | if (trayOptions.enabled) { 90 | createTray(mainWindow, trayOptions) 91 | } 92 | 93 | if (trayOptions.enabled && trayOptions.trayWindow) { 94 | hideWindow(mainWindow) 95 | if (trayOptions.showAtStartup) { 96 | showWindow(mainWindow) 97 | } 98 | } else { 99 | mainWindow.once('ready-to-show', (): void => { 100 | mainWindow.setAlwaysOnTop(true) 101 | mainWindow.show() 102 | mainWindow.focus() 103 | mainWindow.setAlwaysOnTop(false) 104 | }) 105 | } 106 | 107 | // Initialize IPC Communication 108 | IPCs.initialize() 109 | 110 | if (Constants.IS_DEV_ENV) { 111 | await mainWindow.loadURL(Constants.APP_INDEX_URL_DEV) 112 | } else { 113 | await mainWindow.loadFile(Constants.APP_INDEX_URL_PROD) 114 | } 115 | 116 | return mainWindow 117 | } 118 | 119 | export const createErrorWindow = async ( 120 | errorWindow: BrowserWindow, 121 | mainWindow: BrowserWindow, 122 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 123 | details?: RenderProcessGoneDetails 124 | ): Promise => { 125 | if (!Constants.IS_DEV_ENV) { 126 | mainWindow?.hide() 127 | } 128 | 129 | errorWindow = new BrowserWindow({ 130 | title: Constants.APP_NAME, 131 | show: false, 132 | resizable: Constants.IS_DEV_ENV, 133 | webPreferences: Constants.DEFAULT_WEB_PREFERENCES 134 | }) 135 | 136 | errorWindow.setMenu(null) 137 | 138 | if (Constants.IS_DEV_ENV) { 139 | await errorWindow.loadURL(`${Constants.APP_INDEX_URL_DEV}#/error`) 140 | } else { 141 | await errorWindow.loadFile(Constants.APP_INDEX_URL_PROD, { hash: 'error' }) 142 | } 143 | 144 | errorWindow.on('ready-to-show', (): void => { 145 | if (!Constants.IS_DEV_ENV && mainWindow && !mainWindow.isDestroyed()) { 146 | mainWindow.destroy() 147 | } 148 | errorWindow.show() 149 | errorWindow.focus() 150 | }) 151 | 152 | errorWindow.webContents.on('did-frame-finish-load', (): void => { 153 | if (Constants.IS_DEV_ENV) { 154 | errorWindow.webContents.openDevTools() 155 | } 156 | }) 157 | 158 | return errorWindow 159 | } 160 | -------------------------------------------------------------------------------- /docs/src/en/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: Vutron 5 | titleTemplate: Quick Start Templates for Vite + Vue 3 + Electron 6 | 7 | hero: 8 | name: Vutron 9 | text: Quick Start Templates for Vite + Vue 3 + Electron 10 | tagline: Vutron is a preconfigured template for developing `Electron` cross-platform desktop apps. It uses `Vue 3` and allows you to build a fast development environment with little effort. 11 | actions: 12 | - theme: brand 13 | text: Getting Started 14 | link: /installation-and-build/getting-started 15 | - theme: alt 16 | text: GitHub 17 | link: https://github.com/jooy2/vutron 18 | image: 19 | src: /icon.png 20 | alt: Vue 21 | 22 | features: 23 | - icon: 24 | title: Powerful web application development templates 25 | details: Vutron supports cross-platform, multi-language, layouts and theme, and style frameworks. 26 | - icon: 27 | title: Rapid development through hot-reload 28 | details: Reduce initial project setup time with maximum feature support for developers. 29 | - icon: 30 | title: Reliable maintenance support 31 | details: There are many real-world use cases, and we have fast technical support. 32 | --- 33 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. 8 | 9 | ## Our Standards 10 | 11 | Examples of behavior that contributes to a positive environment for our community include: 12 | 13 | - Demonstrating empathy and kindness toward other people 14 | - Being respectful of differing opinions, viewpoints, and experiences 15 | - Giving and gracefully accepting constructive feedback 16 | - Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience 17 | - Focusing on what is best not just for us as individuals, but for the overall community 18 | 19 | Examples of unacceptable behavior include: 20 | 21 | - The use of sexualized language or imagery, and sexual attention or advances of any kind 22 | - Trolling, insulting or derogatory comments, and personal or political attacks 23 | - Public or private harassment 24 | - Publishing others' private information, such as a physical or email address, without their explicit permission 25 | - Other conduct which could reasonably be considered inappropriate in a professional setting 26 | 27 | ## Enforcement Responsibilities 28 | 29 | Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. 32 | 33 | ## Scope 34 | 35 | This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. 36 | 37 | ## Enforcement 38 | 39 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at https://cdget.com/contact. All complaints will be reviewed and investigated promptly and fairly. 40 | 41 | All community leaders are obligated to respect the privacy and security of the reporter of any incident. 42 | 43 | ## Enforcement Guidelines 44 | 45 | Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: 46 | 47 | ### 1. Correction 48 | 49 | **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. 50 | 51 | **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. 52 | 53 | ### 2. Warning 54 | 55 | **Community Impact**: A violation through a single incident or series of actions. 56 | 57 | **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. 58 | 59 | ### 3. Temporary Ban 60 | 61 | **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. 62 | 63 | **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. 64 | 65 | ### 4. Permanent Ban 66 | 67 | **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. 68 | 69 | **Consequence**: A permanent ban from any sort of public interaction within the community. 70 | 71 | ## Attribution 72 | 73 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 74 | 75 | Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). 76 | 77 | [homepage]: https://www.contributor-covenant.org 78 | 79 | For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. 80 | -------------------------------------------------------------------------------- /src/renderer/screens/MainScreen.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 201 | --------------------------------------------------------------------------------