├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .github └── workflows │ └── deploy.yml ├── .gitignore ├── .npmrc ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── docs ├── .vitepress │ └── config.ts ├── about │ └── index.md ├── api │ └── index.md ├── index.md ├── introduce │ ├── catalogue.md │ ├── cli.md │ ├── config.md │ ├── introduction.md │ └── project.md ├── plugins │ ├── create-electronup.md │ ├── electron-browser.md │ ├── electron-ipc.md │ ├── electron-preload.md │ ├── index.md │ └── parser-config.md └── public │ ├── favicon.ico │ ├── group.jpg │ ├── home.png │ └── quiteer.jpg ├── package.json ├── packages ├── create-electronup │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ └── cli.spec.ts │ ├── build.config.ts │ ├── index.js │ ├── package.json │ ├── src │ │ ├── getData.ts │ │ └── index.ts │ ├── template │ │ ├── base │ │ │ ├── .env │ │ │ ├── .env.development │ │ │ ├── .env.production │ │ │ ├── .eslintrc.cjs.ejs │ │ │ ├── .npmrc.ejs │ │ │ ├── .vscode │ │ │ │ └── settings.json │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── _gitignore │ │ │ ├── electronup.config.ts.ejs │ │ │ ├── main │ │ │ │ ├── index.ts │ │ │ │ └── utils │ │ │ │ │ ├── common.ts │ │ │ │ │ └── is.ts │ │ │ ├── package.json.ejs │ │ │ ├── public │ │ │ │ ├── icon.png │ │ │ │ └── vite.svg │ │ │ ├── tsconfig.json.ejs │ │ │ ├── tsconfig.node.json │ │ │ └── typings │ │ │ │ ├── env.d.ts │ │ │ │ └── global.d.ts │ │ ├── react │ │ │ ├── App.css │ │ │ ├── App.tsx │ │ │ ├── assets │ │ │ │ └── react.svg │ │ │ ├── index.css │ │ │ ├── index.html │ │ │ └── main.tsx │ │ ├── solid │ │ │ ├── App.css │ │ │ ├── App.tsx │ │ │ ├── assets │ │ │ │ └── solid.svg │ │ │ ├── index.css │ │ │ ├── index.html │ │ │ └── index.tsx │ │ ├── vanilla │ │ │ ├── counter.ts │ │ │ ├── index.html │ │ │ ├── main.ts │ │ │ ├── style.css │ │ │ └── typescript.svg │ │ └── vue │ │ │ ├── App.vue │ │ │ ├── assets │ │ │ ├── avatar.png │ │ │ └── vue.svg │ │ │ ├── index.html │ │ │ ├── loading │ │ │ └── index.vue │ │ │ ├── main.ts │ │ │ ├── store │ │ │ └── index.ts │ │ │ └── styles │ │ │ └── style.css │ └── tsconfig.json └── electronup │ ├── LICENSE │ ├── README.md │ ├── cli.ts │ ├── configs │ ├── builder.ts │ ├── electronup.ts │ ├── tsup.ts │ └── vite.ts │ ├── index.ts │ ├── package.json │ ├── runner │ ├── build.ts │ ├── index.ts │ └── watch.ts │ ├── transform │ ├── getConfig.ts │ ├── getExportConfig.ts │ └── index.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── typings │ └── electronup.d.ts │ └── utils │ ├── dirs.ts │ ├── index.ts │ └── store.ts ├── playground ├── edit-config │ ├── electronup.config.ts │ └── package.json └── electronup-test │ ├── .env │ ├── .env.development │ ├── .env.production │ ├── .env.staging │ ├── .env.test │ ├── build │ ├── builder.config.ts │ ├── electronup.config.ts │ ├── tsup.config.ts │ └── vite.config.ts │ ├── electronup.config.ts │ ├── main │ └── index.ts │ ├── package.json │ ├── public │ └── vite.svg │ ├── render │ ├── App.vue │ ├── assets │ │ └── vue.svg │ ├── components │ │ └── HelloWorld.vue │ ├── index.html │ ├── main.ts │ └── style.css │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── typings │ ├── global.d.ts │ └── vite-env.d.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── template ├── index.ts ├── package.json ├── react-project │ ├── .env │ ├── .env.development │ ├── .env.production │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .npmrc │ ├── LICENSE │ ├── README.md │ ├── electronup.config.ts │ ├── main │ │ ├── index.ts │ │ └── utils │ │ │ ├── common.ts │ │ │ └── is.ts │ ├── package.json │ ├── public │ │ ├── icon.png │ │ └── vite.svg │ ├── render │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ └── react.svg │ │ ├── index.css │ │ ├── index.html │ │ └── main.tsx │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── typings │ │ ├── env.d.ts │ │ └── global.d.ts ├── react-swc-project │ ├── .env │ ├── .env.development │ ├── .env.production │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .npmrc │ ├── LICENSE │ ├── README.md │ ├── electronup.config.ts │ ├── main │ │ ├── index.ts │ │ └── utils │ │ │ ├── common.ts │ │ │ └── is.ts │ ├── package.json │ ├── public │ │ ├── icon.png │ │ └── vite.svg │ ├── render │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ └── react.svg │ │ ├── index.css │ │ ├── index.html │ │ └── main.tsx │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── typings │ │ ├── env.d.ts │ │ └── global.d.ts ├── solid-project │ ├── .env │ ├── .env.development │ ├── .env.production │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .npmrc │ ├── LICENSE │ ├── README.md │ ├── electronup.config.ts │ ├── main │ │ ├── index.ts │ │ └── utils │ │ │ ├── common.ts │ │ │ └── is.ts │ ├── package.json │ ├── public │ │ ├── icon.png │ │ └── vite.svg │ ├── render │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ └── solid.svg │ │ ├── index.css │ │ ├── index.html │ │ └── index.tsx │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── typings │ │ ├── env.d.ts │ │ └── global.d.ts ├── vanilla-project │ ├── .env │ ├── .env.development │ ├── .env.production │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .npmrc │ ├── LICENSE │ ├── README.md │ ├── electronup.config.ts │ ├── main │ │ ├── index.ts │ │ └── utils │ │ │ ├── common.ts │ │ │ └── is.ts │ ├── package.json │ ├── public │ │ ├── icon.png │ │ └── vite.svg │ ├── render │ │ ├── counter.ts │ │ ├── index.html │ │ ├── main.ts │ │ ├── style.css │ │ └── typescript.svg │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── typings │ │ ├── env.d.ts │ │ └── global.d.ts └── vue-project │ ├── .env │ ├── .env.development │ ├── .env.production │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .npmrc │ ├── LICENSE │ ├── README.md │ ├── electronup.config.ts │ ├── main │ ├── index.ts │ └── utils │ │ ├── common.ts │ │ └── is.ts │ ├── package.json │ ├── public │ ├── icon.png │ └── vite.svg │ ├── render │ ├── App.vue │ ├── assets │ │ ├── avatar.png │ │ └── vue.svg │ ├── index.html │ ├── loading │ │ └── index.vue │ ├── main.ts │ ├── store │ │ └── index.ts │ └── styles │ │ └── style.css │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── typings │ ├── env.d.ts │ └── global.d.ts └── vitest.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | temp 3 | node_modules 4 | **/*.md 5 | docs/.vitepress/cache 6 | .github 7 | *.ejs 8 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quiteer" 3 | } 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | # Sample workflow for building and deploying a VitePress site to GitHub Pages 2 | # 3 | name: Deploy VitePress site to Pages 4 | 5 | on: 6 | # Runs on pushes targeting the `main` branch. Change this to `master` if you're 7 | # using the `master` branch as the default branch. 8 | push: 9 | branches: [main] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 15 | permissions: 16 | contents: read 17 | pages: write 18 | id-token: write 19 | 20 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 21 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 22 | concurrency: 23 | group: pages 24 | cancel-in-progress: false 25 | 26 | jobs: 27 | # Build job 28 | build: 29 | runs-on: ubuntu-latest 30 | steps: 31 | - name: Checkout 32 | uses: actions/checkout@v3 33 | with: 34 | fetch-depth: 0 # Not needed if lastUpdated is not enabled 35 | 36 | - name: Install pnpm 37 | uses: pnpm/action-setup@v2.2.4 38 | 39 | - name: Setup Node 40 | uses: actions/setup-node@v3 41 | with: 42 | node-version: 18 43 | registry-url: https://registry.npmjs.org/ 44 | cache: pnpm 45 | 46 | - name: Setup Pages 47 | uses: actions/configure-pages@v3 48 | 49 | - name: Install dependencies 50 | run: pnpm install # or pnpm install / yarn install 51 | 52 | - name: Build with VitePress 53 | run: pnpm docs:build # or pnpm docs:build / yarn docs:build 54 | 55 | - name: Upload artifact 56 | uses: actions/upload-pages-artifact@v2 57 | with: 58 | path: docs/.vitepress/dist 59 | 60 | # Deployment job 61 | deploy: 62 | environment: 63 | name: github-pages 64 | url: ${{ steps.deployment.outputs.page_url }} 65 | needs: build 66 | runs-on: ubuntu-latest 67 | name: Deploy 68 | steps: 69 | - name: Deploy to GitHub Pages 70 | id: deployment 71 | uses: actions/deploy-pages@v2 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | npm-debug.log* 3 | yarn-debug.log* 4 | yarn-error.log* 5 | .DS_Store 6 | dist 7 | out 8 | bin 9 | logs 10 | coverage 11 | 12 | node_modules/ 13 | jspm_packages/ 14 | 15 | /docs/.vitepress/cache 16 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmmirror.com 2 | electron_mirror=https://cdn.npmmirror.com/binaries/electron/ 3 | electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/ 4 | sqlite3_mirror=https://cdn.npmmirror.com/binaries/sqlite3/ 5 | 6 | # https://pnpm.io/zh/npmrc#strict-peer-dependencies 7 | strict-peer-dependencies=false 8 | # https://pnpm.io/zh/cli/run#shell-emulator 9 | shell-emulator=true 10 | # https://pnpm.io/zh/npmrc#auto-install-peers 11 | auto-install-peers=false 12 | # https://pnpm.io/zh/npmrc#node-linker 13 | # node-linker=hoisted 14 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "prettier.enable": false, 3 | "editor.formatOnSave": false, 4 | "editor.codeActionsOnSave": { 5 | "source.fixAll.eslint": "explicit", 6 | "source.organizeImports": "never" 7 | }, 8 | 9 | // The following is optional. 10 | // It's better to put under project setting `.vscode/settings.json` 11 | // to avoid conflicts with working with different eslint configs 12 | // that does not support all formats. 13 | "eslint.validate": [ 14 | "javascript", 15 | "javascriptreact", 16 | "typescript", 17 | "typescriptreact", 18 | "vue", 19 | "html", 20 | "markdown", 21 | "json", 22 | "jsonc", 23 | "yaml" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 安静 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # electronup 2 | 3 | 4 | > 融合构建 electron 应用需要的构建工具,保留原有配置习惯的命令行工具 。 5 | 6 | 7 | ## 安装 8 | 9 | ```bash 10 | npm i electronup -D 11 | ``` 12 | 13 | ```bash 14 | yarn add electronup -D 15 | ``` 16 | 17 | ```bash 18 | pnpm add electronup -D 19 | ``` 20 | 21 | ## 文档 22 | 23 | > 详细文档已施工完毕 ~ 24 | > https://quiteerjs.github.io/electronup/ 25 | 26 | ## 示例 27 | 28 | > https://github.com/QuiteerJs/electronup/tree/main/playground/electronup-test 29 | -------------------------------------------------------------------------------- /docs/.vitepress/config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress' 2 | import { version } from '../../packages/electronup/package.json' 3 | 4 | export default defineConfig({ 5 | title: 'electronup中文文档', 6 | description: 'electron 的构建所需', 7 | base: '/electronup/', 8 | lang: 'en', 9 | head: [['link', { rel: 'icon', href: 'favicon.ico' }]], 10 | markdown: { 11 | lineNumbers: true 12 | }, 13 | lastUpdated: true, 14 | appearance: true, 15 | themeConfig: { 16 | siteTitle: 'electronup中文文档', 17 | logo: '/favicon.ico', 18 | lastUpdatedText: '最后更新时间', 19 | footer: { 20 | message: 'Released under the MIT License.', 21 | copyright: 'Copyright © 2023-08-present 安静' 22 | }, 23 | docFooter: { 24 | prev: '上一页', 25 | next: '下一页' 26 | }, 27 | nav: nav(), 28 | socialLinks: [{ icon: 'github', link: 'https://github.com/QuiteerJs/electronup' }], 29 | sidebar: { 30 | '/about/': [ 31 | { 32 | text: '关于', 33 | items: [{ text: '文档配置', link: '/about/' }] 34 | } 35 | ], 36 | ...introduceSidebar() 37 | } 38 | } 39 | }) 40 | 41 | function nav() { 42 | return [ 43 | { 44 | text: '指引', 45 | link: '/introduce/project', 46 | activeMatch: '/introduce|main|renderer|config|builder/' 47 | }, 48 | { 49 | text: '关于', 50 | link: '/about/', 51 | activeMatch: '/about/' 52 | }, 53 | { 54 | text: '相关文档', 55 | items: [ 56 | { 57 | text: 'electron', 58 | link: 'https://www.electronjs.org/' 59 | }, 60 | { 61 | text: 'vite', 62 | link: 'https://cn.vitejs.dev/' 63 | }, 64 | { 65 | text: 'tsup', 66 | link: 'https://tsup.egoist.dev/' 67 | }, 68 | { 69 | text: 'electron-builder', 70 | link: 'https://www.electron.build/' 71 | } 72 | ] 73 | }, 74 | { 75 | text: version, 76 | items: [ 77 | { 78 | text: '组织', 79 | link: 'https://github.com/QuiteerJs' 80 | }, 81 | { 82 | text: '友情连接/sky', 83 | link: 'https://zh-sky.gitee.io/electron-vue-template-doc/' 84 | } 85 | ] 86 | } 87 | ] 88 | } 89 | 90 | function introduceSidebar() { 91 | const commonRoute = [ 92 | { 93 | text: '介绍', 94 | items: [ 95 | { text: '项目介绍', link: '/introduce/project' }, 96 | { text: '快速上手', link: '/introduce/introduction' }, 97 | { text: '目录', link: '/introduce/catalogue' }, 98 | { text: '命令行界面', link: '/introduce/cli' }, 99 | { text: '配置', link: '/introduce/config' } 100 | ] 101 | }, 102 | { 103 | text: '插件', 104 | items: [ 105 | { text: '插件总览', link: '/plugins/' }, 106 | { text: 'parser-config', link: '/plugins/parser-config' }, 107 | { text: 'create-electronup', link: '/plugins/create-electronup' }, 108 | { text: 'electron-ipc', link: '/plugins/electron-ipc' }, 109 | { text: 'electron-preload', link: '/plugins/electron-preload' }, 110 | { text: 'electron-browser', link: '/plugins/electron-browser' } 111 | ] 112 | }, 113 | { 114 | text: 'API', 115 | items: [{ text: 'API', link: '/api/' }] 116 | } 117 | ] 118 | 119 | return { 120 | '/introduce/': commonRoute, 121 | '/plugins/': commonRoute, 122 | '/api/': commonRoute 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /docs/about/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 配置 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | ::: tip 本文档的 vitepress 配置 8 | 仅供参考 , 更多配置请查看官方文档 9 | ::: 10 | <<< @/.vitepress/config.ts 11 | -------------------------------------------------------------------------------- /docs/api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: API 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | ## `defineConfig` 8 | 9 | > 工具函数,配置智能提示。 10 | 11 | 最基础的配置文件是这样的: 12 | 13 | ```ts 14 | // electronup.config.ts 15 | import { defineConfig } from 'electronup' 16 | 17 | export default defineConfig({ 18 | // ... 19 | }) 20 | ``` 21 | 22 | 注意:即使项目没有在 package.json 中开启 type: "module" ,electronup 也支持在配置文件中使用 ESM 语法。这种情况下,配置文件会在被加载前自动进行预处理。 23 | 24 | ### 情景配置 25 | 26 | > 如果配置文件需要基于(dev/serve 或 build)命令或者不同的 模式 来决定选项,亦或者是一个 SSR 构建(ssrBuild),则可以选择导出这样一个函数: 27 | 28 | ```ts 29 | export default defineConfig(({ command, root }) => { 30 | if (command === 'serve') { 31 | return { 32 | // dev 独有配置 33 | } 34 | } else { 35 | // command === 'build' 36 | return { 37 | // build 独有配置 38 | } 39 | } 40 | } 41 | ``` 42 | 43 | ### 异步配置 44 | 45 | > 如果配置需要调用一个异步函数,也可以转而导出一个异步函数。这个异步函数也可以通过 defineConfig 传递,以便获得更好的智能提示: 46 | 47 | ```ts 48 | export default defineConfig(async ({ command, mode }) => { 49 | const data = await asyncFunction() 50 | return { 51 | // 配置 52 | } 53 | }) 54 | ``` 55 | 56 | ### 在配置中使用环境变量 57 | 58 | > 暂不支持。 59 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | # https://vitepress.dev/reference/default-theme-home-page 3 | layout: home 4 | 5 | hero: 6 | name: "electronup" 7 | text: "electron 的构建所需" 8 | tagline: 简化配置文件 , package 瘦身 , 多种选项的 cli 9 | image: 10 | src: /home.png 11 | alt: quiteer 12 | style: 13 | 14 | actions: 15 | - theme: brand 16 | text: 开始使用 17 | link: /introduce/introduction 18 | - text: 介绍 19 | link: /introduce/project 20 | - theme: alt 21 | text: GitHub 22 | link: https://github.com/QuiteerJs/electronup 23 | - theme: alt 24 | text: 友情连接/sky 25 | link: https://zh-sky.gitee.io/electron-vue-template-doc/ 26 | 27 | features: 28 | - icon: ⚡️ 29 | title: 立即响应 30 | details: 双进程热更新 , 代码修改快速响应 ! 不再等待 (最多等一会会 ... ) 31 | - icon: 🦾 32 | title: 个性化打包 33 | details: 人性化脚本配置 , 默认识别当前平台输出打包 , 选项式自定义配置打包 34 | - icon: 🤺 35 | title: 知根知底 36 | details: 详尽的文档介绍 , 手摸手教学 ( 共同学习 ) 37 | - icon: 🛠️ 38 | title: vite 39 | details: 提供渲染进程热更新及构建发布 40 | - icon: 🛠️ 41 | title: tsup 42 | details: 提供主进程代码热更新及构建发布 43 | - icon: 🛠️ 44 | title: electron-builder 45 | details: 构建桌面端软件包所需,提供了一些可覆盖的预置配置 46 | --- 47 | 48 | 49 | 70 | -------------------------------------------------------------------------------- /docs/introduce/catalogue.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 目录介绍 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | ## 概览 8 | 9 | ## 以 vue 模板为例 10 | 11 | :::tip 12 | 接下来会逐个文件进行讲解说明。 13 | ::: 14 | 15 | ```sh 16 | |-- template-vue 17 | |-- .env 18 | |-- .env.development 19 | |-- .env.production 20 | |-- .eslintrc 21 | |-- .gitignore 22 | |-- .npmrc 23 | |-- electronup.config.ts 24 | |-- LICENSE 25 | |-- package.json 26 | |-- README.md 27 | |-- tsconfig.json 28 | |-- tsconfig.node.json 29 | |-- .vscode 30 | | |-- extensions.json 31 | | |-- settings.json 32 | |-- main 33 | | |-- index.ts 34 | | |-- utils 35 | | |-- common.ts 36 | | |-- is.ts 37 | |-- public 38 | | |-- avatar.png 39 | | |-- icon.png 40 | | |-- vite.svg 41 | |-- render 42 | | |-- App.vue 43 | | |-- index.html 44 | | |-- main.ts 45 | | |-- assets 46 | | | |-- vue.svg 47 | | |-- loading 48 | | | |-- index.vue 49 | | |-- store 50 | | | |-- index.ts 51 | | |-- styles 52 | | |-- style.css 53 | |-- typings 54 | |-- env.d.ts 55 | |-- global.d.ts 56 | 57 | ``` 58 | 59 | ## `.env.*` 60 | 61 | > 环境变量,可根据自己需求设置不同后缀实现不同环境的环境变量。 62 | 63 | - **.env** : 默认加载的环境变量。 64 | - **.env.development** : 开发环境变量。 65 | - **.env.production** : 生产环境变量。 66 | 67 | ## `.eslintrc` 68 | 69 | eslint配置。 70 | 71 | ## `.gitignore` 72 | 73 | git 忽略目录。 74 | 75 | ## `.npmrc` 76 | 77 | 项目下包管理器的配置,npmrc比较通用,yarn也会读取该文件的配置。 78 | 79 | ## `electronup.config.ts` 80 | 81 | **electronup** 核心配置,用户自定义配置文件。 82 | 83 | ## `LICENSE` 84 | 85 | 开源协议。 86 | 87 | ## `package.json` 88 | 89 | 项目管理信息。 90 | 91 | ## `README.md` 92 | 93 | 项目说明。 94 | 95 | ## `tsconfig.json` 96 | 97 | 渲染进程 ts 规则配置。 98 | 99 | ## `tsconfig.node.json` 100 | 101 | node 环境下 ts 的配置。 102 | 103 | ## `.vscode` 104 | 105 | vscode 配置,作用于项目内,不影响全局配置。 106 | 107 | ### `extensions.json` 108 | 109 | 插件推荐。 110 | 111 | ### `settings.json` 112 | 113 | 编辑器配置。 114 | 115 | ## `main` 116 | 117 | > 主进程可用。 118 | 119 | 主进程环境代码为 `nodejs`, 明确的隔离提升代码可读性。 120 | 121 | ## `public` 122 | 123 | > 静态资源目录 124 | 125 | 该目录下的文件总会输出至项目根目录。 126 | 127 | ## `render` 128 | 129 | > 渲染进程可用。 130 | 131 | 熟悉的前端 vue 目录 , 基本与平时的 `vue3` 项目结构一致。 132 | 133 | ## `typings` 134 | 135 | > 双进程可用。 136 | 137 | 全局类型定义, `*.d.ts` 统一存放 , 无需导出 , 可自定定义添加类型文件。 138 | 139 | -------------------------------------------------------------------------------- /docs/introduce/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 快速上手 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | 本节将帮助您从头开始构建 [**electron**](https://www.electronjs.org/zh/) 应用。 8 | 9 | ## 创建模板 10 | 11 | ::: tip 基本要求 12 | 在使用 `Electron` 进行开发之前,您需要安装 `Node.js` , 并确认 `node` 版本>=18 。 建议您使用最新的 `LTS` 版本或官网当前长期维护版。 13 | 本地环境需要安装 [`npm` | `yarn 1.x` | `pnpm`] 、 `Git`。 14 | ::: 15 | 16 | 使用 `npm`: 17 | 18 | ```bash 19 | npm init electronup@latest 20 | ``` 21 | 22 | or 23 | 24 | ```bash 25 | npm create electronup@latest 26 | ``` 27 | 28 | 使用 `yarn`: 29 | 30 | ```bash 31 | yarn create electronup 32 | ``` 33 | 34 | 使用 `pnpm`: 35 | 36 | ```bash 37 | pnpm create electronup 38 | ``` 39 | 40 | 41 | 这一指令将会安装并执行 [**create-electronup**](https://github.com/QuiteerJs/electronup/tree/main/packages/create-electronup),它是 [**electronup**](https://github.com/QuiteerJs/electronup) 的项目模板脚手架工具。你将会看到一些模板选项提示,根据提示选择想要的模板即可完成创建。 42 | 43 | ::: tip ps 44 | 如果你想要在当前目录下创建项目, 45 | 项目名称填入 `.` 即可:
46 | `? Project name: » .` 47 | ::: 48 | 49 | ### create-electornup 命令行参数 50 | 51 | > `-t` or `--template` 52 | 53 | 可选项: 54 | 55 | - vanilla 56 | - vue 57 | - react 58 | - react-swc 59 | - solid 60 | 61 | 示例: 62 | 63 | ```bash 64 | create-electronup vanilla-project --template vanilla 65 | ``` 66 | 67 | ```bash 68 | create-electronup vue-project -t vue 69 | ``` 70 | 71 | ```bash 72 | create-electronup react-project -t react 73 | ``` 74 | 75 | ```bash 76 | create-electronup react-swc-project -t react-swc 77 | ``` 78 | 79 | ```bash 80 | create-electronup solid-project -t solid 81 | ``` 82 | 83 | 84 | ## 安装依赖 85 | 86 | 使用 `npm`: 87 | 88 | ```bash 89 | npm install 90 | ``` 91 | 92 | 93 | 使用 `yarn`: 94 | 95 | ```bash 96 | yarn install 97 | ``` 98 | 99 | 使用 `pnpm`: 100 | 101 | ```bash 102 | pnpm install 103 | ``` 104 | 105 | ## 命令行 106 | 107 | ```json 108 | { 109 | "scripts": { 110 | // 启动开发环境(不压缩) 111 | "dev": "electronup --no-minify", 112 | // 构建发布 113 | "build": "electronup build", 114 | // 生成 dir 115 | "dir": "electronup build --dir --no-asar --no-minify", 116 | // 预构建 117 | "postinstall": "electron-builder install-app-deps" 118 | } 119 | } 120 | ``` 121 | 122 | ::: details 安装依赖过程中可能出现装不上依赖或者 `rebuild` 报错等问题情况 123 | 建议进群一起交流 群号 : **12354891** 124 | ::: 125 | -------------------------------------------------------------------------------- /docs/introduce/project.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 项目介绍 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | ## 简介 8 | 9 | [electronup](https://github.com/QuiteerJs/electronup) 是一个集成 **Vite4.x**、**tsup6.x**、**electron-builder23.x** 的桌面端构建工具,一个配置文件完成多环境多目标的构建包。 10 | 11 | ::: warning 12 | 因为使用了 tsup 构建主进程代码,所以该命令行及脚手架只支持 `TypeScript` ,不支持 `JavaScript`。 13 | ::: 14 | 15 | ## 特性 16 | 17 | - **多框架支持** : 使用 `create-electronup` 询问式创建项目模板 , 内置 `vue3` , `react` ,`solid` 等项目模板。 18 | - **Vite + tsup** : 双进程热更新 , 快速开发(主进程代码修改会触发软件重启)。 19 | - **统一的环境变量** : `dotenv` 加载 , 构建时注入 , 双进程拥有相同的环境变量。 20 | - **模式构建** : 默认识别当前代码运行的平台输出打包程序 。 21 | - **可选构建功能提示** : 你将获得可选范围内支持的功能提示 , 选项式自定义构建输出。 22 | - **TypeScript** : 应用程序级 `JavaScript` 的语言。 23 | - **集中管理路径** : 解决双进程资源路径的问题。 24 | - **预置配置** : 内置了很多可以覆盖的构建工具配置。 25 | - **单文件配置** : 只需一个 **electronup.config.ts** 即可管理项目的运行构建。 26 | - **多插件** : 作者会继续开发更多无副作用的独立插件,如:创建窗口,预加载,ipc通信,更新等等。 27 | 28 | ## 前置技术栈 29 | 30 | ::: warning 📢 31 | 正常的 electron 开发需要你掌握基本的 node 和 web 开发知识 , 如果你对前端开发完全陌生,最好不要直接在一开始针对一个框架进行学习——最好是掌握了基础知识再回到这里。 32 | ::: 33 | 34 | 如果你想要掌握本框架的完全开发能力,以下技术栈是你需要了解的。 35 | 36 | - `Nodejs` , [Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时环境。](https://nodejs.org/zh-cn/) 37 | - `Electron` , [使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序。](https://www.electronjs.org/) 38 | - `Typescript` , [TypeScript 是 JavaScript 类型的超集,它可以编译成纯 JavaScript。](https://www.tslang.cn/index.html) 39 | - `Vite` , [下一代的前端工具链 , 为开发提供极速响应。](https://cn.vitejs.dev/) 40 | - `tsup` , [这是构建TypeScript库的最简单、最快的方法。](https://tsup.egoist.dev/) 41 | - `Electron-Builder` , [一个完整的解决方案,打包和构建一个准备分发 electron 应用程序与“自动更新”的支持开箱即用。](https://www.electron.build/) 42 | - `适用于vite 的 web 框架` , [vue3.x](https://staging-cn.vuejs.org/),[react16.x](https://zh-hans.react.dev/learn) 。。。 43 | - 更多相关 js 知识 ... 44 | 45 | 46 | ## 集成依赖 47 | 48 | ```json 49 | { 50 | "dependencies": { 51 | "electron-builder": "^23.6.0", 52 | "tsup": "^6.7.0", 53 | "typescript": "^5.0.4", 54 | "vite": "^4.4.9" 55 | } 56 | } 57 | ``` 58 | 59 | 60 | ## 61 | ::: tip 62 | 63 | 和兴趣爱好者一起摸鱼 , 交流 ! 64 | 65 | Electron 技术框架交流群 : 12354891 66 | ::: 67 | -------------------------------------------------------------------------------- /docs/plugins/create-electronup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: create-electronup 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | > 一键生成基于 [electronup](https://github.com/QuiteerJs/electronup) 的项目模板。 8 | > 目前内置了 vue 、 react 、 react-swc。 9 | 10 | ## 按需创建模板 11 | 12 | 打开控制台输入: 13 | 14 | ```bash 15 | npm init electronup [project-name] 16 | ``` 17 | 18 | or 19 | 20 | ```bash 21 | npm create electronup [project-name] 22 | ``` 23 | 24 | `npm create electronup` 后为项目名称,或者传入项目名称,即在当前目录下创建输入的项目名称的模板。 25 | 26 | 不传则会弹出询问 27 | ```bash 28 | ? Project name: » electronup-project 29 | ``` 30 | 传入 `.` 即为当前目录,会在当前目录下创建模板。 31 | 32 | 而后选择模板,根据提示完成项目创建。 33 | -------------------------------------------------------------------------------- /docs/plugins/electron-browser.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: electron-browser 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | > 正在施工。。。。 8 | -------------------------------------------------------------------------------- /docs/plugins/electron-ipc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: electron-ipc 3 | --- 4 | 5 | # @quiteer/electron-ipc 6 | 7 | 8 | > 基于electron , 提供了一些 独立无副作用的 ipc 事件相关操作 9 | 10 | ## 安装 11 | 12 | - 获取项目代码 13 | 14 | ```bash 15 | npm i @quiteer/electron-ipc 16 | ``` 17 | ```bash 18 | yarn add @quiteer/electron-ipc 19 | ``` 20 | ```bash 21 | pnpm add @quiteer/electron-ipc 22 | ``` 23 | 24 | ## 使用 25 | 26 | ### 在主进程中初始化ipc预设 27 | > init即可 无需多余操作 28 | 29 | ```js 30 | import { Ipc } from '@quiteer/electron-ipc' 31 | 32 | app.whenReady().then(() => { 33 | Ipc.init() 34 | }) 35 | ``` 36 | 37 | ### 渲染进程中使用 38 | > 引用包内预定义的事件枚举 按需取用 39 | 40 | ```js 41 | import { EventKeys, IpcWindowOptions } from '@quiteer/electron-ipc/web' 42 | 43 | const test = () => { 44 | // 窗口最大化 45 | window.$ipc.send(EventKeys.WindowOptionsKey, IpcWindowOptions.MAXIMIZE) 46 | 47 | setTimeout(() => { 48 | // 取消最大化 49 | window.$ipc.send(EventKeys.WindowOptionsKey, IpcWindowOptions.UNMAXIMIZE) 50 | }, 1000) 51 | } 52 | ``` 53 | 54 | > 配合 '@quiteer/electron-preload' 使用获得代码提示 55 | 56 | ```ts 57 | // global.d.ts 58 | interface Window { 59 | $ipc: import('@quiteer/electron-preload').PreloadIpc & import('@quiteer/electron-ipc/web').ExpandPreloadIpc 60 | } 61 | 62 | // other.ts 63 | window.$ipc.send('__window_options__', 'destroy') 64 | window.$ipc.invoke('__file_options__', 'join', '/', '/experiment') 65 | ``` 66 | 67 | 68 | -------------------------------------------------------------------------------- /docs/plugins/electron-preload.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: electron-preload 3 | --- 4 | 5 | # @quiteer/electron-preload 6 | 7 | 8 | > 基于electron , 提供预加载功能脚本 9 | 10 | ## 安装 11 | 12 | ```bash 13 | npm i @quiteer/electron-preload 14 | ``` 15 | ```bash 16 | yarn add @quiteer/electron-preload 17 | ``` 18 | ```bash 19 | pnpm add @quiteer/electron-preload 20 | ``` 21 | 22 | 23 | ## 使用 24 | 25 | > 在主进程中引入预加载脚本 26 | 27 | ```js 28 | import preload from '@quiteer/electron-preload' 29 | 30 | const win = new BrowserWindow({ 31 | width: 800, 32 | height: 600 33 | }) 34 | ``` 35 | 36 | ### 暴露的api 37 | 38 | 分别暴露了以下api , 具体使用方法可参照官方 api 文档使用 39 | 40 | - ipcRenderer 41 | - send 42 | - sendSync 43 | - invoke 44 | - on 45 | - once 46 | - removeAllListeners 47 | 48 | - clipboard 49 | - readText 50 | - writeText 51 | - readHTML 52 | - writeHTML 53 | - readImage 54 | - writeImage 55 | - readRTF 56 | - writeRTF 57 | - readBookmark 58 | - writeBookmark 59 | - readFindText 60 | - writeFindText 61 | - clear 62 | - availableFormats 63 | - has 64 | - read 65 | - readBuffer 66 | - writeBuffer 67 | - write 68 | 69 | - webFrame 70 | - setZoomFactor 71 | - getZoomFactor 72 | - setZoomLevel 73 | - getZoomLevel 74 | - insertText 75 | - executeJavaScript 76 | - executeJavaScriptInIsolatedWorld 77 | - setIsolatedWorldInfo 78 | - getResourceUsage 79 | - clearCache 80 | - getFrameForSelector 81 | - firstChild 82 | - nextSibling 83 | - opener 84 | - parent 85 | - routingId 86 | - top 87 | 88 | 89 | ### 渲染进程中使用 90 | 91 | ```js 92 | console.log('window.$ipc :>> ', window.$ipc) 93 | console.log('window.$clipboard :>> ', window.$clipboard) 94 | console.log('window.$webFrame :>> ', window.$webFrame) 95 | ``` 96 | 97 | #### 获取类型提示 98 | 99 | 全局类型声明 100 | ```ts 101 | interface Window { 102 | $ipc: import('@quiteer/electron-preload').PreloadIpc 103 | $clipboard: import('@quiteer/electron-preload').PreLoadPath 104 | $webFrame: import('@quiteer/electron-preload').PreloadWebFrame 105 | } 106 | ``` 107 | 108 | 109 | -------------------------------------------------------------------------------- /docs/plugins/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 总览 3 | --- 4 | 5 | # {{ $frontmatter.title }} 6 | 7 | > 以下是 [electronup cli](https://github.com/QuiteerJs/electronup) 相关的包。 8 | 9 | - [create-electronup](https://github.com/QuiteerJs/electronup/tree/main/packages/create-electronup):创建 electornup cli 驱动的模板的命令行。 10 | - [@quiteer/parser-config](https://github.com/QuiteerJs/parser-config):通过路径解析配置。 11 | - [@quiteer/electron-ipc](https://github.com/QuiteerJs/electron-modules/tree/main/packages/ipc):一些通用的 electron 事件通信。 12 | - [@quiteer/electron-preload](https://github.com/QuiteerJs/electron-modules/tree/main/packages/preload):通用的预加载脚本。 13 | - [@quiteer/electron-browser](https://github.com/QuiteerJs/electron-modules/tree/main/packages/browser):快速创建 electron 窗口程序。 14 | -------------------------------------------------------------------------------- /docs/plugins/parser-config.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: parser-config 3 | --- 4 | 5 | # @quiteer/parser-config 6 | 7 | > 用于读取项目下 'ts', 'mjs', 'js', 'cjs', 'json', 'yaml' 的用户配置 8 | 9 | ## 安装 10 | 11 | ```bash 12 | npm i @quiteer/parser-config -D 13 | ``` 14 | ```bash 15 | yarn add @quiteer/parser-config -D 16 | ``` 17 | ```bash 18 | pnpm add @quiteer/parser-config -D 19 | ``` 20 | 21 | 22 | ## 使用 23 | 24 | `configPath` : 传入具体路径或者所在目录路径,configPath 的 默认路径为当前命令行启动路径 (指定 ·configName· 参数时可传入undefined) 25 | 26 | `configName` : 可选,传入参数后,无需指定具体参数,传入目录路径即可,自动匹配不同后缀的配置文件 27 | 28 | ```ts 29 | import { resolve } from 'path' 30 | import { parserConfig } from '@quiteer/parser-config' 31 | 32 | const filePath = (path: string) => resolve(resolve(), path) 33 | 34 | const cjs = filePath('./test-cjs/config.cjs') 35 | const js = filePath('./test-js/config.js') 36 | const json = filePath('./test-json/config.json') 37 | const mjs = filePath('./test-mjs/config.mjs') 38 | const ts = filePath('./test-ts/config.ts') 39 | const yaml = filePath('./test-yaml/config.yaml') 40 | 41 | const test = async () => { 42 | const yamlConfig = await parserConfig(yaml) 43 | console.log('yamlConfig: ', yamlConfig) 44 | 45 | const jsonConfig = await parserConfig(json) 46 | console.log('jsonConfig: ', jsonConfig) 47 | 48 | const mjsConfig = await parserConfig(mjs) 49 | console.log('mjsConfig: ', mjsConfig) 50 | 51 | const jsConfig = await parserConfig(js) 52 | console.log('jsConfig: ', jsConfig) 53 | 54 | const cjsConfig = await parserConfig(cjs) 55 | console.log('cjsConfig: ', cjsConfig) 56 | 57 | const tsConfig = await parserConfig(ts) 58 | console.log('tsConfig: ', tsConfig) 59 | 60 | const rootConfig = await parserConfig(undefined, 'config') 61 | console.log('rootConfig: ', rootConfig) 62 | 63 | const elctornup = await parserConfig(undefined, 'electronup.config') 64 | console.log('elctornup: ', JSON.stringify(elctornup)) 65 | } 66 | test() 67 | ``` 68 | 69 | ## 暴露的api 70 | ``` ts 71 | /** 72 | * 描述 73 | * @param {any} configPath:string 需要读取配置的路径 74 | * @param {any} configName?:string 配置文件名 75 | * @returns {any} 76 | */ 77 | declare function parserConfig(configPath?: string, configName?: string): Promise 78 | 79 | export { parserConfig } 80 | ``` 81 | 82 | ## 配置文件优先级 83 | 84 | 'ts' > 'mjs' > 'cjs' > 'js' > 'json' > 'yaml' 85 | -------------------------------------------------------------------------------- /docs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/docs/public/favicon.ico -------------------------------------------------------------------------------- /docs/public/group.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/docs/public/group.jpg -------------------------------------------------------------------------------- /docs/public/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/docs/public/home.png -------------------------------------------------------------------------------- /docs/public/quiteer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/docs/public/quiteer.jpg -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electronup-monorepo", 3 | "type": "module", 4 | "private": true, 5 | "packageManager": "pnpm@8.6.7", 6 | "description": "融合构建 electron 应用需要的构建工具,保留原有配置习惯的命令行工具 ", 7 | "author": "quiteer", 8 | "license": "MIT", 9 | "homepage": "https://github.com/QuiteerJs/electronup#readme", 10 | "scripts": { 11 | "work:dev": "pnpm --filter './packages/*' dev", 12 | "work:build": "pnpm --filter './packages/*' build", 13 | "docs:dev": "vitepress dev docs", 14 | "docs:build": "vitepress build docs", 15 | "docs:serve": "vitepress serve docs", 16 | "template:run": "pnpm --filter './template/*' dev", 17 | "lint": "eslint . --fix" 18 | }, 19 | "devDependencies": { 20 | "@quiteer/eslint-config": "^0.0.3", 21 | "@quiteer/ts-config": "^0.0.6", 22 | "@types/fs-extra": "^9.0.13", 23 | "@types/node": "^20.3.2", 24 | "bumpp": "^9.1.1", 25 | "eslint": "^8.46.0", 26 | "typescript": "^5.1.6", 27 | "unbuild": "^1.2.1", 28 | "vitepress": "1.0.0-beta.7", 29 | "vitest": "^0.34.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/create-electronup/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 安静 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 | -------------------------------------------------------------------------------- /packages/create-electronup/README.md: -------------------------------------------------------------------------------- 1 | # create-electronup 2 | 3 | > 通过 `npm create electornup` 创建 `electronup 驱动`的模板,内置各类框架模板。 4 | -------------------------------------------------------------------------------- /packages/create-electronup/__tests__/cli.spec.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'node:path' 2 | import type { ExecaSyncReturnValue, SyncOptions } from 'execa' 3 | import { execaCommandSync } from 'execa' 4 | import fs from 'fs-extra' 5 | import { afterEach, beforeAll, expect, test } from 'vitest' 6 | 7 | const CLI_PATH = join(__dirname, '..') 8 | 9 | const projectName = 'test-app' 10 | const genPath = join(__dirname, projectName) 11 | 12 | const run = ( 13 | args: string[], 14 | options: SyncOptions = {} 15 | ): ExecaSyncReturnValue => { 16 | return execaCommandSync(`node ${CLI_PATH} ${args.join(' ')}`, options) 17 | } 18 | 19 | // Helper to create a non-empty directory 20 | // 创建一个非空目录的助手 21 | const createNonEmptyDir = () => { 22 | // Create the temporary directory 23 | // 创建临时目录 24 | fs.mkdirpSync(genPath) 25 | 26 | // Create a package.json file 27 | // 创建一个 package.json 文件 28 | const pkgJson = join(genPath, 'package.json') 29 | fs.writeFileSync(pkgJson, '{ "foo": "bar" }') 30 | } 31 | 32 | beforeAll(() => fs.remove(genPath)) 33 | afterEach(() => fs.remove(genPath)) 34 | 35 | // 如果未提供项目名称,则提示输入项目名称 36 | test('prompts for the project name if none supplied', () => { 37 | const { stdout } = run([]) 38 | expect(stdout).toContain('Project name:') 39 | }) 40 | 41 | // 当目标目录为当前目录时,如果没有提供框架提示 42 | test('prompts for the framework if none supplied when target dir is current directory', () => { 43 | fs.mkdirpSync(genPath) 44 | const { stdout } = run(['.'], { cwd: genPath }) 45 | expect(stdout).toContain('Select a framework:') 46 | }) 47 | 48 | // 如果没有提供,则提示输入框架 49 | test('prompts for the framework if none supplied', () => { 50 | const { stdout } = run([projectName]) 51 | expect(stdout).toContain('Select a framework:') 52 | }) 53 | 54 | // 要求覆盖非空目标目录 55 | test('asks to overwrite non-empty target directory', () => { 56 | createNonEmptyDir() 57 | const { stdout } = run([projectName], { cwd: __dirname }) 58 | expect(stdout).toContain(`Target directory "${projectName}" is not empty.`) 59 | }) 60 | 61 | // 要求覆盖非空的当前目录 62 | test('asks to overwrite non-empty current directory', () => { 63 | createNonEmptyDir() 64 | const { stdout } = run(['.'], { cwd: genPath }) 65 | expect(stdout).toContain('Current directory is not empty.') 66 | }) 67 | 68 | -------------------------------------------------------------------------------- /packages/create-electronup/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | entries: ['src/index'], 5 | clean: true, 6 | rollup: { 7 | inlineDependencies: true, 8 | esbuild: { 9 | minify: true 10 | } 11 | }, 12 | alias: { 13 | // we can always use non-transpiled code since we support 14.18.0+ 14 | prompts: 'prompts/lib/index.js' 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /packages/create-electronup/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import './dist/index.mjs' 4 | -------------------------------------------------------------------------------- /packages/create-electronup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-electronup", 3 | "type": "module", 4 | "version": "0.1.1", 5 | "description": "创建electronup项目模板", 6 | "author": "quiteer", 7 | "license": "MIT", 8 | "homepage": "https://github.com/QuiteerJs/electronup/tree/main/packages/create-electronup#readme", 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/QuiteerJs/electronup.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/QuiteerJs/electronup/issues" 15 | }, 16 | "bin": { 17 | "create-electronup": "index.js" 18 | }, 19 | "publishConfig": { 20 | "access": "public", 21 | "registry": "https://registry.npmjs.org/" 22 | }, 23 | "files": [ 24 | "index.js", 25 | "template", 26 | "dist" 27 | ], 28 | "engines": { 29 | "node": ">= 18" 30 | }, 31 | "scripts": { 32 | "dev": "unbuild --stub", 33 | "build": "unbuild", 34 | "typecheck": "tsc --noEmit", 35 | "update-version": "bumpp package.json" 36 | }, 37 | "devDependencies": { 38 | "@types/ejs": "^3.1.2", 39 | "@types/minimist": "^1.2.2", 40 | "@types/prompts": "^2.4.4", 41 | "ejs": "^3.1.9", 42 | "execa": "^7.2.0", 43 | "kolorist": "^1.8.0", 44 | "minimist": "^1.2.8", 45 | "prompts": "^2.4.2", 46 | "unbuild": "^1.2.1" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/create-electronup/src/getData.ts: -------------------------------------------------------------------------------- 1 | export type Template = 'vanilla' | 'vue' | 'react' | 'react-swc' | 'svelte' | 'solid' 2 | 3 | export function getData(template: Template) { 4 | switch (template) { 5 | case 'vanilla': 6 | return { 7 | importer: '', 8 | initializer: '', 9 | dependencies: { }, 10 | devDependencies: {}, 11 | jsx: 'preserve' 12 | } 13 | case 'vue': 14 | return { 15 | importer: 'import vue from \'@vitejs/plugin-vue\'', 16 | initializer: 'vue()', 17 | dependencies: { 18 | echarts: '^5.4.2' 19 | }, 20 | devDependencies: { 21 | '@vitejs/plugin-vue': '^5.0.3', 22 | 'pinia': '^2.1.7', 23 | 'vue': '^3.4.15', 24 | 'vue-router': '^4.2.5', 25 | 'vue-tsc': '^1.8.1' 26 | }, 27 | jsx: 'preserve' 28 | } 29 | case 'react': 30 | return { 31 | importer: 'import react from \'@vitejs/plugin-react\'', 32 | initializer: 'react()', 33 | dependencies: { 34 | 'react': '^18.2.0', 35 | 'react-dom': '^18.2.0' 36 | }, 37 | devDependencies: { 38 | '@types/react': '^18.2.18', 39 | '@types/react-dom': '^18.2.7', 40 | '@vitejs/plugin-react': '^4.0.4', 41 | 'eslint-plugin-react-hooks': '^4.6.0', 42 | 'eslint-plugin-react-refresh': '^0.4.3' 43 | }, 44 | jsx: 'react-jsx' 45 | } 46 | case 'react-swc': 47 | return { 48 | importer: 'import reactSwc from \'@vitejs/plugin-react-swc\'', 49 | initializer: 'reactSwc()', 50 | dependencies: { 51 | 'react': '^18.2.0', 52 | 'react-dom': '^18.2.0' 53 | }, 54 | devDependencies: { 55 | '@types/react': '^18.2.18', 56 | '@types/react-dom': '^18.2.7', 57 | '@vitejs/plugin-react-swc': '^3.3.2', 58 | 'eslint-plugin-react-hooks': '^4.6.0', 59 | 'eslint-plugin-react-refresh': '^0.4.3' 60 | }, 61 | jsx: 'react-jsx' 62 | } 63 | case 'solid': 64 | return { 65 | importer: 'import solid from \'vite-plugin-solid\'', 66 | initializer: 'solid()', 67 | dependencies: { 68 | 'solid-js': '^1.7.9' 69 | }, 70 | devDependencies: { 71 | 'vite-plugin-solid': '^2.7.0' 72 | }, 73 | jsx: 'preserve' 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/.env: -------------------------------------------------------------------------------- 1 | VITE_HELLO = 你好!electronup! 2 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/.env.development: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是开发环境 2 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/.env.production: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是生产环境 2 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/.eslintrc.cjs.ejs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | <%_ if(template === 'vue'|| template === 'vanilla'){ _%> 3 | extends: ['@quiteer/eslint-config'], 4 | <%_ } _%> 5 | <%_ if(template === 'react'|| template === 'react-swc'){ _%> 6 | root: true, 7 | env: { browser: true, es2020: true }, 8 | extends: [ 9 | '@quiteer/eslint-config', 10 | 'plugin:react-hooks/recommended' 11 | ], 12 | ignorePatterns: ['dist'], 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react-refresh/only-export-components': [ 16 | 'warn', 17 | { allowConstantExport: true } 18 | ] 19 | } 20 | <%_ } _%> 21 | } 22 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/.npmrc.ejs: -------------------------------------------------------------------------------- 1 | <%_ if(isRegistry){ _%> 2 | # 一些镜像配置 3 | registry=https://registry.npmmirror.com 4 | electron_mirror=https://cdn.npmmirror.com/binaries/electron/ 5 | electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/ 6 | # sqlite3_mirror=https://cdn.npmmirror.com/binaries/sqlite3/ 7 | # node_sqlite3_binary_host_mirror=https://npmmirror.com/mirrors/sqlite3/ 8 | <%_ } _%> 9 | 10 | <%_ if(pkgManager === 'pnpm'){ _%> 11 | # https://pnpm.io/zh/npmrc#strict-peer-dependencies 12 | strict-peer-dependencies=false 13 | # https://pnpm.io/zh/cli/run#shell-emulator 14 | shell-emulator=true 15 | # https://pnpm.io/zh/npmrc#auto-install-peers 16 | auto-install-peers=false 17 | <%_ } _%> 18 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "prettier.enable": false, 3 | "editor.formatOnSave": false, 4 | "editor.codeActionsOnSave": { 5 | "source.fixAll.eslint": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 quiteer 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 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 |

electronup-project

4 |

使用 electronup cli 驱动。

5 |
6 | 7 | # [electronup](https://github.com/QuiteerJs/electronup) 8 | [![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE) ![](https://img.shields.io/github/stars/QuiteerJs/electronup) ![](https://img.shields.io/github/forks/QuiteerJs/electronup) 9 | 10 | > electronup 是一个集成 Vite4.x、tsup6.x、electron-builder24.x 的桌面端构建工具,一个配置文件完成多环境多目标的构建包。 11 | 12 | ## 文档地址 13 | 14 | 文档地址 :https://quiteerjs.github.io/electronup 15 | 16 | 17 | ## 特性 18 | 19 | - **多框架支持** : 使用 `create-electronup` 询问式创建项目模板 , 内置 `vue3` , `react` ,`solid` 等项目模板。 20 | - **Vite + tsup** : 双进程热更新 , 快速开发(主进程代码修改会触发软件重启)。 21 | - **统一的环境变量** : `dotenv` 加载 , 构建时注入 , 双进程拥有相同的环境变量。 22 | - **模式构建** : 默认识别当前代码运行的平台输出打包程序 。 23 | - **可选构建功能提示** : 你将获得可选范围内支持的功能提示 , 选项式自定义构建输出。 24 | - **TypeScript** : 应用程序级 `JavaScript` 的语言。 25 | - **集中管理路径** : 解决双进程资源路径的问题。 26 | - **预置配置** : 内置了很多可以覆盖的构建工具配置。 27 | - **单文件配置** : 只需一个 **electronup.config.ts** 即可管理项目的运行构建。 28 | - **多插件** : 作者会继续开发更多无副作用的独立插件,如:创建窗口,预加载,ipc通信,更新等等。 29 | 30 | ## 声明 31 | 32 | 前提条件 33 | > 熟悉命令行 34 | > 已安装 18 或更高版本的 Node.js 35 | 36 | 37 | 因为使用了 tsup 构建主进程代码,所以该命令行及脚手架只支持 TypeScript ,不支持 JavaScript。 38 | 39 | 40 | ### 一些便携包的相关配置参考 41 | 42 | - `electronup` 43 | 44 | https://www.npmjs.com/package/electronup 45 | 46 | - `@quiteer/electron-ipc` 47 | 48 | https://www.npmjs.com/package/@quiteer/electron-ipc 49 | 50 | - `@quiteer/electron-preload` 51 | 52 | https://www.npmjs.com/package/@quiteer/electron-preload 53 | 54 | 如果你觉得这个项目对你有帮助,可以动动小手 `star` 一下 , 非常感谢!!! 55 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/_gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/electronup.config.ts.ejs: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { defineConfig } from 'electronup' 3 | 4 | <%- importer %> 5 | 6 | export default defineConfig((env) => { 7 | const srcDir = resolve(env.root, 'render') 8 | return { 9 | viteConfig: { 10 | plugins: [<%- initializer _%>], 11 | resolve: { 12 | alias: { 13 | '@': resolve(env.root, 'render') 14 | } 15 | } 16 | }, 17 | builderConfig: { 18 | win: { 19 | icon: 'public/icon.png', 20 | target: { 21 | target: 'nsis', 22 | arch: 'ia32' 23 | } 24 | } 25 | } 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/main/index.ts: -------------------------------------------------------------------------------- 1 | import { Ipc } from '@quiteer/electron-ipc' 2 | import preload from '@quiteer/electron-preload' 3 | import { BrowserWindow, app } from 'electron' 4 | import { Common } from './utils/common' 5 | 6 | app.whenReady().then(() => { 7 | Ipc.init() 8 | 9 | const win = new BrowserWindow({ 10 | height: 700, 11 | width: 800, 12 | webPreferences: { 13 | preload: preload as string 14 | } 15 | }) 16 | 17 | const child = new BrowserWindow({ 18 | parent: win, 19 | height: 730, 20 | width: 700, 21 | frame: false, 22 | show: false, 23 | webPreferences: { 24 | preload: preload as string 25 | } 26 | }) 27 | 28 | win.loadURL(Common.loadUrl) 29 | child.loadURL('https://freegpt.one/') 30 | 31 | win.webContents.openDevTools({ mode: 'right' }) 32 | win.once('ready-to-show', () => { 33 | setTimeout(() => { 34 | const [x, y] = win.getPosition() 35 | child.setPosition(x + 810, y + 1) 36 | // child.show() 37 | }, 1000) 38 | }) 39 | 40 | win.on('will-move', (event, newBounds) => { 41 | child.setPosition(newBounds.x + 810, newBounds.y + 1) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/main/utils/common.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { Is } from './is' 3 | 4 | export class Common { 5 | static get loadUrl() { 6 | const devUrl = `http://localhost:${process.env.RENDER_PORT}` 7 | const prodUrl = `file://${resolve(__dirname, 'index.html')}` 8 | return Is.dev ? devUrl : prodUrl 9 | } 10 | 11 | static get publicPath() { 12 | const dev = resolve(__dirname, '..', '..', 'public') 13 | const prod = __dirname 14 | return Is.dev ? dev : prod 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/main/utils/is.ts: -------------------------------------------------------------------------------- 1 | import { arch, platform } from 'process' 2 | 3 | export class Is { 4 | static get win() { 5 | return platform === 'win32' 6 | } 7 | 8 | static get mac() { 9 | return platform === 'darwin' 10 | } 11 | 12 | static get linux() { 13 | return platform === 'linux' 14 | } 15 | 16 | static get ia32() { 17 | return arch === 'ia32' 18 | } 19 | 20 | static get x64() { 21 | return arch === 'x64' 22 | } 23 | 24 | static get dev() { 25 | return process.env.NODE_ENV === 'development' 26 | } 27 | 28 | static get prod() { 29 | return process.env.NODE_ENV === 'production' 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/package.json.ejs: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= name %>", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "main": "dist/resource/electron.js", 6 | "scripts": { 7 | "dev": "electronup --no-minify", 8 | "build": "electronup build", 9 | "dir": "electronup build --dir --no-asar --no-minify", 10 | <%_ if(template === 'vue'){ _%> 11 | "typecheck": "vue-tsc --noEmit --skipLibCheck", 12 | <%_ }else{ -%> 13 | <%_ } _%> 14 | "lint": "eslint .", 15 | "postinstall": "electron-builder install-app-deps" 16 | }, 17 | "dependencies": { 18 | "@quiteer/electron-ipc": "^2.0.4", 19 | "@quiteer/electron-preload": "^0.0.10"<%_ if(dependencies.length !== 0){ _%>,<%_ } %> 20 | <%_ dependencies.forEach(function (name,index) { _%> 21 | "<%= name[0] %>": "<%= name[1] %>"<%_ if(index !== dependencies.length - 1){ _%>,<%_ } %> 22 | <%_ }) _%> 23 | }, 24 | "devDependencies": { 25 | "@quiteer/eslint-config": "^0.0.3", 26 | "@types/node": "^20.4.6", 27 | "electron": "22.3.6", 28 | <%_ if(pkgManager === 'pnpm'){ _%> 29 | "electron-builder": "^24.6.3", 30 | <%_ }else{ -%> 31 | <%_ } _%> 32 | "electronup": "^0.1.1", 33 | "eslint": "^8.43.0", 34 | "sass": "^1.65.1", 35 | "typescript": "^5.1.6"<%_ if(devDependencies.length !== 0){ _%>,<%_ } %> 36 | <%_ devDependencies.forEach(function (name,index) { _%> 37 | "<%= name[0] %>": "<%= name[1] %>"<%_ if(index !== devDependencies.length - 1){ _%>,<%_ } %> 38 | <%_ }) _%> 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/packages/create-electronup/template/base/public/icon.png -------------------------------------------------------------------------------- /packages/create-electronup/template/base/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/tsconfig.json.ejs: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "<%= jsx %>", 16 | <%_ if(template === 'solid'){ _%> 17 | "jsxImportSource": "solid-js", 18 | <%_ }else{ -%> 19 | <%_ } _%> 20 | 21 | /* Linting */ 22 | "strict": true, 23 | "noUnusedLocals": true, 24 | "noUnusedParameters": true, 25 | "noFallthroughCasesInSwitch": true 26 | }, 27 | "include": ["render", "typings"], 28 | "references": [{ "path": "./tsconfig.node.json" }] 29 | } 30 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["electronup.config.ts", "main", "typings/*"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/typings/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare interface ImportMetaEnv { 4 | readonly VITE_MODE_TEXT: string 5 | readonly VITE_HELLO: string 6 | } 7 | 8 | declare interface ImportMeta { 9 | readonly env: ImportMetaEnv 10 | } 11 | 12 | // 主进程环境变量 13 | declare namespace NodeJS { 14 | export interface ProcessEnv { 15 | readonly NODE_ENV: 'development' | 'production' 16 | readonly RENDER_PORT?: string 17 | readonly VITE_HELLO: string 18 | readonly VITE_MODE_TEXT: string 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/create-electronup/template/base/typings/global.d.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | $ipc: import('@quiteer/electron-preload').PreloadIpc & import('@quiteer/electron-ipc/web').ExpandPreloadIpc 3 | $clipboard: import('@quiteer/electron-preload').PreloadClipboard 4 | $webFrame: import('@quiteer/electron-preload').PreloadWebFrame 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/create-electronup/template/react/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /packages/create-electronup/template/react/App.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import reactLogo from './assets/react.svg' 3 | import viteLogo from '/vite.svg' 4 | import './App.css' 5 | 6 | function App() { 7 | const [count, setCount] = useState(0) 8 | 9 | return ( 10 | <> 11 |
12 | 13 | Vite logo 14 | 15 | 16 | React logo 17 | 18 |
19 |

Vite + React

20 |
21 | 24 |

25 | Edit src/App.tsx and save to test HMR 26 |

27 |
28 |

29 | Click on the Vite and React logos to learn more 30 |

31 | 32 | ) 33 | } 34 | 35 | export default App 36 | -------------------------------------------------------------------------------- /packages/create-electronup/template/react/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | a:hover { 23 | color: #535bf2; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | display: flex; 29 | place-items: center; 30 | min-width: 320px; 31 | min-height: 100vh; 32 | } 33 | 34 | h1 { 35 | font-size: 3.2em; 36 | line-height: 1.1; 37 | } 38 | 39 | button { 40 | border-radius: 8px; 41 | border: 1px solid transparent; 42 | padding: 0.6em 1.2em; 43 | font-size: 1em; 44 | font-weight: 500; 45 | font-family: inherit; 46 | background-color: #1a1a1a; 47 | cursor: pointer; 48 | transition: border-color 0.25s; 49 | } 50 | button:hover { 51 | border-color: #646cff; 52 | } 53 | button:focus, 54 | button:focus-visible { 55 | outline: 4px auto -webkit-focus-ring-color; 56 | } 57 | 58 | @media (prefers-color-scheme: light) { 59 | :root { 60 | color: #213547; 61 | background-color: #ffffff; 62 | } 63 | a:hover { 64 | color: #747bff; 65 | } 66 | button { 67 | background-color: #f9f9f9; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /packages/create-electronup/template/react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | electronup-react 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/create-electronup/template/react/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import './index.css' 5 | 6 | 7 | ReactDOM.createRoot(document.getElementById('root')!).render( 8 | 9 | 10 | 11 | ) 12 | -------------------------------------------------------------------------------- /packages/create-electronup/template/solid/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.solid:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | .card { 22 | padding: 2em; 23 | } 24 | 25 | .read-the-docs { 26 | color: #888; 27 | } 28 | -------------------------------------------------------------------------------- /packages/create-electronup/template/solid/App.tsx: -------------------------------------------------------------------------------- 1 | import { createSignal } from 'solid-js' 2 | import solidLogo from './assets/solid.svg' 3 | import viteLogo from '/vite.svg' 4 | import './App.css' 5 | 6 | function App() { 7 | const [count, setCount] = createSignal(0) 8 | 9 | return ( 10 | <> 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

Vite + Solid

20 |
21 | 24 |

25 | Edit src/App.tsx and save to test HMR 26 |

27 |
28 |

29 | Click on the Vite and Solid logos to learn more 30 |

31 | 32 | ) 33 | } 34 | 35 | export default App 36 | -------------------------------------------------------------------------------- /packages/create-electronup/template/solid/assets/solid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/create-electronup/template/solid/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | a:hover { 23 | color: #535bf2; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | display: flex; 29 | place-items: center; 30 | min-width: 320px; 31 | min-height: 100vh; 32 | } 33 | 34 | h1 { 35 | font-size: 3.2em; 36 | line-height: 1.1; 37 | } 38 | 39 | button { 40 | border-radius: 8px; 41 | border: 1px solid transparent; 42 | padding: 0.6em 1.2em; 43 | font-size: 1em; 44 | font-weight: 500; 45 | font-family: inherit; 46 | background-color: #1a1a1a; 47 | cursor: pointer; 48 | transition: border-color 0.25s; 49 | } 50 | button:hover { 51 | border-color: #646cff; 52 | } 53 | button:focus, 54 | button:focus-visible { 55 | outline: 4px auto -webkit-focus-ring-color; 56 | } 57 | 58 | @media (prefers-color-scheme: light) { 59 | :root { 60 | color: #213547; 61 | background-color: #ffffff; 62 | } 63 | a:hover { 64 | color: #747bff; 65 | } 66 | button { 67 | background-color: #f9f9f9; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /packages/create-electronup/template/solid/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | electronup-solid 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/create-electronup/template/solid/index.tsx: -------------------------------------------------------------------------------- 1 | /* @refresh reload */ 2 | import { render } from 'solid-js/web' 3 | 4 | import './index.css' 5 | import App from './App' 6 | 7 | const root = document.getElementById('root') 8 | 9 | render(() => , root!) 10 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vanilla/counter.ts: -------------------------------------------------------------------------------- 1 | export function setupCounter(element: HTMLButtonElement) { 2 | let counter = 0 3 | const setCounter = (count: number) => { 4 | counter = count 5 | element.innerHTML = `count is ${counter}` 6 | } 7 | element.addEventListener('click', () => setCounter(counter + 1)) 8 | setCounter(0) 9 | } 10 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vanilla/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | electronup-vanilla 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vanilla/main.ts: -------------------------------------------------------------------------------- 1 | import './style.css' 2 | import typescriptLogo from './typescript.svg' 3 | import viteLogo from '/vite.svg' 4 | import { setupCounter } from './counter' 5 | 6 | document.querySelector('#app')!.innerHTML = ` 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |

Vite + TypeScript

15 |
16 | 17 |
18 |

19 | Click on the Vite and TypeScript logos to learn more 20 |

21 |
22 | ` 23 | 24 | setupCounter(document.querySelector('#counter')!) 25 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vanilla/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | a:hover { 23 | color: #535bf2; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | display: flex; 29 | place-items: center; 30 | min-width: 320px; 31 | min-height: 100vh; 32 | } 33 | 34 | h1 { 35 | font-size: 3.2em; 36 | line-height: 1.1; 37 | } 38 | 39 | #app { 40 | max-width: 1280px; 41 | margin: 0 auto; 42 | padding: 2rem; 43 | text-align: center; 44 | } 45 | 46 | .logo { 47 | height: 6em; 48 | padding: 1.5em; 49 | will-change: filter; 50 | transition: filter 300ms; 51 | } 52 | .logo:hover { 53 | filter: drop-shadow(0 0 2em #646cffaa); 54 | } 55 | .logo.vanilla:hover { 56 | filter: drop-shadow(0 0 2em #3178c6aa); 57 | } 58 | 59 | .card { 60 | padding: 2em; 61 | } 62 | 63 | .read-the-docs { 64 | color: #888; 65 | } 66 | 67 | button { 68 | border-radius: 8px; 69 | border: 1px solid transparent; 70 | padding: 0.6em 1.2em; 71 | font-size: 1em; 72 | font-weight: 500; 73 | font-family: inherit; 74 | background-color: #1a1a1a; 75 | cursor: pointer; 76 | transition: border-color 0.25s; 77 | } 78 | button:hover { 79 | border-color: #646cff; 80 | } 81 | button:focus, 82 | button:focus-visible { 83 | outline: 4px auto -webkit-focus-ring-color; 84 | } 85 | 86 | @media (prefers-color-scheme: light) { 87 | :root { 88 | color: #213547; 89 | background-color: #ffffff; 90 | } 91 | a:hover { 92 | color: #747bff; 93 | } 94 | button { 95 | background-color: #f9f9f9; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vanilla/typescript.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vue/App.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 40 | 41 | 90 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vue/assets/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/packages/create-electronup/template/vue/assets/avatar.png -------------------------------------------------------------------------------- /packages/create-electronup/template/vue/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | electronup-vue 8 | 9 | 10 |
11 |
12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vue/loading/index.vue: -------------------------------------------------------------------------------- 1 | 58 | 59 | 62 | 63 | 73 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vue/main.ts: -------------------------------------------------------------------------------- 1 | import './styles/style.css' 2 | import { createPinia } from 'pinia' 3 | import { createApp } from 'vue' 4 | import App from './App.vue' 5 | import Loading from './loading/index.vue' 6 | 7 | createApp(Loading).mount('#app-loading') 8 | 9 | console.log(import.meta.env) 10 | 11 | setTimeout(() => { 12 | const app = createApp(App) 13 | app.use(createPinia()) 14 | .mount('#app') 15 | }, 2000) 16 | 17 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vue/store/index.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | 3 | interface DemoState { 4 | demo: { 5 | name: string 6 | } 7 | } 8 | 9 | export const useDemoStore = defineStore('demo', { 10 | state: (): DemoState => ({ 11 | demo: { 12 | name: 'demo' 13 | } 14 | }), 15 | getters: { 16 | name: (state): string => state.demo.name 17 | }, 18 | actions: { 19 | actionDemo(data: string) { 20 | this.demo.name = data 21 | } 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /packages/create-electronup/template/vue/styles/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | 5 | #app { 6 | max-width: 1280px; 7 | margin: 0 auto; 8 | padding: 2rem; 9 | text-align: center; 10 | } 11 | 12 | #app-loading{ 13 | position:absolut; 14 | top:0; 15 | left:0; 16 | } 17 | -------------------------------------------------------------------------------- /packages/create-electronup/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "build.config.ts", 4 | "src", 5 | "__tests__" 6 | ], 7 | "compilerOptions": { 8 | "outDir": "dist", 9 | "target": "ES2020", 10 | "module": "ES2020", 11 | "moduleResolution": "bundler", 12 | "strict": true, 13 | "skipLibCheck": true, 14 | "declaration": false, 15 | "sourceMap": false, 16 | "noUnusedLocals": true, 17 | "esModuleInterop": true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/electronup/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 安静 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 | -------------------------------------------------------------------------------- /packages/electronup/README.md: -------------------------------------------------------------------------------- 1 | # electronup 2 | [![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE) ![](https://img.shields.io/github/stars/QuiteerJs/electronup) ![](https://img.shields.io/github/forks/QuiteerJs/electronup) 3 | 4 | > electronup 是一个集成 Vite4.x、tsup6.x、electron-builder24.x 的桌面端构建工具,一个配置文件完成多环境多目标的构建包。 5 | 6 | ## 文档地址 7 | 8 | 文档地址 :https://quiteerjs.github.io/electronup 9 | 10 | ## 安装 11 | 12 | ```bash 13 | npm install electronup -D 14 | ``` 15 | 16 | ```bash 17 | yarn add electronup -D 18 | ``` 19 | 20 | ```bash 21 | pnpm add electronup -D 22 | ``` 23 | 24 | ## 特性 25 | 26 | - **多框架支持** : 使用 `create-electronup` 询问式创建项目模板 , 内置 `vue3` , `react` ,`solid` 等项目模板。 27 | - **Vite + tsup** : 双进程热更新 , 快速开发(主进程代码修改会触发软件重启)。 28 | - **统一的环境变量** : `dotenv` 加载 , 构建时注入 , 双进程拥有相同的环境变量。 29 | - **模式构建** : 默认识别当前代码运行的平台输出打包程序 。 30 | - **可选构建功能提示** : 你将获得可选范围内支持的功能提示 , 选项式自定义构建输出。 31 | - **TypeScript** : 应用程序级 `JavaScript` 的语言。 32 | - **集中管理路径** : 解决双进程资源路径的问题。 33 | - **预置配置** : 内置了很多可以覆盖的构建工具配置。 34 | - **单文件配置** : 只需一个 **electronup.config.ts** 即可管理项目的运行构建。 35 | - **多插件** : 作者会继续开发更多无副作用的独立插件,如:创建窗口,预加载,ipc通信,更新等等。 36 | 37 | ## 声明 38 | 39 | 前提条件 40 | > 熟悉命令行 41 | > 已安装 18.0 或更高版本的 Node.js 42 | 43 | 44 | 因为使用了 tsup 构建主进程代码,所以该命令行及脚手架只支持 TypeScript ,不支持 JavaScript。 45 | 46 | ## 示例 47 | 48 | > https://github.com/QuiteerJs/electronup/tree/main/playground/electronup-test 49 | -------------------------------------------------------------------------------- /packages/electronup/cli.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { resolve } from 'node:path' 3 | import fs from 'node:fs' 4 | import { cac } from 'cac' 5 | import { version } from './package.json' 6 | import { getConfig } from './transform' 7 | import { DefaultDirs, store } from './utils' 8 | import { build, watch } from './runner' 9 | 10 | interface Options { 11 | m?: string 12 | mode?: string 13 | minify: boolean 14 | } 15 | 16 | interface DevOptions extends Options { 17 | p?: number 18 | port?: number 19 | } 20 | 21 | interface BuildOptions extends Options { 22 | o?: true 23 | option?: true 24 | win?: true | 'ia32' | 'x64' 25 | mac?: true | 'x64' | 'arm64' | 'universal' 26 | linux?: true 27 | dir?: true 28 | asar: boolean 29 | } 30 | 31 | const cli = cac('electronup') 32 | 33 | cli.option('-m , --mode ', '[development | production | test | staging | ...] 环境模式 ') 34 | cli.option('--no-minify', '使主进程和渲染进程代码不进行压缩 ') 35 | 36 | cli 37 | .command('[config-file]', '等同于electronup dev ,启动开发环境热更新') // default command 38 | .alias('dev') 39 | .option('-p , --port ', '[number] 渲染进程的端口号 ,如果占用会切换非占用的端口 ') 40 | .action(async (configFile: undefined | string, options: DevOptions) => { 41 | const { mode, port, minify } = options 42 | 43 | const option = await getConfig(configFile) 44 | 45 | emptyDir(resolve(store.root, option.resourceDir || DefaultDirs.resourceDir)) 46 | 47 | store.command = 'serve' 48 | store.mode = (mode || 'development') 49 | store.port = (port || 8090) 50 | store.minify = !!minify 51 | 52 | watch(option) 53 | }) 54 | 55 | cli 56 | .command('build [root]', '开始构建服务 , 若不指定平台则默认当前操作系统的架构类型') 57 | .option('-o , --option', '自定义 , 自定义构建选项 ') 58 | .option('--dir', '只生成目录') 59 | .option('--no-asar', 'asar false') 60 | .option('--win [arch]', '[ia32 | x64] 构建 win 平台下的输出包 , 不指定架构则输出 ia32 和 x64的两个包') 61 | .option('--mac [arch]', '[x64 | arm64 | universal] 构建 mac 平台下的输出包 , 若不指定架构则默认当前操作系统的架构类型') 62 | .option('--linux', '[x64 | arm64 | armv7l] 构建 linux 平台下的输出包 , 若不指定架构则默认当前操作系统的架构类型') 63 | .action(async (configFile: undefined | string, options: BuildOptions) => { 64 | const { 65 | mode, minify, option, 66 | win, mac, linux, 67 | dir, asar 68 | } = options 69 | 70 | const configOption = await getConfig(configFile) 71 | 72 | emptyDir(resolve(store.root, configOption.resourceDir || DefaultDirs.resourceDir)) 73 | emptyDir(resolve(store.root, configOption.outDir || DefaultDirs.outDir)) 74 | 75 | store.command = 'build' 76 | store.mode = (mode || 'production') 77 | store.minify = minify 78 | store.option = !!option 79 | store.dir = dir ? 'dir' : null 80 | store.asar = asar 81 | store.win = win 82 | store.mac = mac 83 | store.linux = linux 84 | 85 | build(configOption) 86 | }) 87 | 88 | cli.help() 89 | cli.version(version) 90 | cli.parse() 91 | 92 | function emptyDir(dir: string) { 93 | if (!fs.existsSync(dir)) 94 | return 95 | 96 | for (const file of fs.readdirSync(dir)) 97 | fs.rmSync(resolve(dir, file), { recursive: true, force: true }) 98 | } 99 | -------------------------------------------------------------------------------- /packages/electronup/configs/builder.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import type { CliOptions } from 'electron-builder' 3 | import { readJSON } from 'fs-extra' 4 | import type { BuilderConfig, ElectronupConfig } from '../typings/electronup' 5 | import { DefaultDirs, store } from '../utils' 6 | 7 | /** 8 | * CliOptions 配置直接 9 | */ 10 | 11 | // const allTargetFormats = ['7z', 'zip', 'tar.xz', 'tar.lz', 'tar.gz', 'tar.bz2', 'dir'] 12 | 13 | // const winTargetFormats = ['nsis', 'nsis-web', 'portable', 'AppX', ...allTargetFormats] 14 | // const winTargets = Platform.WINDOWS.createTarget(winTargetFormats, Arch.ia32, Arch.x64) 15 | 16 | // const macTargetFormats = ['dmg', 'pkg', 'mas', 'mas-dev', ...allTargetFormats] 17 | // const macTargets = Platform.MAC.createTarget(macTargetFormats, Arch.arm64, Arch.x64, Arch.universal) 18 | 19 | // const linuxTargetFormats = ['AppImage', 'snap', 'debian', 'rpm', 'freebsd', 'pacman', 'p5p', 'apk', ...allTargetFormats] 20 | // const linuxTargets = Platform.LINUX.createTarget(linuxTargetFormats, Arch.armv7l, Arch.arm64, Arch.x64) 21 | 22 | export async function getBuilderConfig(config: BuilderConfig, allConfig: ElectronupConfig): Promise { 23 | const packages = await readJSON(resolve(store.root, 'package.json')) 24 | 25 | const defaultConfig: CliOptions['config'] = { 26 | asar: store.asar, 27 | appId: 'org.quiteer.electronup', 28 | productName: packages.name, 29 | protocols: { 30 | name: packages.name, 31 | schemes: ['deeplink'] 32 | }, 33 | nsis: { 34 | oneClick: false, 35 | language: '2052', 36 | perMachine: true, 37 | allowElevation: true, 38 | allowToChangeInstallationDirectory: true, 39 | runAfterFinish: true, 40 | createDesktopShortcut: true, 41 | createStartMenuShortcut: true, 42 | artifactName: `${packages.name} \${arch} Setup ${packages.version}.\${ext}` 43 | }, 44 | files: [`${allConfig.resourceDir || DefaultDirs.resourceDir}/**/*`], 45 | extraFiles: [allConfig.libDir || DefaultDirs.libDir], 46 | directories: { 47 | output: allConfig.outDir || config.directories?.output || DefaultDirs.outDir 48 | }, 49 | ...config 50 | } 51 | 52 | return { targets: store.targets, config: defaultConfig } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /packages/electronup/configs/electronup.ts: -------------------------------------------------------------------------------- 1 | import type { UserConfig } from 'vite' 2 | import type { Options } from 'tsup' 3 | import type { CliOptions } from 'electron-builder' 4 | 5 | import { store } from '../utils' 6 | import type { ElectronupConfig } from '../typings/electronup' 7 | import { getBuilderConfig } from './builder' 8 | import { getTsupConfig } from './tsup' 9 | import { getViteConfig } from './vite' 10 | 11 | interface InitConfig extends Omit { 12 | vite: UserConfig 13 | tsup: Options 14 | preload?: Options | Options[] 15 | builder?: CliOptions 16 | } 17 | 18 | export async function getElectronupConfig(config: ElectronupConfig) { 19 | const { viteConfig, tsupConfig, preloadTsup, builderConfig, ...dirConfig } = config 20 | 21 | const vite = getViteConfig(viteConfig || {}, config) 22 | const tsup = getTsupConfig(tsupConfig || {}, config) 23 | 24 | const initConfig: InitConfig = { vite, tsup } 25 | 26 | if (store.command === 'build') { 27 | const builder = await getBuilderConfig(builderConfig, config) 28 | initConfig.builder = builder 29 | } 30 | 31 | preloadTsup && (initConfig.preload = preloadTsup) 32 | 33 | return { ...dirConfig, ...initConfig } 34 | } 35 | -------------------------------------------------------------------------------- /packages/electronup/configs/vite.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import type { UserConfig } from 'vite' 3 | import type { ElectronupConfig, ViteConfig } from '../typings/electronup' 4 | import { DefaultDirs, store } from '../utils' 5 | 6 | export function getViteConfig(config: ViteConfig, allConfig: ElectronupConfig) { 7 | const { root, minify } = store 8 | 9 | const defaultConfig: UserConfig = { 10 | base: './', 11 | ...config, 12 | build: { 13 | ...config?.build, 14 | minify: minify && 'esbuild', 15 | outDir: resolve(root, allConfig.resourceDir || DefaultDirs.resourceDir) 16 | }, 17 | root: allConfig.renderDir || DefaultDirs.renderDir, 18 | publicDir: resolve(root, allConfig.publicDir || DefaultDirs.publicDir) 19 | } 20 | 21 | return defaultConfig 22 | } 23 | 24 | -------------------------------------------------------------------------------- /packages/electronup/index.ts: -------------------------------------------------------------------------------- 1 | import type { ElectronupConfig, ElectronupConfigExport, ElectronupConfigFnObject } from './typings/electronup' 2 | 3 | export function defineConfig(config: ElectronupConfig): ElectronupConfig 4 | 5 | export function defineConfig(config: Promise): Promise 6 | 7 | export function defineConfig(config: ElectronupConfigFnObject): ElectronupConfigFnObject 8 | 9 | export function defineConfig(config: ElectronupConfigExport): ElectronupConfigExport 10 | 11 | export function defineConfig(config: ElectronupConfigExport): ElectronupConfigExport { 12 | return config 13 | } 14 | 15 | export type { ElectronupConfig, ViteConfig, ConfigEnv, TsupConfig, BuilderConfig } from './typings/electronup' 16 | -------------------------------------------------------------------------------- /packages/electronup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electronup", 3 | "version": "0.1.1", 4 | "description": "融合构建 electron 应用需要的构建工具,保留原有配置习惯的命令行工具 ", 5 | "author": "quiteer", 6 | "license": "MIT", 7 | "homepage": "https://github.com/QuiteerJs/electronup#readme", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/QuiteerJs/electronup.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/QuiteerJs/electronup/issues" 14 | }, 15 | "keywords": [ 16 | "vite", 17 | "tsup", 18 | "electron-builder", 19 | "electron" 20 | ], 21 | "publishConfig": { 22 | "access": "public", 23 | "registry": "https://registry.npmjs.org/" 24 | }, 25 | "main": "dist/client/index.js", 26 | "module": "dist/client/index.mjs", 27 | "types": "dist/client/index.d.ts", 28 | "bin": { 29 | "electronup": "dist/bin/electronup.js" 30 | }, 31 | "files": [ 32 | "dist" 33 | ], 34 | "scripts": { 35 | "dev": "tsup --watch", 36 | "build": "tsup", 37 | "update-version": "bumpp package.json" 38 | }, 39 | "peerDependencies": { 40 | "@types/node": ">= 18", 41 | "node": ">= 18", 42 | "vue": ">= 3" 43 | }, 44 | "dependencies": { 45 | "@quiteer/parser-config": "^1.0.3", 46 | "@types/prompts": "^2.4.4", 47 | "cac": "^6.7.14", 48 | "dotenv": "^16.3.1", 49 | "electron": "^22.3.6", 50 | "electron-builder": "^24.9.1", 51 | "fs-extra": "^11.2.0", 52 | "kolorist": "^1.8.0", 53 | "portfinder": "^1.0.32", 54 | "prompts": "^2.4.2", 55 | "tsup": "^7.3.0", 56 | "vite": "^4.5.1", 57 | "yaml": "^2.3.4" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /packages/electronup/runner/index.ts: -------------------------------------------------------------------------------- 1 | export { watch } from './watch' 2 | export { build } from './build' 3 | -------------------------------------------------------------------------------- /packages/electronup/runner/watch.ts: -------------------------------------------------------------------------------- 1 | import { getPortPromise } from 'portfinder' 2 | import { createServer } from 'vite' 3 | import { build } from 'tsup' 4 | import type { ElectronupConfig } from '../typings/electronup' 5 | import { electronupConfig } from '../transform' 6 | import { store } from '../utils' 7 | 8 | export async function watch(options: ElectronupConfig) { 9 | const p = await getPortPromise({ 10 | port: Number(store.port) 11 | }) 12 | 13 | store.port = p 14 | 15 | const initConfig = await electronupConfig(options) 16 | 17 | const viteDevServer = await createServer({ configFile: false, ...initConfig.vite }) 18 | 19 | viteDevServer.listen(p).then(viteDevServer.printUrls) 20 | 21 | build(initConfig.tsup) 22 | } 23 | 24 | -------------------------------------------------------------------------------- /packages/electronup/transform/getConfig.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'path' 2 | import { pathExists } from 'fs-extra' 3 | import { parserConfig } from '@quiteer/parser-config' 4 | import type { ElectronupConfig } from '../typings/electronup' 5 | import { store } from '../utils' 6 | 7 | const NOT_FOUND = '找不到 electronup.config.ts | electronup.config.js | electronup.config.json , 请在根目录下添加配置文件 , 或显式的指定配置文件路径(相对于根目录)' 8 | const PARSING_FAILED = '找到了配置文件,但解析配置文件失败!' 9 | 10 | const configPath = async (filePath: string | undefined) => { 11 | const { root } = store 12 | 13 | if (filePath) 14 | return join(root, filePath) 15 | 16 | const configList = ['ts', 'mjs', 'cjs', 'js'].map(suffix => `${join(root, 'electronup.config')}.${suffix}`) 17 | 18 | const index = (await Promise.all(configList.map(path => pathExists(path)))).findIndex(flag => flag) 19 | 20 | if (index > -1) 21 | return configList[index] 22 | 23 | throw new Error(NOT_FOUND) 24 | } 25 | 26 | export const getConfig = async (filePath: string | undefined): Promise => { 27 | const path = await configPath(filePath) 28 | 29 | try { 30 | const option: ElectronupConfig = await parserConfig(path, 'electronup.config') 31 | return option 32 | } 33 | catch (error) { 34 | console.error('error :>> ', error) 35 | throw new Error(PARSING_FAILED) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/electronup/transform/getExportConfig.ts: -------------------------------------------------------------------------------- 1 | import type { ElectronupConfig, ElectronupConfigExport, ElectronupConfigFn } from '../typings/electronup' 2 | import { getElectronupConfig } from '../configs/electronup' 3 | import { store } from '../utils' 4 | 5 | /** 6 | * Description 解析用户自定义配置··· 7 | * @param {any} config:ElectronupConfigExport 8 | * @returns {any} 9 | */ 10 | const exportElectronupConfig = async (config: ElectronupConfigExport): Promise => { 11 | const typeStr = typeof config 12 | 13 | if (typeStr === 'function') { 14 | const option = await (config as ElectronupConfigFn)({ command: store.command, root: store.root }) 15 | return option 16 | } 17 | 18 | if (typeStr === 'object') 19 | return config as ElectronupConfig 20 | 21 | throw new Error('electronup 配置错误,解析失败!') 22 | } 23 | 24 | export const electronupConfig = async (config: ElectronupConfigExport) => getElectronupConfig(await exportElectronupConfig(config)) 25 | -------------------------------------------------------------------------------- /packages/electronup/transform/index.ts: -------------------------------------------------------------------------------- 1 | export { getConfig } from './getConfig' 2 | export { electronupConfig } from './getExportConfig' 3 | -------------------------------------------------------------------------------- /packages/electronup/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quiteer/ts-config/tsconfig.node.json", 3 | "include": [ 4 | "src/*", 5 | "package.json" 6 | ], 7 | "compilerOptions": { 8 | "strict": true, // 开启所有严格的类型检查 9 | "strictPropertyInitialization": false, // 类的实例属性必须初始化 10 | "resolveJsonModule": true, 11 | "esModuleInterop": true, // 允许export=导出,由import from 导入 12 | "declaration": false, // 生成声明文件,开启后会自动生成声明文件 13 | "module": "esnext", // 生成代码的模板标准 14 | "target": "esnext", // 目标语言的版本 15 | "moduleResolution": "node", // 模块解析策略,ts默认用node的解析策略,即相对的方式导入 16 | "allowSyntheticDefaultImports": true, 17 | "emitDecoratorMetadata": false, 18 | "lib": ["ESNext"], 19 | "experimentalDecorators": true, 20 | "baseUrl": ".", 21 | "isolatedModules": false, 22 | "ignoreDeprecations": "5.0", 23 | "paths": { }, 24 | "typeRoots": ["node_modules/@types"] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/electronup/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from 'tsup' 2 | import { defineConfig } from 'tsup' 3 | 4 | const config: Options = { 5 | splitting: false, 6 | minify: false, 7 | clean: true 8 | } 9 | 10 | export default defineConfig(() => [ 11 | { 12 | ...config, 13 | name: 'electronup-api', 14 | outDir: 'dist/client', 15 | entry: ['index.ts'], 16 | format: ['esm', 'cjs'], 17 | dts: true 18 | }, 19 | { 20 | ...config, 21 | name: 'electronup-cli', 22 | outDir: 'dist/bin', 23 | format: 'cjs', 24 | entry: { electronup: 'cli.ts' } 25 | } 26 | ]) 27 | -------------------------------------------------------------------------------- /packages/electronup/typings/electronup.d.ts: -------------------------------------------------------------------------------- 1 | 2 | import type { Configuration } from 'electron-builder'; 3 | import type { UserConfig } from 'vite'; 4 | import type { Options } from 'tsup' 5 | 6 | export interface ViteConfig extends Omit { } 7 | 8 | export interface TsupConfig { 9 | external?: (string | RegExp)[]; 10 | noExternal?: (string | RegExp)[]; 11 | } 12 | 13 | export interface BuilderConfig extends Configuration { } 14 | 15 | export interface ElectronupConfig { 16 | viteConfig?: ViteConfig 17 | tsupConfig?: TsupConfig 18 | preloadTsup?: Options | Options[] 19 | builderConfig: BuilderConfig 20 | 21 | /** 22 | * 渲染进程入口目录 23 | * @default 'render' 24 | */ 25 | renderDir?: string 26 | 27 | /** 28 | * 主进程入口目录 29 | * @default 'main' 30 | */ 31 | mainDir?: string 32 | 33 | /** 34 | * 静态资源目录 35 | * @default 'public' 36 | */ 37 | publicDir?: string 38 | 39 | /** 40 | * 动态库目录 41 | * @default 'lib' 42 | */ 43 | libDir?: string 44 | 45 | /** 46 | * 资源构建输出目录 47 | * @default 'dist' 48 | */ 49 | resourceDir?: string 50 | 51 | /** 52 | * electron-builder 输出目录 53 | * @default 'out' 54 | */ 55 | outDir?: string 56 | } 57 | 58 | export interface ConfigEnv { 59 | command: 'build' | 'serve' 60 | root: string 61 | } 62 | 63 | export type ElectronupConfigFnObject = (env: ConfigEnv) => ElectronupConfig 64 | export type ElectronupConfigFnPromise = (env: ConfigEnv) => Promise 65 | export type ElectronupConfigFn = (env: ConfigEnv) => ElectronupConfig | Promise 66 | 67 | export type ElectronupConfigExport = 68 | | ElectronupConfig 69 | | Promise 70 | | ElectronupConfigFnObject 71 | | ElectronupConfigFnPromise 72 | | ElectronupConfigFn 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /packages/electronup/utils/dirs.ts: -------------------------------------------------------------------------------- 1 | export const enum DefaultDirs { 2 | /* 渲染进程入口目录 */ 3 | renderDir = 'render', 4 | /* 主进程入口目录 */ 5 | mainDir = 'main', 6 | /* 静态资源目录 */ 7 | publicDir = 'public', 8 | /* 动态库目录 */ 9 | libDir = 'lib', 10 | /* 资源构建输出目录 */ 11 | resourceDir = 'dist/resource', 12 | /* electron-builder 输出目录 */ 13 | outDir = 'dist/out' 14 | } 15 | 16 | -------------------------------------------------------------------------------- /packages/electronup/utils/index.ts: -------------------------------------------------------------------------------- 1 | export { store } from './store' 2 | export { DefaultDirs } from './dirs' 3 | -------------------------------------------------------------------------------- /packages/electronup/utils/store.ts: -------------------------------------------------------------------------------- 1 | import type { Arch, Platform } from 'electron-builder' 2 | 3 | type Command = 'build' | 'serve' 4 | type Mode = 'development' | 'production' | 'test' | 'staging' | string 5 | 6 | class Store { 7 | static instance: Store 8 | 9 | command: Command 10 | config: string 11 | mode: Mode 12 | minify: boolean 13 | port?: number 14 | option: boolean 15 | win?: true | 'ia32' | 'x64' 16 | mac?: true | 'x64' | 'arm64' | 'universal' 17 | linux?: true | 'x64' | 'arm64' | 'armv7l' 18 | dir?: 'dir' | null 19 | asar?: boolean 20 | targets?: Map> 21 | 22 | static getInstance() { 23 | if (this.instance) 24 | return this.instance 25 | return (this.instance = new Store()) 26 | } 27 | 28 | get root() { 29 | return process.cwd() 30 | } 31 | 32 | get isWin() { 33 | return process.platform === 'win32' 34 | } 35 | 36 | get isMac() { 37 | return process.platform === 'darwin' 38 | } 39 | 40 | get isLinux() { 41 | return process.platform === 'linux' 42 | } 43 | 44 | get currentArch() { 45 | return process.arch 46 | } 47 | } 48 | 49 | export const store = Store.getInstance() 50 | -------------------------------------------------------------------------------- /playground/edit-config/electronup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'electronup' 2 | import vue from '@vitejs/plugin-vue' 3 | import react from '@vitejs/plugin-react' 4 | 5 | defineConfig({ 6 | viteConfig: { 7 | resolve: { 8 | alias: { 9 | '@': 'src' 10 | } 11 | }, 12 | build: { 13 | reportCompressedSize: false 14 | }, 15 | plugins: [vue(), react()] 16 | }, 17 | tsupConfig: { 18 | external: ['electron'] 19 | }, 20 | builderConfig: {} 21 | }) 22 | 23 | defineConfig(Promise.resolve({ 24 | viteConfig: { 25 | plugins: [vue(), react()] 26 | }, 27 | tsupConfig: { 28 | external: ['electron'] 29 | }, 30 | builderConfig: {} 31 | })) 32 | 33 | defineConfig(() => ({ 34 | viteConfig: { 35 | plugins: [vue(), react()] 36 | }, 37 | tsupConfig: { 38 | external: ['electron'] 39 | }, 40 | builderConfig: {} 41 | })) 42 | 43 | defineConfig(() => Promise.resolve({ 44 | viteConfig: { 45 | plugins: [vue(), react()] 46 | }, 47 | tsupConfig: { 48 | external: ['electron'] 49 | }, 50 | builderConfig: {} 51 | })) 52 | 53 | defineConfig(async (env) => { 54 | return { 55 | viteConfig: { 56 | }, 57 | tsupConfig: { 58 | external: ['electron'] 59 | }, 60 | builderConfig: {} 61 | } 62 | }) 63 | 64 | -------------------------------------------------------------------------------- /playground/edit-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "edit-config", 3 | "version": "1.0.0", 4 | "description": "", 5 | "author": "", 6 | "license": "ISC", 7 | "keywords": [], 8 | "main": "index.js", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "devDependencies": { 13 | "@vitejs/plugin-react": "^4.0.4", 14 | "@vitejs/plugin-vue": "^4.2.3", 15 | "electronup": "workspace:^" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /playground/electronup-test/.env: -------------------------------------------------------------------------------- 1 | VITE_HELLO = 你好!electronup! 2 | -------------------------------------------------------------------------------- /playground/electronup-test/.env.development: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是开发环境 2 | -------------------------------------------------------------------------------- /playground/electronup-test/.env.production: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是生产环境 2 | -------------------------------------------------------------------------------- /playground/electronup-test/.env.staging: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是预发布|预上线环境 2 | -------------------------------------------------------------------------------- /playground/electronup-test/.env.test: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是测试环境 2 | -------------------------------------------------------------------------------- /playground/electronup-test/build/builder.config.ts: -------------------------------------------------------------------------------- 1 | import type { BuilderConfig } from 'electronup' 2 | 3 | /** 4 | * 框架内置的配置 5 | * 无需重复配置 6 | * 在此列出 7 | */ 8 | // { 9 | // appId: 'org.quiter.electron-up', 10 | // productName: packages.name, 11 | // protocols: { 12 | // name: packages.name, 13 | // schemes: ['deeplink'] 14 | // }, 15 | // nsis: { 16 | // oneClick: false, 17 | // language: '2052', 18 | // perMachine: true, 19 | // allowElevation: true, 20 | // allowToChangeInstallationDirectory: true, 21 | // runAfterFinish: true, 22 | // createDesktopShortcut: true, 23 | // createStartMenuShortcut: true, 24 | // artifactName: `${packages.name} \${arch} Setup ${packages.version}.\${ext}` 25 | // }, 26 | // files: ['dist/**/*'], 27 | // extraFiles: ['lib'], 28 | // directories: { 29 | // output: 'out' 30 | // } 31 | // } 32 | 33 | export default { 34 | asar: false 35 | } as BuilderConfig 36 | -------------------------------------------------------------------------------- /playground/electronup-test/build/electronup.config.ts: -------------------------------------------------------------------------------- 1 | import type { ConfigEnv } from 'electronup' 2 | import { defineConfig } from 'electronup' 3 | import builderConfig from './builder.config' 4 | import tsupConfig from './tsup.config' 5 | import viteConfig from './vite.config' 6 | 7 | /** 8 | * 框架内置的配置 9 | * 无需重复配置 10 | * 在此列出 11 | */ 12 | // const defaultConfig: Omit = { 13 | // mainDir: 'main', 14 | // renderDir: 'render', 15 | // publicDir: 'public', 16 | // libDir: 'lib', 17 | // resourceDir: 'dist', 18 | // outDir: 'out' 19 | // } 20 | 21 | export default defineConfig((env: ConfigEnv) => { 22 | console.log('defineConfig env: ', env) 23 | return { 24 | builderConfig, 25 | tsupConfig, 26 | viteConfig 27 | } 28 | }) 29 | -------------------------------------------------------------------------------- /playground/electronup-test/build/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import type { TsupConfig } from 'electronup' 2 | 3 | /** 4 | * 框架内置的配置 5 | * 无需重复配置 6 | * 在此列出 7 | */ 8 | // { 9 | // external: [ 10 | // 'electron' 11 | // ... 自行追加忽略文件 12 | // ], 13 | // entry: { electron: 'main/index.ts' }, 14 | // outDir: 'dist', 15 | // watch: command === 'serve' dev环境下监听文件改变, 16 | // dts: false, 17 | // clean: false 18 | // env: injectEnv() 自动注入 .env 文件内的环境变量 19 | // } 20 | 21 | export default {} as TsupConfig 22 | -------------------------------------------------------------------------------- /playground/electronup-test/build/vite.config.ts: -------------------------------------------------------------------------------- 1 | import type { ViteConfig } from 'electronup' 2 | import VueMacros from 'unplugin-vue-macros/vite' 3 | import Vue from '@vitejs/plugin-vue' 4 | import VueJsx from '@vitejs/plugin-vue-jsx' 5 | 6 | /** 7 | * 框架内置的配置 8 | * 无需重复配置 9 | * 在此列出 10 | */ 11 | // { 12 | // base: './', 13 | // root: 'render', 14 | // publicDir: 'public', 15 | // server: { host: '0.0.0.0' }, 16 | // plugins: [ 17 | // 自行导入插件 18 | // ], 19 | // ...config.viteOptions, 20 | // build: { 21 | // outDir: 'dist', 22 | // target: 'esnext', 23 | // minify: 'esbuild', 24 | // reportCompressedSize: false, 25 | // emptyOutDir: false, 26 | // chunkSizeWarningLimit: 2000 27 | // }, 28 | // 额外的vite配置 29 | // viteOptions: {} 30 | // } 31 | 32 | export default { 33 | plugins: [VueMacros({ 34 | plugins: { 35 | vue: Vue(), 36 | vueJsx: VueJsx() 37 | } 38 | })] 39 | } as ViteConfig 40 | -------------------------------------------------------------------------------- /playground/electronup-test/electronup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'electronup' 2 | import VueMacros from 'unplugin-vue-macros/vite' 3 | import Vue from '@vitejs/plugin-vue' 4 | import VueJsx from '@vitejs/plugin-vue-jsx' 5 | 6 | export default defineConfig((env) => { 7 | console.log('defineConfig env: ', env) 8 | return { 9 | viteConfig: { 10 | plugins: [VueMacros({ 11 | plugins: { 12 | vue: Vue(), 13 | vueJsx: VueJsx() 14 | } 15 | })] 16 | }, 17 | builderConfig: { 18 | asar: false, 19 | mac: { 20 | target: [ 21 | { 22 | target: 'dmg' 23 | } 24 | ] 25 | } 26 | } 27 | } 28 | }) 29 | -------------------------------------------------------------------------------- /playground/electronup-test/main/index.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { BrowserWindow, app } from 'electron' 3 | import { Ipc } from '@quiteer/electron-ipc' 4 | 5 | const loadUrl = process.env.NODE_ENV === 'development' 6 | ? `http://localhost:${process.env.RENDER_PORT}` 7 | : `file://${resolve(__dirname, 'index.html')}` 8 | 9 | app.whenReady().then(() => { 10 | Ipc.init() 11 | const win = new BrowserWindow({ 12 | height: 700, width: 1000 13 | }) 14 | 15 | console.log('loadUrl: ', loadUrl) 16 | console.log('NODE_ENV', process.env.NODE_ENV) 17 | console.log('VITE_HELLO :>> ', process.env.VITE_HELLO) 18 | console.log('VITE_MODE_TEXT :>> ', process.env.VITE_MODE_TEXT) 19 | 20 | win.loadURL(loadUrl) 21 | win.webContents.openDevTools({ mode: 'right' }) 22 | // appApiLogs() 23 | }) 24 | 25 | function appApiLogs() { 26 | console.log('app.getVersion(): ', app.getVersion()) 27 | console.log('app.getAppPath(): ', app.getAppPath()) 28 | console.log('app.getName(): ', app.getName()) 29 | console.log('app.getLocale(): ', app.getLocale()) 30 | console.log('app.getSystemLocale(): ', app.getSystemLocale()) 31 | console.log('app.getLocaleCountryCode(): ', app.getLocaleCountryCode()) 32 | console.log('app.hasSingleInstanceLock(): ', app.hasSingleInstanceLock()) 33 | console.log('app.getAppMetrics(): ', app.getAppMetrics()) 34 | console.log('app.getGPUFeatureStatus(): ', app.getGPUFeatureStatus()) 35 | console.log('app.getBadgeCount(): ', app.getBadgeCount()) 36 | console.log('app.isEmojiPanelSupported(): ', app.isEmojiPanelSupported()) 37 | app.showEmojiPanel() 38 | console.log('app.commandLine: ', app.commandLine) 39 | console.log('app.dock: ', app.dock) 40 | console.log('app.isPackaged: ', app.isPackaged) 41 | console.log('app.name: ', app.name) 42 | console.log('app.userAgentFallback: ', app.userAgentFallback) 43 | } 44 | -------------------------------------------------------------------------------- /playground/electronup-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electronup-test", 3 | "version": "1.0.0", 4 | "description": "description", 5 | "author": "", 6 | "license": "ISC", 7 | "keywords": [], 8 | "main": "dist/resource/electron.js", 9 | "scripts": { 10 | "command": "electronup -h && electronup build -h && electronup -v", 11 | "dev:1": "electronup", 12 | "dev:2": "electronup dev", 13 | "dev:port": "electronup dev --port 1020", 14 | "dev:production": "electronup --mode production", 15 | "dev:test": "electronup --mode test", 16 | "dev:staging": "electronup --mode staging", 17 | "dev:err": "electronup --mode err", 18 | "dev:custom": "electronup dev build/electronup.config.ts", 19 | "build": "electronup build", 20 | "build:dir": "electronup build --dir", 21 | "build:win": "electronup build --win", 22 | "build:win32": "electronup build --win ia32", 23 | "build:win64": "electronup build --win x64", 24 | "build:mac": "electronup build --mac", 25 | "build:mac-x64": "electronup build --mac x64", 26 | "build:mac-arm64": "electronup build --mac arm64", 27 | "build:mac-universal": "electronup build --mac universal", 28 | "build:linux": "electronup build --linux", 29 | "build:custom": "electronup build build/electronup.config.ts", 30 | "build:option": "electronup build build/electronup.config.ts -o" 31 | }, 32 | "dependencies": { 33 | "@quiteer/electron-ipc": "^2.0.4", 34 | "@quiteer/electron-preload": "^0.0.10", 35 | "epic-spinners": "^2.0.0" 36 | }, 37 | "devDependencies": { 38 | "@quiteer/eslint-config": "^0.0.3", 39 | "@quiteer/ts-config": "^0.0.5", 40 | "@vitejs/plugin-vue": "^4.0.0", 41 | "@vitejs/plugin-vue-jsx": "^3.0.0", 42 | "electron": "^21.2.2", 43 | "electronup": "workspace:^", 44 | "unplugin-vue-macros": "^1.0.3", 45 | "vite": "^5.0.12", 46 | "vue": "^3.2.43" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /playground/electronup-test/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /playground/electronup-test/render/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 35 | 36 | 49 | -------------------------------------------------------------------------------- /playground/electronup-test/render/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /playground/electronup-test/render/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 35 | 36 | 41 | -------------------------------------------------------------------------------- /playground/electronup-test/render/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + Vue + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /playground/electronup-test/render/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import './style.css' 3 | import App from './App.vue' 4 | 5 | createApp(App).mount('#app') 6 | 7 | console.info(import.meta.env) 8 | 9 | -------------------------------------------------------------------------------- /playground/electronup-test/render/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | background-color: #242424; 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | 18 | a { 19 | font-weight: 500; 20 | color: #646cff; 21 | text-decoration: inherit; 22 | } 23 | a:hover { 24 | color: #535bf2; 25 | } 26 | 27 | body { 28 | margin: 0; 29 | display: flex; 30 | place-items: center; 31 | min-width: 320px; 32 | min-height: 100vh; 33 | } 34 | 35 | h1 { 36 | font-size: 3.2em; 37 | line-height: 1.1; 38 | } 39 | 40 | button { 41 | border-radius: 8px; 42 | border: 1px solid transparent; 43 | padding: 0.6em 1.2em; 44 | font-size: 1em; 45 | font-weight: 500; 46 | font-family: inherit; 47 | background-color: #1a1a1a; 48 | cursor: pointer; 49 | transition: border-color 0.25s; 50 | } 51 | button:hover { 52 | border-color: #646cff; 53 | } 54 | button:focus, 55 | button:focus-visible { 56 | outline: 4px auto -webkit-focus-ring-color; 57 | } 58 | 59 | .card { 60 | padding: 2em; 61 | } 62 | 63 | #app { 64 | max-width: 1280px; 65 | margin: 0 auto; 66 | padding: 2rem; 67 | text-align: center; 68 | } 69 | 70 | @media (prefers-color-scheme: light) { 71 | :root { 72 | color: #213547; 73 | background-color: #ffffff; 74 | } 75 | a:hover { 76 | color: #747bff; 77 | } 78 | button { 79 | background-color: #f9f9f9; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /playground/electronup-test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@quiteer/ts-config/tsconfig.web.json", 3 | "compilerOptions": { 4 | "ignoreDeprecations": "5.0" 5 | }, 6 | "include": [ 7 | "typings/*.d.ts", 8 | "render/**/*" 9 | ], 10 | "references": [{ "path": "./tsconfig.node.json" }] 11 | } 12 | -------------------------------------------------------------------------------- /playground/electronup-test/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "strict": true, // 开启所有严格的类型检查 5 | "strictPropertyInitialization": false, // 类的实例属性必须初始化 6 | "isolatedModules": true, 7 | "resolveJsonModule": true, 8 | "sourceMap": true, 9 | "esModuleInterop": true, // 允许export=导出,由import from 导入 10 | "module": "esnext", // 生成代码的模板标准 11 | "target": "esnext", // 目标语言的版本 12 | "moduleResolution": "node", // 模块解析策略,ts默认用node的解析策略,即相对的方式导入 13 | "allowSyntheticDefaultImports": true, 14 | "emitDecoratorMetadata": true, 15 | "experimentalDecorators": true, 16 | "lib": ["ESNext"], 17 | "types": ["node"] 18 | }, 19 | "include": [ 20 | "build/**/*.ts", 21 | "main/**/*.ts", 22 | "typings/*.d.ts", 23 | "package.json" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /playground/electronup-test/typings/global.d.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | $ipc:import('@quiteer/electron-preload').PreloadIpc & import('@quiteer/electron-ipc/web').ExpandPreloadIpc 3 | $clipboard: import('@quiteer/electron-preload').PreloadClipboard 4 | $webFrame: import('@quiteer/electron-preload').PreloadWebFrame 5 | } 6 | 7 | -------------------------------------------------------------------------------- /playground/electronup-test/typings/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | const component: DefineComponent<{}, {}, any> 6 | export default component 7 | } 8 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | - 'playground/*' 4 | - 'template/*' 5 | -------------------------------------------------------------------------------- /template/index.ts: -------------------------------------------------------------------------------- 1 | import { $, fs, path } from 'zx' 2 | 3 | async function createTemplate() { 4 | await $`pnpm create:vanilla && pnpm create:vue && pnpm create:react && pnpm create:react-swc && pnpm create:solid` 5 | 6 | // 读取目录下的目录 7 | const directories = fs.readdirSync(__dirname, { withFileTypes: true }).filter(dirent => dirent.isDirectory() && !dirent.name.startsWith('node_modules')) 8 | 9 | // 重写 electronup 的版本 10 | directories.forEach(async (dir) => { 11 | const packageJsonPath = path.join(__dirname, dir.name, 'package.json') 12 | const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')) 13 | packageJson.devDependencies.electronup = 'workspace:^' 14 | fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)) 15 | }) 16 | } 17 | 18 | createTemplate() 19 | -------------------------------------------------------------------------------- /template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "template", 3 | "version": "1.0.0", 4 | "description": "", 5 | "author": "", 6 | "license": "ISC", 7 | "keywords": [], 8 | "main": "index.js", 9 | "scripts": { 10 | "create": "create-electronup", 11 | "create:name": "create-electronup user-project", 12 | "create:template": "create-electronup user-project --template vue", 13 | "create:t": "create-electronup user-project -t vue", 14 | "create:err:template": "create-electronup user-project -t vue1", 15 | "create:err:t": "create-electronup user-project -t vue1", 16 | "create:vanilla": "create-electronup vanilla-project -t vanilla", 17 | "create:vue": "create-electronup vue-project -t vue", 18 | "create:react": "create-electronup react-project -t react", 19 | "create:react-swc": "create-electronup react-swc-project -t react-swc", 20 | "create:solid": "create-electronup solid-project -t solid", 21 | "create:all": "esno index.ts" 22 | }, 23 | "devDependencies": { 24 | "create-electronup": "workspace:^", 25 | "esno": "^4.0.0", 26 | "zx": "^7.2.3" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /template/react-project/.env: -------------------------------------------------------------------------------- 1 | VITE_HELLO = 你好!electronup! 2 | -------------------------------------------------------------------------------- /template/react-project/.env.development: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是开发环境 2 | -------------------------------------------------------------------------------- /template/react-project/.env.production: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是生产环境 2 | -------------------------------------------------------------------------------- /template/react-project/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | '@quiteer/eslint-config', 6 | 'plugin:react-hooks/recommended' 7 | ], 8 | ignorePatterns: ['dist'], 9 | plugins: ['react-refresh'], 10 | rules: { 11 | 'react-refresh/only-export-components': [ 12 | 'warn', 13 | { allowConstantExport: true } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/react-project/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /template/react-project/.npmrc: -------------------------------------------------------------------------------- 1 | # 一些镜像配置 2 | registry=https://registry.npmmirror.com 3 | electron_mirror=https://cdn.npmmirror.com/binaries/electron/ 4 | electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/ 5 | # sqlite3_mirror=https://cdn.npmmirror.com/binaries/sqlite3/ 6 | # node_sqlite3_binary_host_mirror=https://npmmirror.com/mirrors/sqlite3/ 7 | 8 | # https://pnpm.io/zh/npmrc#strict-peer-dependencies 9 | strict-peer-dependencies=false 10 | # https://pnpm.io/zh/cli/run#shell-emulator 11 | shell-emulator=true 12 | # https://pnpm.io/zh/npmrc#auto-install-peers 13 | auto-install-peers=false 14 | -------------------------------------------------------------------------------- /template/react-project/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 quiteer 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 | -------------------------------------------------------------------------------- /template/react-project/README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 |

electronup-project

4 |

使用 electronup cli 驱动。

5 |
6 | 7 | # [electronup](https://github.com/QuiteerJs/electronup) 8 | [![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE) ![](https://img.shields.io/github/stars/QuiteerJs/electronup) ![](https://img.shields.io/github/forks/QuiteerJs/electronup) 9 | 10 | > electronup 是一个集成 Vite4.x、tsup6.x、electron-builder24.x 的桌面端构建工具,一个配置文件完成多环境多目标的构建包。 11 | 12 | ## 文档地址 13 | 14 | 文档地址 :https://quiteerjs.github.io/electronup 15 | 16 | 17 | ## 特性 18 | 19 | - **多框架支持** : 使用 `create-electronup` 询问式创建项目模板 , 内置 `vue3` , `react` ,`solid` 等项目模板。 20 | - **Vite + tsup** : 双进程热更新 , 快速开发(主进程代码修改会触发软件重启)。 21 | - **统一的环境变量** : `dotenv` 加载 , 构建时注入 , 双进程拥有相同的环境变量。 22 | - **模式构建** : 默认识别当前代码运行的平台输出打包程序 。 23 | - **可选构建功能提示** : 你将获得可选范围内支持的功能提示 , 选项式自定义构建输出。 24 | - **TypeScript** : 应用程序级 `JavaScript` 的语言。 25 | - **集中管理路径** : 解决双进程资源路径的问题。 26 | - **预置配置** : 内置了很多可以覆盖的构建工具配置。 27 | - **单文件配置** : 只需一个 **electronup.config.ts** 即可管理项目的运行构建。 28 | - **多插件** : 作者会继续开发更多无副作用的独立插件,如:创建窗口,预加载,ipc通信,更新等等。 29 | 30 | ## 声明 31 | 32 | 前提条件 33 | > 熟悉命令行 34 | > 已安装 18 或更高版本的 Node.js 35 | 36 | 37 | 因为使用了 tsup 构建主进程代码,所以该命令行及脚手架只支持 TypeScript ,不支持 JavaScript。 38 | 39 | 40 | ### 一些便携包的相关配置参考 41 | 42 | - `electronup` 43 | 44 | https://www.npmjs.com/package/electronup 45 | 46 | - `@quiteer/electron-ipc` 47 | 48 | https://www.npmjs.com/package/@quiteer/electron-ipc 49 | 50 | - `@quiteer/electron-preload` 51 | 52 | https://www.npmjs.com/package/@quiteer/electron-preload 53 | 54 | 如果你觉得这个项目对你有帮助,可以动动小手 `star` 一下 , 非常感谢!!! 55 | -------------------------------------------------------------------------------- /template/react-project/electronup.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { defineConfig } from 'electronup' 3 | 4 | import react from '@vitejs/plugin-react' 5 | 6 | export default defineConfig((env) => { 7 | const srcDir = resolve(env.root, 'render') 8 | return { 9 | viteConfig: { 10 | plugins: [react()], 11 | resolve: { 12 | alias: { 13 | '@': resolve(env.root, 'render') 14 | } 15 | } 16 | }, 17 | builderConfig: { 18 | win: { 19 | icon: 'public/icon.png', 20 | target: { 21 | target: 'nsis', 22 | arch: 'ia32' 23 | } 24 | } 25 | } 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /template/react-project/main/index.ts: -------------------------------------------------------------------------------- 1 | import { Ipc } from '@quiteer/electron-ipc' 2 | import preload from '@quiteer/electron-preload' 3 | import { BrowserWindow, app } from 'electron' 4 | import { Common } from './utils/common' 5 | 6 | app.whenReady().then(() => { 7 | Ipc.init() 8 | 9 | const win = new BrowserWindow({ 10 | height: 700, 11 | width: 800, 12 | webPreferences: { 13 | preload: preload as string 14 | } 15 | }) 16 | 17 | const child = new BrowserWindow({ 18 | parent: win, 19 | height: 730, 20 | width: 700, 21 | frame: false, 22 | show: false, 23 | webPreferences: { 24 | preload: preload as string 25 | } 26 | }) 27 | 28 | win.loadURL(Common.loadUrl) 29 | child.loadURL('https://freegpt.one/') 30 | 31 | win.webContents.openDevTools({ mode: 'right' }) 32 | win.once('ready-to-show', () => { 33 | setTimeout(() => { 34 | const [x, y] = win.getPosition() 35 | child.setPosition(x + 810, y + 1) 36 | // child.show() 37 | }, 1000) 38 | }) 39 | 40 | win.on('will-move', (event, newBounds) => { 41 | child.setPosition(newBounds.x + 810, newBounds.y + 1) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /template/react-project/main/utils/common.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { Is } from './is' 3 | 4 | export class Common { 5 | static get loadUrl() { 6 | const devUrl = `http://localhost:${process.env.RENDER_PORT}` 7 | const prodUrl = `file://${resolve(__dirname, 'index.html')}` 8 | return Is.dev ? devUrl : prodUrl 9 | } 10 | 11 | static get publicPath() { 12 | const dev = resolve(__dirname, '..', '..', 'public') 13 | const prod = __dirname 14 | return Is.dev ? dev : prod 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/react-project/main/utils/is.ts: -------------------------------------------------------------------------------- 1 | import { arch, platform } from 'process' 2 | 3 | export class Is { 4 | static get win() { 5 | return platform === 'win32' 6 | } 7 | 8 | static get mac() { 9 | return platform === 'darwin' 10 | } 11 | 12 | static get linux() { 13 | return platform === 'linux' 14 | } 15 | 16 | static get ia32() { 17 | return arch === 'ia32' 18 | } 19 | 20 | static get x64() { 21 | return arch === 'x64' 22 | } 23 | 24 | static get dev() { 25 | return process.env.NODE_ENV === 'development' 26 | } 27 | 28 | static get prod() { 29 | return process.env.NODE_ENV === 'production' 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /template/react-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-project", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "main": "dist/resource/electron.js", 6 | "scripts": { 7 | "dev": "electronup --no-minify", 8 | "build": "electronup build", 9 | "dir": "electronup build --dir --no-asar --no-minify", 10 | "lint": "eslint .", 11 | "postinstall": "electron-builder install-app-deps" 12 | }, 13 | "dependencies": { 14 | "@quiteer/electron-ipc": "^2.0.4", 15 | "@quiteer/electron-preload": "^0.0.10", 16 | "react": "^18.2.0", 17 | "react-dom": "^18.2.0" 18 | }, 19 | "devDependencies": { 20 | "@quiteer/eslint-config": "^0.0.3", 21 | "@types/node": "^20.4.6", 22 | "electron": "22.3.6", 23 | "electron-builder": "^24.6.3", 24 | "electronup": "workspace:^", 25 | "eslint": "^8.43.0", 26 | "sass": "^1.65.1", 27 | "typescript": "^5.1.6", 28 | "@types/react": "^18.2.18", 29 | "@types/react-dom": "^18.2.7", 30 | "@vitejs/plugin-react": "^4.0.4", 31 | "eslint-plugin-react-hooks": "^4.6.0", 32 | "eslint-plugin-react-refresh": "^0.4.3" 33 | } 34 | } -------------------------------------------------------------------------------- /template/react-project/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/template/react-project/public/icon.png -------------------------------------------------------------------------------- /template/react-project/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/react-project/render/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /template/react-project/render/App.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import reactLogo from './assets/react.svg' 3 | import viteLogo from '/vite.svg' 4 | import './App.css' 5 | 6 | function App() { 7 | const [count, setCount] = useState(0) 8 | 9 | return ( 10 | <> 11 | 19 |

Vite + React

20 |
21 | 24 |

25 | Edit src/App.tsx and save to test HMR 26 |

27 |
28 |

29 | Click on the Vite and React logos to learn more 30 |

31 | 32 | ) 33 | } 34 | 35 | export default App 36 | -------------------------------------------------------------------------------- /template/react-project/render/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | a:hover { 23 | color: #535bf2; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | display: flex; 29 | place-items: center; 30 | min-width: 320px; 31 | min-height: 100vh; 32 | } 33 | 34 | h1 { 35 | font-size: 3.2em; 36 | line-height: 1.1; 37 | } 38 | 39 | button { 40 | border-radius: 8px; 41 | border: 1px solid transparent; 42 | padding: 0.6em 1.2em; 43 | font-size: 1em; 44 | font-weight: 500; 45 | font-family: inherit; 46 | background-color: #1a1a1a; 47 | cursor: pointer; 48 | transition: border-color 0.25s; 49 | } 50 | button:hover { 51 | border-color: #646cff; 52 | } 53 | button:focus, 54 | button:focus-visible { 55 | outline: 4px auto -webkit-focus-ring-color; 56 | } 57 | 58 | @media (prefers-color-scheme: light) { 59 | :root { 60 | color: #213547; 61 | background-color: #ffffff; 62 | } 63 | a:hover { 64 | color: #747bff; 65 | } 66 | button { 67 | background-color: #f9f9f9; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /template/react-project/render/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | electronup-react 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /template/react-project/render/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import './index.css' 5 | 6 | 7 | ReactDOM.createRoot(document.getElementById('root')!).render( 8 | 9 | 10 | 11 | ) 12 | -------------------------------------------------------------------------------- /template/react-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["render", "typings"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /template/react-project/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["electronup.config.ts", "main", "typings/*"] 10 | } 11 | -------------------------------------------------------------------------------- /template/react-project/typings/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare interface ImportMetaEnv { 4 | readonly VITE_MODE_TEXT: string 5 | readonly VITE_HELLO: string 6 | } 7 | 8 | declare interface ImportMeta { 9 | readonly env: ImportMetaEnv 10 | } 11 | 12 | // 主进程环境变量 13 | declare namespace NodeJS { 14 | export interface ProcessEnv { 15 | readonly NODE_ENV: 'development' | 'production' 16 | readonly RENDER_PORT?: string 17 | readonly VITE_HELLO: string 18 | readonly VITE_MODE_TEXT: string 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /template/react-project/typings/global.d.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | $ipc: import('@quiteer/electron-preload').PreloadIpc & import('@quiteer/electron-ipc/web').ExpandPreloadIpc 3 | $clipboard: import('@quiteer/electron-preload').PreloadClipboard 4 | $webFrame: import('@quiteer/electron-preload').PreloadWebFrame 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /template/react-swc-project/.env: -------------------------------------------------------------------------------- 1 | VITE_HELLO = 你好!electronup! 2 | -------------------------------------------------------------------------------- /template/react-swc-project/.env.development: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是开发环境 2 | -------------------------------------------------------------------------------- /template/react-swc-project/.env.production: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是生产环境 2 | -------------------------------------------------------------------------------- /template/react-swc-project/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | '@quiteer/eslint-config', 6 | 'plugin:react-hooks/recommended' 7 | ], 8 | ignorePatterns: ['dist'], 9 | plugins: ['react-refresh'], 10 | rules: { 11 | 'react-refresh/only-export-components': [ 12 | 'warn', 13 | { allowConstantExport: true } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/react-swc-project/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /template/react-swc-project/.npmrc: -------------------------------------------------------------------------------- 1 | # 一些镜像配置 2 | registry=https://registry.npmmirror.com 3 | electron_mirror=https://cdn.npmmirror.com/binaries/electron/ 4 | electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/ 5 | # sqlite3_mirror=https://cdn.npmmirror.com/binaries/sqlite3/ 6 | # node_sqlite3_binary_host_mirror=https://npmmirror.com/mirrors/sqlite3/ 7 | 8 | # https://pnpm.io/zh/npmrc#strict-peer-dependencies 9 | strict-peer-dependencies=false 10 | # https://pnpm.io/zh/cli/run#shell-emulator 11 | shell-emulator=true 12 | # https://pnpm.io/zh/npmrc#auto-install-peers 13 | auto-install-peers=false 14 | -------------------------------------------------------------------------------- /template/react-swc-project/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 quiteer 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 | -------------------------------------------------------------------------------- /template/react-swc-project/README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 |

electronup-project

4 |

使用 electronup cli 驱动。

5 |
6 | 7 | # [electronup](https://github.com/QuiteerJs/electronup) 8 | [![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE) ![](https://img.shields.io/github/stars/QuiteerJs/electronup) ![](https://img.shields.io/github/forks/QuiteerJs/electronup) 9 | 10 | > electronup 是一个集成 Vite4.x、tsup6.x、electron-builder24.x 的桌面端构建工具,一个配置文件完成多环境多目标的构建包。 11 | 12 | ## 文档地址 13 | 14 | 文档地址 :https://quiteerjs.github.io/electronup 15 | 16 | 17 | ## 特性 18 | 19 | - **多框架支持** : 使用 `create-electronup` 询问式创建项目模板 , 内置 `vue3` , `react` ,`solid` 等项目模板。 20 | - **Vite + tsup** : 双进程热更新 , 快速开发(主进程代码修改会触发软件重启)。 21 | - **统一的环境变量** : `dotenv` 加载 , 构建时注入 , 双进程拥有相同的环境变量。 22 | - **模式构建** : 默认识别当前代码运行的平台输出打包程序 。 23 | - **可选构建功能提示** : 你将获得可选范围内支持的功能提示 , 选项式自定义构建输出。 24 | - **TypeScript** : 应用程序级 `JavaScript` 的语言。 25 | - **集中管理路径** : 解决双进程资源路径的问题。 26 | - **预置配置** : 内置了很多可以覆盖的构建工具配置。 27 | - **单文件配置** : 只需一个 **electronup.config.ts** 即可管理项目的运行构建。 28 | - **多插件** : 作者会继续开发更多无副作用的独立插件,如:创建窗口,预加载,ipc通信,更新等等。 29 | 30 | ## 声明 31 | 32 | 前提条件 33 | > 熟悉命令行 34 | > 已安装 18 或更高版本的 Node.js 35 | 36 | 37 | 因为使用了 tsup 构建主进程代码,所以该命令行及脚手架只支持 TypeScript ,不支持 JavaScript。 38 | 39 | 40 | ### 一些便携包的相关配置参考 41 | 42 | - `electronup` 43 | 44 | https://www.npmjs.com/package/electronup 45 | 46 | - `@quiteer/electron-ipc` 47 | 48 | https://www.npmjs.com/package/@quiteer/electron-ipc 49 | 50 | - `@quiteer/electron-preload` 51 | 52 | https://www.npmjs.com/package/@quiteer/electron-preload 53 | 54 | 如果你觉得这个项目对你有帮助,可以动动小手 `star` 一下 , 非常感谢!!! 55 | -------------------------------------------------------------------------------- /template/react-swc-project/electronup.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { defineConfig } from 'electronup' 3 | 4 | import reactSwc from '@vitejs/plugin-react-swc' 5 | 6 | export default defineConfig((env) => { 7 | const srcDir = resolve(env.root, 'render') 8 | return { 9 | viteConfig: { 10 | plugins: [reactSwc()], 11 | resolve: { 12 | alias: { 13 | '@': resolve(env.root, 'render') 14 | } 15 | } 16 | }, 17 | builderConfig: { 18 | win: { 19 | icon: 'public/icon.png', 20 | target: { 21 | target: 'nsis', 22 | arch: 'ia32' 23 | } 24 | } 25 | } 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /template/react-swc-project/main/index.ts: -------------------------------------------------------------------------------- 1 | import { Ipc } from '@quiteer/electron-ipc' 2 | import preload from '@quiteer/electron-preload' 3 | import { BrowserWindow, app } from 'electron' 4 | import { Common } from './utils/common' 5 | 6 | app.whenReady().then(() => { 7 | Ipc.init() 8 | 9 | const win = new BrowserWindow({ 10 | height: 700, 11 | width: 800, 12 | webPreferences: { 13 | preload: preload as string 14 | } 15 | }) 16 | 17 | const child = new BrowserWindow({ 18 | parent: win, 19 | height: 730, 20 | width: 700, 21 | frame: false, 22 | show: false, 23 | webPreferences: { 24 | preload: preload as string 25 | } 26 | }) 27 | 28 | win.loadURL(Common.loadUrl) 29 | child.loadURL('https://freegpt.one/') 30 | 31 | win.webContents.openDevTools({ mode: 'right' }) 32 | win.once('ready-to-show', () => { 33 | setTimeout(() => { 34 | const [x, y] = win.getPosition() 35 | child.setPosition(x + 810, y + 1) 36 | // child.show() 37 | }, 1000) 38 | }) 39 | 40 | win.on('will-move', (event, newBounds) => { 41 | child.setPosition(newBounds.x + 810, newBounds.y + 1) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /template/react-swc-project/main/utils/common.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { Is } from './is' 3 | 4 | export class Common { 5 | static get loadUrl() { 6 | const devUrl = `http://localhost:${process.env.RENDER_PORT}` 7 | const prodUrl = `file://${resolve(__dirname, 'index.html')}` 8 | return Is.dev ? devUrl : prodUrl 9 | } 10 | 11 | static get publicPath() { 12 | const dev = resolve(__dirname, '..', '..', 'public') 13 | const prod = __dirname 14 | return Is.dev ? dev : prod 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/react-swc-project/main/utils/is.ts: -------------------------------------------------------------------------------- 1 | import { arch, platform } from 'process' 2 | 3 | export class Is { 4 | static get win() { 5 | return platform === 'win32' 6 | } 7 | 8 | static get mac() { 9 | return platform === 'darwin' 10 | } 11 | 12 | static get linux() { 13 | return platform === 'linux' 14 | } 15 | 16 | static get ia32() { 17 | return arch === 'ia32' 18 | } 19 | 20 | static get x64() { 21 | return arch === 'x64' 22 | } 23 | 24 | static get dev() { 25 | return process.env.NODE_ENV === 'development' 26 | } 27 | 28 | static get prod() { 29 | return process.env.NODE_ENV === 'production' 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /template/react-swc-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-swc-project", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "main": "dist/resource/electron.js", 6 | "scripts": { 7 | "dev": "electronup --no-minify", 8 | "build": "electronup build", 9 | "dir": "electronup build --dir --no-asar --no-minify", 10 | "lint": "eslint .", 11 | "postinstall": "electron-builder install-app-deps" 12 | }, 13 | "dependencies": { 14 | "@quiteer/electron-ipc": "^2.0.4", 15 | "@quiteer/electron-preload": "^0.0.10", 16 | "react": "^18.2.0", 17 | "react-dom": "^18.2.0" 18 | }, 19 | "devDependencies": { 20 | "@quiteer/eslint-config": "^0.0.3", 21 | "@types/node": "^20.4.6", 22 | "electron": "22.3.6", 23 | "electron-builder": "^24.6.3", 24 | "electronup": "workspace:^", 25 | "eslint": "^8.43.0", 26 | "sass": "^1.65.1", 27 | "typescript": "^5.1.6", 28 | "@types/react": "^18.2.18", 29 | "@types/react-dom": "^18.2.7", 30 | "@vitejs/plugin-react-swc": "^3.3.2", 31 | "eslint-plugin-react-hooks": "^4.6.0", 32 | "eslint-plugin-react-refresh": "^0.4.3" 33 | } 34 | } -------------------------------------------------------------------------------- /template/react-swc-project/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/template/react-swc-project/public/icon.png -------------------------------------------------------------------------------- /template/react-swc-project/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/react-swc-project/render/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /template/react-swc-project/render/App.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import reactLogo from './assets/react.svg' 3 | import viteLogo from '/vite.svg' 4 | import './App.css' 5 | 6 | function App() { 7 | const [count, setCount] = useState(0) 8 | 9 | return ( 10 | <> 11 | 19 |

Vite + React

20 |
21 | 24 |

25 | Edit src/App.tsx and save to test HMR 26 |

27 |
28 |

29 | Click on the Vite and React logos to learn more 30 |

31 | 32 | ) 33 | } 34 | 35 | export default App 36 | -------------------------------------------------------------------------------- /template/react-swc-project/render/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | a:hover { 23 | color: #535bf2; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | display: flex; 29 | place-items: center; 30 | min-width: 320px; 31 | min-height: 100vh; 32 | } 33 | 34 | h1 { 35 | font-size: 3.2em; 36 | line-height: 1.1; 37 | } 38 | 39 | button { 40 | border-radius: 8px; 41 | border: 1px solid transparent; 42 | padding: 0.6em 1.2em; 43 | font-size: 1em; 44 | font-weight: 500; 45 | font-family: inherit; 46 | background-color: #1a1a1a; 47 | cursor: pointer; 48 | transition: border-color 0.25s; 49 | } 50 | button:hover { 51 | border-color: #646cff; 52 | } 53 | button:focus, 54 | button:focus-visible { 55 | outline: 4px auto -webkit-focus-ring-color; 56 | } 57 | 58 | @media (prefers-color-scheme: light) { 59 | :root { 60 | color: #213547; 61 | background-color: #ffffff; 62 | } 63 | a:hover { 64 | color: #747bff; 65 | } 66 | button { 67 | background-color: #f9f9f9; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /template/react-swc-project/render/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | electronup-react 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /template/react-swc-project/render/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import './index.css' 5 | 6 | 7 | ReactDOM.createRoot(document.getElementById('root')!).render( 8 | 9 | 10 | 11 | ) 12 | -------------------------------------------------------------------------------- /template/react-swc-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["render", "typings"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /template/react-swc-project/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["electronup.config.ts", "main", "typings/*"] 10 | } 11 | -------------------------------------------------------------------------------- /template/react-swc-project/typings/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare interface ImportMetaEnv { 4 | readonly VITE_MODE_TEXT: string 5 | readonly VITE_HELLO: string 6 | } 7 | 8 | declare interface ImportMeta { 9 | readonly env: ImportMetaEnv 10 | } 11 | 12 | // 主进程环境变量 13 | declare namespace NodeJS { 14 | export interface ProcessEnv { 15 | readonly NODE_ENV: 'development' | 'production' 16 | readonly RENDER_PORT?: string 17 | readonly VITE_HELLO: string 18 | readonly VITE_MODE_TEXT: string 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /template/react-swc-project/typings/global.d.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | $ipc: import('@quiteer/electron-preload').PreloadIpc & import('@quiteer/electron-ipc/web').ExpandPreloadIpc 3 | $clipboard: import('@quiteer/electron-preload').PreloadClipboard 4 | $webFrame: import('@quiteer/electron-preload').PreloadWebFrame 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /template/solid-project/.env: -------------------------------------------------------------------------------- 1 | VITE_HELLO = 你好!electronup! 2 | -------------------------------------------------------------------------------- /template/solid-project/.env.development: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是开发环境 2 | -------------------------------------------------------------------------------- /template/solid-project/.env.production: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是生产环境 2 | -------------------------------------------------------------------------------- /template/solid-project/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | } 3 | -------------------------------------------------------------------------------- /template/solid-project/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /template/solid-project/.npmrc: -------------------------------------------------------------------------------- 1 | # 一些镜像配置 2 | registry=https://registry.npmmirror.com 3 | electron_mirror=https://cdn.npmmirror.com/binaries/electron/ 4 | electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/ 5 | # sqlite3_mirror=https://cdn.npmmirror.com/binaries/sqlite3/ 6 | # node_sqlite3_binary_host_mirror=https://npmmirror.com/mirrors/sqlite3/ 7 | 8 | # https://pnpm.io/zh/npmrc#strict-peer-dependencies 9 | strict-peer-dependencies=false 10 | # https://pnpm.io/zh/cli/run#shell-emulator 11 | shell-emulator=true 12 | # https://pnpm.io/zh/npmrc#auto-install-peers 13 | auto-install-peers=false 14 | -------------------------------------------------------------------------------- /template/solid-project/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 quiteer 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 | -------------------------------------------------------------------------------- /template/solid-project/README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 |

electronup-project

4 |

使用 electronup cli 驱动。

5 |
6 | 7 | # [electronup](https://github.com/QuiteerJs/electronup) 8 | [![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE) ![](https://img.shields.io/github/stars/QuiteerJs/electronup) ![](https://img.shields.io/github/forks/QuiteerJs/electronup) 9 | 10 | > electronup 是一个集成 Vite4.x、tsup6.x、electron-builder24.x 的桌面端构建工具,一个配置文件完成多环境多目标的构建包。 11 | 12 | ## 文档地址 13 | 14 | 文档地址 :https://quiteerjs.github.io/electronup 15 | 16 | 17 | ## 特性 18 | 19 | - **多框架支持** : 使用 `create-electronup` 询问式创建项目模板 , 内置 `vue3` , `react` ,`solid` 等项目模板。 20 | - **Vite + tsup** : 双进程热更新 , 快速开发(主进程代码修改会触发软件重启)。 21 | - **统一的环境变量** : `dotenv` 加载 , 构建时注入 , 双进程拥有相同的环境变量。 22 | - **模式构建** : 默认识别当前代码运行的平台输出打包程序 。 23 | - **可选构建功能提示** : 你将获得可选范围内支持的功能提示 , 选项式自定义构建输出。 24 | - **TypeScript** : 应用程序级 `JavaScript` 的语言。 25 | - **集中管理路径** : 解决双进程资源路径的问题。 26 | - **预置配置** : 内置了很多可以覆盖的构建工具配置。 27 | - **单文件配置** : 只需一个 **electronup.config.ts** 即可管理项目的运行构建。 28 | - **多插件** : 作者会继续开发更多无副作用的独立插件,如:创建窗口,预加载,ipc通信,更新等等。 29 | 30 | ## 声明 31 | 32 | 前提条件 33 | > 熟悉命令行 34 | > 已安装 18 或更高版本的 Node.js 35 | 36 | 37 | 因为使用了 tsup 构建主进程代码,所以该命令行及脚手架只支持 TypeScript ,不支持 JavaScript。 38 | 39 | 40 | ### 一些便携包的相关配置参考 41 | 42 | - `electronup` 43 | 44 | https://www.npmjs.com/package/electronup 45 | 46 | - `@quiteer/electron-ipc` 47 | 48 | https://www.npmjs.com/package/@quiteer/electron-ipc 49 | 50 | - `@quiteer/electron-preload` 51 | 52 | https://www.npmjs.com/package/@quiteer/electron-preload 53 | 54 | 如果你觉得这个项目对你有帮助,可以动动小手 `star` 一下 , 非常感谢!!! 55 | -------------------------------------------------------------------------------- /template/solid-project/electronup.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { defineConfig } from 'electronup' 3 | 4 | import solid from 'vite-plugin-solid' 5 | 6 | export default defineConfig((env) => { 7 | const srcDir = resolve(env.root, 'render') 8 | return { 9 | viteConfig: { 10 | plugins: [solid()], 11 | resolve: { 12 | alias: { 13 | '@': resolve(env.root, 'render') 14 | } 15 | } 16 | }, 17 | builderConfig: { 18 | win: { 19 | icon: 'public/icon.png', 20 | target: { 21 | target: 'nsis', 22 | arch: 'ia32' 23 | } 24 | } 25 | } 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /template/solid-project/main/index.ts: -------------------------------------------------------------------------------- 1 | import { Ipc } from '@quiteer/electron-ipc' 2 | import preload from '@quiteer/electron-preload' 3 | import { BrowserWindow, app } from 'electron' 4 | import { Common } from './utils/common' 5 | 6 | app.whenReady().then(() => { 7 | Ipc.init() 8 | 9 | const win = new BrowserWindow({ 10 | height: 700, 11 | width: 800, 12 | webPreferences: { 13 | preload: preload as string 14 | } 15 | }) 16 | 17 | const child = new BrowserWindow({ 18 | parent: win, 19 | height: 730, 20 | width: 700, 21 | frame: false, 22 | show: false, 23 | webPreferences: { 24 | preload: preload as string 25 | } 26 | }) 27 | 28 | win.loadURL(Common.loadUrl) 29 | child.loadURL('https://freegpt.one/') 30 | 31 | win.webContents.openDevTools({ mode: 'right' }) 32 | win.once('ready-to-show', () => { 33 | setTimeout(() => { 34 | const [x, y] = win.getPosition() 35 | child.setPosition(x + 810, y + 1) 36 | // child.show() 37 | }, 1000) 38 | }) 39 | 40 | win.on('will-move', (event, newBounds) => { 41 | child.setPosition(newBounds.x + 810, newBounds.y + 1) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /template/solid-project/main/utils/common.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { Is } from './is' 3 | 4 | export class Common { 5 | static get loadUrl() { 6 | const devUrl = `http://localhost:${process.env.RENDER_PORT}` 7 | const prodUrl = `file://${resolve(__dirname, 'index.html')}` 8 | return Is.dev ? devUrl : prodUrl 9 | } 10 | 11 | static get publicPath() { 12 | const dev = resolve(__dirname, '..', '..', 'public') 13 | const prod = __dirname 14 | return Is.dev ? dev : prod 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/solid-project/main/utils/is.ts: -------------------------------------------------------------------------------- 1 | import { arch, platform } from 'process' 2 | 3 | export class Is { 4 | static get win() { 5 | return platform === 'win32' 6 | } 7 | 8 | static get mac() { 9 | return platform === 'darwin' 10 | } 11 | 12 | static get linux() { 13 | return platform === 'linux' 14 | } 15 | 16 | static get ia32() { 17 | return arch === 'ia32' 18 | } 19 | 20 | static get x64() { 21 | return arch === 'x64' 22 | } 23 | 24 | static get dev() { 25 | return process.env.NODE_ENV === 'development' 26 | } 27 | 28 | static get prod() { 29 | return process.env.NODE_ENV === 'production' 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /template/solid-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "solid-project", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "main": "dist/resource/electron.js", 6 | "scripts": { 7 | "dev": "electronup --no-minify", 8 | "build": "electronup build", 9 | "dir": "electronup build --dir --no-asar --no-minify", 10 | "lint": "eslint .", 11 | "postinstall": "electron-builder install-app-deps" 12 | }, 13 | "dependencies": { 14 | "@quiteer/electron-ipc": "^2.0.4", 15 | "@quiteer/electron-preload": "^0.0.10", 16 | "solid-js": "^1.7.9" 17 | }, 18 | "devDependencies": { 19 | "@quiteer/eslint-config": "^0.0.3", 20 | "@types/node": "^20.4.6", 21 | "electron": "22.3.6", 22 | "electron-builder": "^24.6.3", 23 | "electronup": "workspace:^", 24 | "eslint": "^8.43.0", 25 | "sass": "^1.65.1", 26 | "typescript": "^5.1.6", 27 | "vite-plugin-solid": "^2.7.0" 28 | } 29 | } -------------------------------------------------------------------------------- /template/solid-project/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/template/solid-project/public/icon.png -------------------------------------------------------------------------------- /template/solid-project/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/solid-project/render/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.solid:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | .card { 22 | padding: 2em; 23 | } 24 | 25 | .read-the-docs { 26 | color: #888; 27 | } 28 | -------------------------------------------------------------------------------- /template/solid-project/render/App.tsx: -------------------------------------------------------------------------------- 1 | import { createSignal } from 'solid-js' 2 | import solidLogo from './assets/solid.svg' 3 | import viteLogo from '/vite.svg' 4 | import './App.css' 5 | 6 | function App() { 7 | const [count, setCount] = createSignal(0) 8 | 9 | return ( 10 | <> 11 | 19 |

Vite + Solid

20 |
21 | 24 |

25 | Edit src/App.tsx and save to test HMR 26 |

27 |
28 |

29 | Click on the Vite and Solid logos to learn more 30 |

31 | 32 | ) 33 | } 34 | 35 | export default App 36 | -------------------------------------------------------------------------------- /template/solid-project/render/assets/solid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/solid-project/render/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | a:hover { 23 | color: #535bf2; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | display: flex; 29 | place-items: center; 30 | min-width: 320px; 31 | min-height: 100vh; 32 | } 33 | 34 | h1 { 35 | font-size: 3.2em; 36 | line-height: 1.1; 37 | } 38 | 39 | button { 40 | border-radius: 8px; 41 | border: 1px solid transparent; 42 | padding: 0.6em 1.2em; 43 | font-size: 1em; 44 | font-weight: 500; 45 | font-family: inherit; 46 | background-color: #1a1a1a; 47 | cursor: pointer; 48 | transition: border-color 0.25s; 49 | } 50 | button:hover { 51 | border-color: #646cff; 52 | } 53 | button:focus, 54 | button:focus-visible { 55 | outline: 4px auto -webkit-focus-ring-color; 56 | } 57 | 58 | @media (prefers-color-scheme: light) { 59 | :root { 60 | color: #213547; 61 | background-color: #ffffff; 62 | } 63 | a:hover { 64 | color: #747bff; 65 | } 66 | button { 67 | background-color: #f9f9f9; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /template/solid-project/render/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | electronup-solid 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /template/solid-project/render/index.tsx: -------------------------------------------------------------------------------- 1 | /* @refresh reload */ 2 | import { render } from 'solid-js/web' 3 | 4 | import './index.css' 5 | import App from './App' 6 | 7 | const root = document.getElementById('root') 8 | 9 | render(() => , root!) 10 | -------------------------------------------------------------------------------- /template/solid-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "preserve", 16 | "jsxImportSource": "solid-js", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true 23 | }, 24 | "include": ["render", "typings"], 25 | "references": [{ "path": "./tsconfig.node.json" }] 26 | } 27 | -------------------------------------------------------------------------------- /template/solid-project/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["electronup.config.ts", "main", "typings/*"] 10 | } 11 | -------------------------------------------------------------------------------- /template/solid-project/typings/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare interface ImportMetaEnv { 4 | readonly VITE_MODE_TEXT: string 5 | readonly VITE_HELLO: string 6 | } 7 | 8 | declare interface ImportMeta { 9 | readonly env: ImportMetaEnv 10 | } 11 | 12 | // 主进程环境变量 13 | declare namespace NodeJS { 14 | export interface ProcessEnv { 15 | readonly NODE_ENV: 'development' | 'production' 16 | readonly RENDER_PORT?: string 17 | readonly VITE_HELLO: string 18 | readonly VITE_MODE_TEXT: string 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /template/solid-project/typings/global.d.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | $ipc: import('@quiteer/electron-preload').PreloadIpc & import('@quiteer/electron-ipc/web').ExpandPreloadIpc 3 | $clipboard: import('@quiteer/electron-preload').PreloadClipboard 4 | $webFrame: import('@quiteer/electron-preload').PreloadWebFrame 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /template/vanilla-project/.env: -------------------------------------------------------------------------------- 1 | VITE_HELLO = 你好!electronup! 2 | -------------------------------------------------------------------------------- /template/vanilla-project/.env.development: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是开发环境 2 | -------------------------------------------------------------------------------- /template/vanilla-project/.env.production: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是生产环境 2 | -------------------------------------------------------------------------------- /template/vanilla-project/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@quiteer/eslint-config'], 3 | } 4 | -------------------------------------------------------------------------------- /template/vanilla-project/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /template/vanilla-project/.npmrc: -------------------------------------------------------------------------------- 1 | # 一些镜像配置 2 | registry=https://registry.npmmirror.com 3 | electron_mirror=https://cdn.npmmirror.com/binaries/electron/ 4 | electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/ 5 | # sqlite3_mirror=https://cdn.npmmirror.com/binaries/sqlite3/ 6 | # node_sqlite3_binary_host_mirror=https://npmmirror.com/mirrors/sqlite3/ 7 | 8 | # https://pnpm.io/zh/npmrc#strict-peer-dependencies 9 | strict-peer-dependencies=false 10 | # https://pnpm.io/zh/cli/run#shell-emulator 11 | shell-emulator=true 12 | # https://pnpm.io/zh/npmrc#auto-install-peers 13 | auto-install-peers=false 14 | -------------------------------------------------------------------------------- /template/vanilla-project/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 quiteer 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 | -------------------------------------------------------------------------------- /template/vanilla-project/README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 |

electronup-project

4 |

使用 electronup cli 驱动。

5 |
6 | 7 | # [electronup](https://github.com/QuiteerJs/electronup) 8 | [![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE) ![](https://img.shields.io/github/stars/QuiteerJs/electronup) ![](https://img.shields.io/github/forks/QuiteerJs/electronup) 9 | 10 | > electronup 是一个集成 Vite4.x、tsup6.x、electron-builder24.x 的桌面端构建工具,一个配置文件完成多环境多目标的构建包。 11 | 12 | ## 文档地址 13 | 14 | 文档地址 :https://quiteerjs.github.io/electronup 15 | 16 | 17 | ## 特性 18 | 19 | - **多框架支持** : 使用 `create-electronup` 询问式创建项目模板 , 内置 `vue3` , `react` ,`solid` 等项目模板。 20 | - **Vite + tsup** : 双进程热更新 , 快速开发(主进程代码修改会触发软件重启)。 21 | - **统一的环境变量** : `dotenv` 加载 , 构建时注入 , 双进程拥有相同的环境变量。 22 | - **模式构建** : 默认识别当前代码运行的平台输出打包程序 。 23 | - **可选构建功能提示** : 你将获得可选范围内支持的功能提示 , 选项式自定义构建输出。 24 | - **TypeScript** : 应用程序级 `JavaScript` 的语言。 25 | - **集中管理路径** : 解决双进程资源路径的问题。 26 | - **预置配置** : 内置了很多可以覆盖的构建工具配置。 27 | - **单文件配置** : 只需一个 **electronup.config.ts** 即可管理项目的运行构建。 28 | - **多插件** : 作者会继续开发更多无副作用的独立插件,如:创建窗口,预加载,ipc通信,更新等等。 29 | 30 | ## 声明 31 | 32 | 前提条件 33 | > 熟悉命令行 34 | > 已安装 18 或更高版本的 Node.js 35 | 36 | 37 | 因为使用了 tsup 构建主进程代码,所以该命令行及脚手架只支持 TypeScript ,不支持 JavaScript。 38 | 39 | 40 | ### 一些便携包的相关配置参考 41 | 42 | - `electronup` 43 | 44 | https://www.npmjs.com/package/electronup 45 | 46 | - `@quiteer/electron-ipc` 47 | 48 | https://www.npmjs.com/package/@quiteer/electron-ipc 49 | 50 | - `@quiteer/electron-preload` 51 | 52 | https://www.npmjs.com/package/@quiteer/electron-preload 53 | 54 | 如果你觉得这个项目对你有帮助,可以动动小手 `star` 一下 , 非常感谢!!! 55 | -------------------------------------------------------------------------------- /template/vanilla-project/electronup.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { defineConfig } from 'electronup' 3 | 4 | 5 | 6 | export default defineConfig((env) => { 7 | const srcDir = resolve(env.root, 'render') 8 | return { 9 | viteConfig: { 10 | plugins: [], 11 | resolve: { 12 | alias: { 13 | '@': resolve(env.root, 'render') 14 | } 15 | } 16 | }, 17 | builderConfig: { 18 | win: { 19 | icon: 'public/icon.png', 20 | target: { 21 | target: 'nsis', 22 | arch: 'ia32' 23 | } 24 | } 25 | } 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /template/vanilla-project/main/index.ts: -------------------------------------------------------------------------------- 1 | import { Ipc } from '@quiteer/electron-ipc' 2 | import preload from '@quiteer/electron-preload' 3 | import { BrowserWindow, app } from 'electron' 4 | import { Common } from './utils/common' 5 | 6 | app.whenReady().then(() => { 7 | Ipc.init() 8 | 9 | const win = new BrowserWindow({ 10 | height: 700, 11 | width: 800, 12 | webPreferences: { 13 | preload: preload as string 14 | } 15 | }) 16 | 17 | const child = new BrowserWindow({ 18 | parent: win, 19 | height: 730, 20 | width: 700, 21 | frame: false, 22 | show: false, 23 | webPreferences: { 24 | preload: preload as string 25 | } 26 | }) 27 | 28 | win.loadURL(Common.loadUrl) 29 | child.loadURL('https://freegpt.one/') 30 | 31 | win.webContents.openDevTools({ mode: 'right' }) 32 | win.once('ready-to-show', () => { 33 | setTimeout(() => { 34 | const [x, y] = win.getPosition() 35 | child.setPosition(x + 810, y + 1) 36 | // child.show() 37 | }, 1000) 38 | }) 39 | 40 | win.on('will-move', (event, newBounds) => { 41 | child.setPosition(newBounds.x + 810, newBounds.y + 1) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /template/vanilla-project/main/utils/common.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { Is } from './is' 3 | 4 | export class Common { 5 | static get loadUrl() { 6 | const devUrl = `http://localhost:${process.env.RENDER_PORT}` 7 | const prodUrl = `file://${resolve(__dirname, 'index.html')}` 8 | return Is.dev ? devUrl : prodUrl 9 | } 10 | 11 | static get publicPath() { 12 | const dev = resolve(__dirname, '..', '..', 'public') 13 | const prod = __dirname 14 | return Is.dev ? dev : prod 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/vanilla-project/main/utils/is.ts: -------------------------------------------------------------------------------- 1 | import { arch, platform } from 'process' 2 | 3 | export class Is { 4 | static get win() { 5 | return platform === 'win32' 6 | } 7 | 8 | static get mac() { 9 | return platform === 'darwin' 10 | } 11 | 12 | static get linux() { 13 | return platform === 'linux' 14 | } 15 | 16 | static get ia32() { 17 | return arch === 'ia32' 18 | } 19 | 20 | static get x64() { 21 | return arch === 'x64' 22 | } 23 | 24 | static get dev() { 25 | return process.env.NODE_ENV === 'development' 26 | } 27 | 28 | static get prod() { 29 | return process.env.NODE_ENV === 'production' 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /template/vanilla-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vanilla-project", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "main": "dist/resource/electron.js", 6 | "scripts": { 7 | "dev": "electronup --no-minify", 8 | "build": "electronup build", 9 | "dir": "electronup build --dir --no-asar --no-minify", 10 | "lint": "eslint .", 11 | "postinstall": "electron-builder install-app-deps" 12 | }, 13 | "dependencies": { 14 | "@quiteer/electron-ipc": "^2.0.4", 15 | "@quiteer/electron-preload": "^0.0.10" 16 | }, 17 | "devDependencies": { 18 | "@quiteer/eslint-config": "^0.0.3", 19 | "@types/node": "^20.4.6", 20 | "electron": "22.3.6", 21 | "electron-builder": "^24.6.3", 22 | "electronup": "workspace:^", 23 | "eslint": "^8.43.0", 24 | "sass": "^1.65.1", 25 | "typescript": "^5.1.6" 26 | } 27 | } -------------------------------------------------------------------------------- /template/vanilla-project/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/template/vanilla-project/public/icon.png -------------------------------------------------------------------------------- /template/vanilla-project/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/vanilla-project/render/counter.ts: -------------------------------------------------------------------------------- 1 | export function setupCounter(element: HTMLButtonElement) { 2 | let counter = 0 3 | const setCounter = (count: number) => { 4 | counter = count 5 | element.innerHTML = `count is ${counter}` 6 | } 7 | element.addEventListener('click', () => setCounter(counter + 1)) 8 | setCounter(0) 9 | } 10 | -------------------------------------------------------------------------------- /template/vanilla-project/render/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | electronup-vanilla 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /template/vanilla-project/render/main.ts: -------------------------------------------------------------------------------- 1 | import './style.css' 2 | import typescriptLogo from './typescript.svg' 3 | import viteLogo from '/vite.svg' 4 | import { setupCounter } from './counter' 5 | 6 | document.querySelector('#app')!.innerHTML = ` 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |

Vite + TypeScript

15 |
16 | 17 |
18 |

19 | Click on the Vite and TypeScript logos to learn more 20 |

21 |
22 | ` 23 | 24 | setupCounter(document.querySelector('#counter')!) 25 | -------------------------------------------------------------------------------- /template/vanilla-project/render/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | a:hover { 23 | color: #535bf2; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | display: flex; 29 | place-items: center; 30 | min-width: 320px; 31 | min-height: 100vh; 32 | } 33 | 34 | h1 { 35 | font-size: 3.2em; 36 | line-height: 1.1; 37 | } 38 | 39 | #app { 40 | max-width: 1280px; 41 | margin: 0 auto; 42 | padding: 2rem; 43 | text-align: center; 44 | } 45 | 46 | .logo { 47 | height: 6em; 48 | padding: 1.5em; 49 | will-change: filter; 50 | transition: filter 300ms; 51 | } 52 | .logo:hover { 53 | filter: drop-shadow(0 0 2em #646cffaa); 54 | } 55 | .logo.vanilla:hover { 56 | filter: drop-shadow(0 0 2em #3178c6aa); 57 | } 58 | 59 | .card { 60 | padding: 2em; 61 | } 62 | 63 | .read-the-docs { 64 | color: #888; 65 | } 66 | 67 | button { 68 | border-radius: 8px; 69 | border: 1px solid transparent; 70 | padding: 0.6em 1.2em; 71 | font-size: 1em; 72 | font-weight: 500; 73 | font-family: inherit; 74 | background-color: #1a1a1a; 75 | cursor: pointer; 76 | transition: border-color 0.25s; 77 | } 78 | button:hover { 79 | border-color: #646cff; 80 | } 81 | button:focus, 82 | button:focus-visible { 83 | outline: 4px auto -webkit-focus-ring-color; 84 | } 85 | 86 | @media (prefers-color-scheme: light) { 87 | :root { 88 | color: #213547; 89 | background-color: #ffffff; 90 | } 91 | a:hover { 92 | color: #747bff; 93 | } 94 | button { 95 | background-color: #f9f9f9; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /template/vanilla-project/render/typescript.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/vanilla-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "preserve", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["render", "typings"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /template/vanilla-project/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["electronup.config.ts", "main", "typings/*"] 10 | } 11 | -------------------------------------------------------------------------------- /template/vanilla-project/typings/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare interface ImportMetaEnv { 4 | readonly VITE_MODE_TEXT: string 5 | readonly VITE_HELLO: string 6 | } 7 | 8 | declare interface ImportMeta { 9 | readonly env: ImportMetaEnv 10 | } 11 | 12 | // 主进程环境变量 13 | declare namespace NodeJS { 14 | export interface ProcessEnv { 15 | readonly NODE_ENV: 'development' | 'production' 16 | readonly RENDER_PORT?: string 17 | readonly VITE_HELLO: string 18 | readonly VITE_MODE_TEXT: string 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /template/vanilla-project/typings/global.d.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | $ipc: import('@quiteer/electron-preload').PreloadIpc & import('@quiteer/electron-ipc/web').ExpandPreloadIpc 3 | $clipboard: import('@quiteer/electron-preload').PreloadClipboard 4 | $webFrame: import('@quiteer/electron-preload').PreloadWebFrame 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /template/vue-project/.env: -------------------------------------------------------------------------------- 1 | VITE_HELLO = 你好!electronup! 2 | -------------------------------------------------------------------------------- /template/vue-project/.env.development: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是开发环境 2 | -------------------------------------------------------------------------------- /template/vue-project/.env.production: -------------------------------------------------------------------------------- 1 | VITE_MODE_TEXT=这里是生产环境 2 | -------------------------------------------------------------------------------- /template/vue-project/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@quiteer/eslint-config'], 3 | } 4 | -------------------------------------------------------------------------------- /template/vue-project/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /template/vue-project/.npmrc: -------------------------------------------------------------------------------- 1 | # 一些镜像配置 2 | registry=https://registry.npmmirror.com 3 | electron_mirror=https://cdn.npmmirror.com/binaries/electron/ 4 | electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/ 5 | # sqlite3_mirror=https://cdn.npmmirror.com/binaries/sqlite3/ 6 | # node_sqlite3_binary_host_mirror=https://npmmirror.com/mirrors/sqlite3/ 7 | 8 | # https://pnpm.io/zh/npmrc#strict-peer-dependencies 9 | strict-peer-dependencies=false 10 | # https://pnpm.io/zh/cli/run#shell-emulator 11 | shell-emulator=true 12 | # https://pnpm.io/zh/npmrc#auto-install-peers 13 | auto-install-peers=false 14 | -------------------------------------------------------------------------------- /template/vue-project/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 quiteer 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 | -------------------------------------------------------------------------------- /template/vue-project/README.md: -------------------------------------------------------------------------------- 1 | 2 |
3 |

electronup-project

4 |

使用 electronup cli 驱动。

5 |
6 | 7 | # [electronup](https://github.com/QuiteerJs/electronup) 8 | [![license](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE) ![](https://img.shields.io/github/stars/QuiteerJs/electronup) ![](https://img.shields.io/github/forks/QuiteerJs/electronup) 9 | 10 | > electronup 是一个集成 Vite4.x、tsup6.x、electron-builder24.x 的桌面端构建工具,一个配置文件完成多环境多目标的构建包。 11 | 12 | ## 文档地址 13 | 14 | 文档地址 :https://quiteerjs.github.io/electronup 15 | 16 | 17 | ## 特性 18 | 19 | - **多框架支持** : 使用 `create-electronup` 询问式创建项目模板 , 内置 `vue3` , `react` ,`solid` 等项目模板。 20 | - **Vite + tsup** : 双进程热更新 , 快速开发(主进程代码修改会触发软件重启)。 21 | - **统一的环境变量** : `dotenv` 加载 , 构建时注入 , 双进程拥有相同的环境变量。 22 | - **模式构建** : 默认识别当前代码运行的平台输出打包程序 。 23 | - **可选构建功能提示** : 你将获得可选范围内支持的功能提示 , 选项式自定义构建输出。 24 | - **TypeScript** : 应用程序级 `JavaScript` 的语言。 25 | - **集中管理路径** : 解决双进程资源路径的问题。 26 | - **预置配置** : 内置了很多可以覆盖的构建工具配置。 27 | - **单文件配置** : 只需一个 **electronup.config.ts** 即可管理项目的运行构建。 28 | - **多插件** : 作者会继续开发更多无副作用的独立插件,如:创建窗口,预加载,ipc通信,更新等等。 29 | 30 | ## 声明 31 | 32 | 前提条件 33 | > 熟悉命令行 34 | > 已安装 18 或更高版本的 Node.js 35 | 36 | 37 | 因为使用了 tsup 构建主进程代码,所以该命令行及脚手架只支持 TypeScript ,不支持 JavaScript。 38 | 39 | 40 | ### 一些便携包的相关配置参考 41 | 42 | - `electronup` 43 | 44 | https://www.npmjs.com/package/electronup 45 | 46 | - `@quiteer/electron-ipc` 47 | 48 | https://www.npmjs.com/package/@quiteer/electron-ipc 49 | 50 | - `@quiteer/electron-preload` 51 | 52 | https://www.npmjs.com/package/@quiteer/electron-preload 53 | 54 | 如果你觉得这个项目对你有帮助,可以动动小手 `star` 一下 , 非常感谢!!! 55 | -------------------------------------------------------------------------------- /template/vue-project/electronup.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { defineConfig } from 'electronup' 3 | 4 | import vue from '@vitejs/plugin-vue' 5 | 6 | export default defineConfig((env) => { 7 | const srcDir = resolve(env.root, 'render') 8 | return { 9 | viteConfig: { 10 | plugins: [vue()], 11 | resolve: { 12 | alias: { 13 | '@': resolve(env.root, 'render') 14 | } 15 | } 16 | }, 17 | builderConfig: { 18 | win: { 19 | icon: 'public/icon.png', 20 | target: { 21 | target: 'nsis', 22 | arch: 'ia32' 23 | } 24 | } 25 | } 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /template/vue-project/main/index.ts: -------------------------------------------------------------------------------- 1 | import { Ipc } from '@quiteer/electron-ipc' 2 | import preload from '@quiteer/electron-preload' 3 | import { BrowserWindow, app } from 'electron' 4 | import { Common } from './utils/common' 5 | 6 | app.whenReady().then(() => { 7 | Ipc.init() 8 | 9 | const win = new BrowserWindow({ 10 | height: 700, 11 | width: 800, 12 | webPreferences: { 13 | preload: preload as string 14 | } 15 | }) 16 | 17 | const child = new BrowserWindow({ 18 | parent: win, 19 | height: 730, 20 | width: 700, 21 | frame: false, 22 | show: false, 23 | webPreferences: { 24 | preload: preload as string 25 | } 26 | }) 27 | 28 | win.loadURL(Common.loadUrl) 29 | child.loadURL('https://freegpt.one/') 30 | 31 | win.webContents.openDevTools({ mode: 'right' }) 32 | win.once('ready-to-show', () => { 33 | setTimeout(() => { 34 | const [x, y] = win.getPosition() 35 | child.setPosition(x + 810, y + 1) 36 | // child.show() 37 | }, 1000) 38 | }) 39 | 40 | win.on('will-move', (event, newBounds) => { 41 | child.setPosition(newBounds.x + 810, newBounds.y + 1) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /template/vue-project/main/utils/common.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { Is } from './is' 3 | 4 | export class Common { 5 | static get loadUrl() { 6 | const devUrl = `http://localhost:${process.env.RENDER_PORT}` 7 | const prodUrl = `file://${resolve(__dirname, 'index.html')}` 8 | return Is.dev ? devUrl : prodUrl 9 | } 10 | 11 | static get publicPath() { 12 | const dev = resolve(__dirname, '..', '..', 'public') 13 | const prod = __dirname 14 | return Is.dev ? dev : prod 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/vue-project/main/utils/is.ts: -------------------------------------------------------------------------------- 1 | import { arch, platform } from 'process' 2 | 3 | export class Is { 4 | static get win() { 5 | return platform === 'win32' 6 | } 7 | 8 | static get mac() { 9 | return platform === 'darwin' 10 | } 11 | 12 | static get linux() { 13 | return platform === 'linux' 14 | } 15 | 16 | static get ia32() { 17 | return arch === 'ia32' 18 | } 19 | 20 | static get x64() { 21 | return arch === 'x64' 22 | } 23 | 24 | static get dev() { 25 | return process.env.NODE_ENV === 'development' 26 | } 27 | 28 | static get prod() { 29 | return process.env.NODE_ENV === 'production' 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /template/vue-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-project", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "main": "dist/resource/electron.js", 6 | "scripts": { 7 | "dev": "electronup --no-minify", 8 | "build": "electronup build", 9 | "dir": "electronup build --dir --no-asar --no-minify", 10 | "typecheck": "vue-tsc --noEmit --skipLibCheck", 11 | "lint": "eslint .", 12 | "postinstall": "electron-builder install-app-deps" 13 | }, 14 | "dependencies": { 15 | "@quiteer/electron-ipc": "^2.0.4", 16 | "@quiteer/electron-preload": "^0.0.10", 17 | "echarts": "^5.4.2" 18 | }, 19 | "devDependencies": { 20 | "@quiteer/eslint-config": "^0.0.3", 21 | "@types/node": "^20.4.6", 22 | "electron": "22.3.6", 23 | "electron-builder": "^24.6.3", 24 | "electronup": "workspace:^", 25 | "eslint": "^8.43.0", 26 | "sass": "^1.65.1", 27 | "typescript": "^5.1.6", 28 | "@vitejs/plugin-vue": "^5.0.3", 29 | "pinia": "^2.1.7", 30 | "vue": "^3.4.15", 31 | "vue-router": "^4.2.5", 32 | "vue-tsc": "^1.8.1" 33 | } 34 | } -------------------------------------------------------------------------------- /template/vue-project/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/template/vue-project/public/icon.png -------------------------------------------------------------------------------- /template/vue-project/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/vue-project/render/App.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 40 | 41 | 90 | -------------------------------------------------------------------------------- /template/vue-project/render/assets/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuiteerJs/electronup/668f9c222aa60a30dea56b9f464b752b03391e08/template/vue-project/render/assets/avatar.png -------------------------------------------------------------------------------- /template/vue-project/render/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/vue-project/render/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | electronup-vue 8 | 9 | 10 |
11 |
12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /template/vue-project/render/loading/index.vue: -------------------------------------------------------------------------------- 1 | 58 | 59 | 62 | 63 | 73 | -------------------------------------------------------------------------------- /template/vue-project/render/main.ts: -------------------------------------------------------------------------------- 1 | import './styles/style.css' 2 | import { createPinia } from 'pinia' 3 | import { createApp } from 'vue' 4 | import App from './App.vue' 5 | import Loading from './loading/index.vue' 6 | 7 | createApp(Loading).mount('#app-loading') 8 | 9 | console.log(import.meta.env) 10 | 11 | setTimeout(() => { 12 | const app = createApp(App) 13 | app.use(createPinia()) 14 | .mount('#app') 15 | }, 2000) 16 | 17 | -------------------------------------------------------------------------------- /template/vue-project/render/store/index.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | 3 | interface DemoState { 4 | demo: { 5 | name: string 6 | } 7 | } 8 | 9 | export const useDemoStore = defineStore('demo', { 10 | state: (): DemoState => ({ 11 | demo: { 12 | name: 'demo' 13 | } 14 | }), 15 | getters: { 16 | name: (state): string => state.demo.name 17 | }, 18 | actions: { 19 | actionDemo(data: string) { 20 | this.demo.name = data 21 | } 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /template/vue-project/render/styles/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | 5 | #app { 6 | max-width: 1280px; 7 | margin: 0 auto; 8 | padding: 2rem; 9 | text-align: center; 10 | } 11 | 12 | #app-loading{ 13 | position:absolut; 14 | top:0; 15 | left:0; 16 | } 17 | -------------------------------------------------------------------------------- /template/vue-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "preserve", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["render", "typings"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /template/vue-project/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["electronup.config.ts", "main", "typings/*"] 10 | } 11 | -------------------------------------------------------------------------------- /template/vue-project/typings/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare interface ImportMetaEnv { 4 | readonly VITE_MODE_TEXT: string 5 | readonly VITE_HELLO: string 6 | } 7 | 8 | declare interface ImportMeta { 9 | readonly env: ImportMetaEnv 10 | } 11 | 12 | // 主进程环境变量 13 | declare namespace NodeJS { 14 | export interface ProcessEnv { 15 | readonly NODE_ENV: 'development' | 'production' 16 | readonly RENDER_PORT?: string 17 | readonly VITE_HELLO: string 18 | readonly VITE_MODE_TEXT: string 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /template/vue-project/typings/global.d.ts: -------------------------------------------------------------------------------- 1 | interface Window { 2 | $ipc: import('@quiteer/electron-preload').PreloadIpc & import('@quiteer/electron-ipc/web').ExpandPreloadIpc 3 | $clipboard: import('@quiteer/electron-preload').PreloadClipboard 4 | $webFrame: import('@quiteer/electron-preload').PreloadWebFrame 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | include: ['**/__tests__/**/*.spec.[tj]s'], 6 | exclude: [ 7 | '**/node_modules/**', 8 | '**/dist/**', 9 | './playground/**/*.*' 10 | ], 11 | testTimeout: 20000, 12 | // node14 segfaults often with threads 13 | threads: !process.versions.node.startsWith('14') 14 | }, 15 | esbuild: { 16 | target: 'node14' 17 | } 18 | }) 19 | --------------------------------------------------------------------------------