├── .changelogrc.js ├── .commitlintrc.js ├── .editorconfig ├── .eslintrc.js ├── .github └── workflows │ ├── auto-merge.yml │ ├── release.yml │ └── test.yml ├── .gitignore ├── .husky ├── .gitignore ├── commit-msg └── pre-commit ├── .npmrc ├── .prettierignore ├── .prettierrc.js ├── .releaserc.js ├── .stylelintrc.js ├── CHANGELOG.md ├── LICENSE ├── README.md ├── docs ├── communication.md ├── guide.md └── structure │ ├── index.md │ ├── main.md │ └── renderer.md ├── mock └── .gitkeep ├── package.json ├── packages ├── common │ ├── .fatherrc.ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── types │ │ │ ├── browser.ts │ │ │ ├── events.ts │ │ │ └── index.ts │ │ └── utils │ │ │ ├── env.ts │ │ │ ├── index.ts │ │ │ ├── is.ts │ │ │ └── request.ts │ └── tsconfig.json ├── main │ ├── build │ │ ├── Icon.icns │ │ ├── background.png │ │ ├── developer-id-app-certs.p12 │ │ ├── embedded.provisionprofile │ │ ├── entitlements.mac.plist │ │ ├── entitlements.mas.inherit.plist │ │ ├── entitlements.mas.loginhelper.plist │ │ ├── entitlements.mas.plist │ │ ├── icon.ico │ │ ├── icon.png │ │ ├── installerIcon.ico │ │ ├── license.txt │ │ └── volume.icns │ ├── electron-builder.config.js │ ├── electron.vite.config.ts │ ├── package.json │ ├── scripts │ │ └── zombieRender │ │ │ └── index.html │ ├── src │ │ ├── browserItems.ts │ │ ├── core │ │ │ ├── App.ts │ │ │ ├── Browser.ts │ │ │ ├── BrowserManager.ts │ │ │ ├── Logger │ │ │ │ ├── config.ts │ │ │ │ ├── customLogger.ts │ │ │ │ ├── index.ts │ │ │ │ ├── logDecorator.ts │ │ │ │ └── types.ts │ │ │ └── ServiceStorage.ts │ │ ├── index.ts │ │ ├── services │ │ │ ├── SystemService.ts │ │ │ ├── UserService.ts │ │ │ └── index.ts │ │ └── utils │ │ │ ├── AutoUpdater.ts │ │ │ ├── createProtocol.ts │ │ │ ├── index.ts │ │ │ └── log.ts │ ├── tsconfig-check.json │ ├── tsconfig.json │ └── types │ │ └── Logger.d.ts ├── preload │ ├── package.json │ └── src │ │ └── index.ts └── renderer │ ├── .umirc.ts │ ├── package.json │ ├── src │ ├── hooks │ │ ├── index.ts │ │ ├── useAppEvent.ts │ │ ├── useDarkMode.ts │ │ └── useMainProcess.ts │ ├── layouts │ │ ├── BasicLayout.tsx │ │ └── style.ts │ ├── pages │ │ ├── database │ │ │ ├── index.tsx │ │ │ └── style.ts │ │ └── home │ │ │ ├── index.tsx │ │ │ └── style.ts │ ├── store │ │ └── theme.ts │ └── utils │ │ ├── dispatch.ts │ │ ├── index.ts │ │ └── route.ts │ ├── tsconfig-check.json │ └── tsconfig.json ├── pnpm-workspace.yaml ├── renovate.json ├── scripts ├── buildMacZip.ts └── update-electron-vendors.mjs ├── tsconfig.json ├── types └── index.d.ts └── version ├── getVersion.mjs └── inject-app-version-plugin.mjs /.changelogrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | scopeDisplayName: { 3 | script: '脚本', 4 | deps: '依赖', 5 | 'deps-dev': '依赖', 6 | scripts: '脚本', 7 | changelog: '日志', 8 | config: '配置', 9 | release: '自动发布', 10 | types: '类型', 11 | readme: '说明文档', 12 | }, 13 | titleLanguage: 'zh-CN', 14 | }; 15 | -------------------------------------------------------------------------------- /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['gitmoji'], 3 | }; 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [license.txt] 16 | charset = GB2312 17 | 18 | [Makefile] 19 | indent_style = tab 20 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // const config = require('@umijs/lint/dist/config/eslint'); 2 | 3 | module.exports = require('@umijs/lint/dist/config/eslint'); 4 | -------------------------------------------------------------------------------- /.github/workflows/auto-merge.yml: -------------------------------------------------------------------------------- 1 | name: Dependabot Auto Merge 2 | on: 3 | pull_request_target: 4 | types: [labeled, edited] 5 | 6 | jobs: 7 | test: 8 | if: contains(github.event.pull_request.labels.*.name, 'dependencies') 9 | name: Dependabot Auto Merge 10 | runs-on: ${{ matrix.os }} 11 | strategy: 12 | matrix: 13 | os: [macos-latest, windows-latest] 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Setup Node.js environment 17 | uses: actions/setup-node@v2.1.2 18 | with: 19 | node-version: '14' 20 | 21 | - uses: c-hive/gha-yarn-cache@v1 22 | - run: yarn 23 | - run: yarn lint 24 | 25 | merge: 26 | needs: test 27 | name: Dependabot Auto Merge 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: ahmadnassri/action-dependabot-auto-merge@v2 31 | with: 32 | command: merge 33 | target: minor 34 | github-token: ${{ secrets.GH_TOKEN }} 35 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | branches: 5 | - master 6 | - beta 7 | 8 | jobs: 9 | precheck: 10 | continue-on-error: true # 如果这个这个 job 挂了继续往下走 11 | runs-on: ubuntu-latest 12 | # Map a step output to a job output 13 | outputs: 14 | should_skip: ${{ steps.skip_check.outputs.should_skip }} 15 | steps: 16 | - id: skip_check 17 | # 这个 action 可以 cancel 掉先前运行的 action 18 | # 使得运行的脚本始终是最新的 commit 19 | # https://github.com/marketplace/actions/skip-duplicate-actions 20 | uses: fkirc/skip-duplicate-actions@master 21 | with: 22 | skip_after_successful_duplicate: 'true' 23 | paths_ignore: '["**/README.md", "**/docs/**"]' 24 | 25 | test: 26 | name: Code quality check 27 | needs: precheck 28 | runs-on: ${{ matrix.os }} 29 | strategy: 30 | matrix: 31 | os: [macos-latest, windows-latest] 32 | steps: 33 | - uses: actions/checkout@v3 34 | 35 | - name: Install pnpm 36 | uses: pnpm/action-setup@v2 37 | with: 38 | version: 8 39 | 40 | - name: Setup Node.js environment 41 | uses: actions/setup-node@v3 42 | with: 43 | node-version: '18' 44 | 45 | - name: Install deps 46 | run: pnpm install 47 | 48 | - name: lint 49 | run: pnpm run lint 50 | 51 | check: 52 | needs: precheck 53 | name: Release check 54 | runs-on: ubuntu-latest 55 | outputs: 56 | # 将 semantic 输出的值作为下一环节的输入 57 | is_new_version: ${{ steps.semantic.outputs.new_release_published }} # ! MUST BE STRING 58 | version: ${{ steps.semantic.outputs.new_release_version }} 59 | steps: 60 | - uses: actions/checkout@v2 61 | 62 | - name: Semantic Release with dryRun 63 | uses: cycjimmy/semantic-release-action@v3 64 | id: semantic 65 | with: 66 | dry_run: true 67 | extra_plugins: semantic-release-config-gitmoji 68 | env: 69 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 70 | 71 | build: 72 | needs: [check, test] 73 | name: Build 74 | if: needs.check.outputs.is_new_version == 'true' 75 | runs-on: ${{ matrix.os }} 76 | strategy: 77 | matrix: 78 | os: [macos-latest, windows-latest] 79 | steps: 80 | - uses: actions/checkout@v3 81 | 82 | - name: Install pnpm 83 | uses: pnpm/action-setup@v2 84 | with: 85 | version: 8 86 | 87 | - name: Setup Node.js environment 88 | uses: actions/setup-node@v3 89 | with: 90 | node-version: '18' 91 | 92 | - name: Install deps 93 | run: pnpm install 94 | 95 | - name: Tricky version 96 | run: npx npe version ${{ needs.check.outputs.version }} 97 | 98 | - name: Build artifact on macOS 99 | if: runner.os == 'macOS' 100 | run: yarn build --publish never # 不使用发包配置 https://www.electron.build/configuration/publish#how-to-publish 101 | env: 102 | # 导入证书环境 有了签名可以保证 electron 在需要授权时使用的是同一个身份 id 103 | # Ref https://www.electron.build/code-signing 104 | CSC_LINK: ./build/developer-id-app-certs.p12 105 | CSC_KEY_PASSWORD: ${{ secrets.APPLE_APP_CERTS_PASSWORD }} 106 | # 针对 macOS 提供 APPLE_ID 和 APPLE_ID_PASSWORD 进行 DMG 公证 107 | APPLE_ID: ${{ secrets.APPLE_ID }} 108 | APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} 109 | 110 | # 目前由于 electron-builder 在 10.15 版本打 zip 包存在 bug 111 | # 详见 https://github.com/electron-userland/electron-builder/issues/4299 112 | # 所以需要手动完成 zip 包的制作 113 | - name: Build zip artifact on macOS 114 | if: runner.os == 'macOS' 115 | run: pnpm run build:mac-zip 116 | 117 | - name: Build artifact on other Platform 118 | if: runner.os != 'macOS' 119 | run: pnpm run build --publish never # 不使用发包配置 https://www.electron.build/configuration/publish#how-to-publish 120 | 121 | - name: Upload artifact 122 | uses: actions/upload-artifact@v2 123 | with: 124 | name: release 125 | path: | 126 | release/latest* 127 | release/umi*.dmg* 128 | release/umi*.zip* 129 | release/umi*.exe* 130 | release/umi*.AppImage 131 | 132 | status: 133 | needs: check 134 | runs-on: ubuntu-latest 135 | name: Release Status 136 | steps: 137 | - name: Release Status 138 | run: echo "🚦New Verison Release Status -> ${{ needs.check.outputs.is_new_version }}" 139 | - name: Release Version 140 | run: echo "🚦New Verison Release Version -> ${{ needs.check.outputs.version }}" 141 | 142 | list: 143 | needs: build 144 | name: List Artifact 145 | runs-on: ubuntu-latest 146 | steps: 147 | - name: Download artifact 148 | uses: actions/download-artifact@v2 149 | with: 150 | name: release 151 | path: release 152 | 153 | - name: List artifact 154 | run: ls -al release 155 | 156 | publish: 157 | if: "! contains(github.event.head_commit.message, '[skip ci]')" 158 | needs: build 159 | name: Semantic release 160 | runs-on: ubuntu-latest 161 | steps: 162 | - uses: actions/checkout@v2 163 | 164 | - name: Download artifact 165 | uses: actions/download-artifact@v2 166 | with: 167 | name: release 168 | path: release 169 | 170 | - name: List artifact 171 | run: ls -al release 172 | 173 | - name: Release 174 | uses: cycjimmy/semantic-release-action@v3 175 | with: 176 | extra_plugins: semantic-release-config-gitmoji 177 | env: 178 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 179 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test CI 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | test: 6 | name: Code quality check 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | os: [macos-latest, windows-latest] 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - name: Install pnpm 15 | uses: pnpm/action-setup@v2 16 | with: 17 | version: 8 18 | 19 | - name: Setup Node.js environment 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: '18' 23 | 24 | - name: Install deps 25 | run: pnpm install 26 | 27 | - name: lint 28 | run: pnpm run lint 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 3 | 4 | # dependencies 5 | **/node_modules 6 | 7 | # production 8 | /dist 9 | /.vscode 10 | 11 | # misc 12 | .DS_Store 13 | npm-debug.log* 14 | yarn-error.log 15 | 16 | /coverage 17 | .idea 18 | *bak 19 | .vscode 20 | 21 | # visual studio code 22 | .history 23 | *.log 24 | functions/* 25 | .temp/** 26 | 27 | node_modules 28 | dist 29 | 30 | .umi 31 | .umi-* 32 | 33 | release 34 | .env* 35 | coverage 36 | /.eslintcache 37 | .electron-vendors.cache.json 38 | lib 39 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx --no-install commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install lint-staged 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | electron_mirror=https://npmmirror.com/mirrors/electron/ 2 | lockfile=false 3 | resolution-mode=highest 4 | shamefully-hoist=true 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .umi 2 | .umi-production 3 | .umi-test 4 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@umijs/max/prettier'); 2 | -------------------------------------------------------------------------------- /.releaserc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | //负责解析 commit 4 | [ 5 | '@semantic-release/commit-analyzer', 6 | { 7 | // 自定义配置,如果不填则是默认的 conventional-changelog-angular 8 | config: 'conventional-changelog-gitmoji-config', 9 | }, 10 | ], 11 | [ 12 | '@semantic-release/release-notes-generator', //此处生成 github-release 的日志 13 | { 14 | //指定配置,这里才是负责生成日志的,也就是说,如果自定义了writerOpts,只有在这里写才会生效 15 | config: 'conventional-changelog-gitmoji-config', 16 | }, 17 | ], 18 | [ 19 | '@semantic-release/changelog', //此处会调用上一个插件生成的新增日志,然后合并到原有日志中 20 | { 21 | changelogFile: 'CHANGELOG.md', 22 | changelogTitle: '# Umi Electron Template 更新日志', 23 | }, 24 | ], 25 | '@semantic-release/npm', // 自动更新版本号,如果是 npm 模块则会触发发布流程 26 | // 在 github 发布 Release 版本 27 | [ 28 | '@semantic-release/github', 29 | { 30 | assets: ['release'], 31 | }, 32 | ], 33 | // 推送代码回 git 34 | [ 35 | '@semantic-release/git', 36 | { 37 | assets: ['CHANGELOG.md', 'package.json'], 38 | message: 39 | ':bookmark: chore(release): ${nextRelease.gitTag} [skip ci] \n\n${nextRelease.notes}', 40 | }, 41 | ], 42 | ], 43 | }; 44 | -------------------------------------------------------------------------------- /.stylelintrc.js: -------------------------------------------------------------------------------- 1 | const fabric = require('@umijs/fabric'); 2 | 3 | module.exports = { 4 | ...fabric.stylelint, 5 | rules: { 6 | 'no-invalid-double-slash-comments': null, 7 | 'function-name-case': null, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Umi Electron Template 更新日志 2 | 3 | # [2.0.0](https://github.com/arvinxx/umi-electron-template/compare/v1.9.1...v2.0.0) (2021-09-05) 4 | 5 | 6 | ### ♻ 重构 7 | 8 | * 重构架构框 ([cb6958e](https://github.com/arvinxx/umi-electron-template/commit/cb6958e)) 9 | 10 | 11 | ### 🎫 杂项 12 | 13 | * 优化部分细节 ([41b8a1d](https://github.com/arvinxx/umi-electron-template/commit/41b8a1d)) 14 | * 更新 umi-plugin-electron-builder 依赖 ([c5d2681](https://github.com/arvinxx/umi-electron-template/commit/c5d2681)) 15 | * 调整 release 配置 ([a9d97a1](https://github.com/arvinxx/umi-electron-template/commit/a9d97a1)) 16 | * 调整 release 配置 ([8b95be0](https://github.com/arvinxx/umi-electron-template/commit/8b95be0)) 17 | * 调整 release 配置 ([0772d64](https://github.com/arvinxx/umi-electron-template/commit/0772d64)) 18 | * 调整配置 ([ba7e1ca](https://github.com/arvinxx/umi-electron-template/commit/ba7e1ca)) 19 | * 调整配置 ([06f3fcf](https://github.com/arvinxx/umi-electron-template/commit/06f3fcf)) 20 | 21 | 22 | ### 🐛 修复 23 | 24 | * 修复 macOS 下开发 electron 部分会重启的 bug ([07de636](https://github.com/arvinxx/umi-electron-template/commit/07de636)) 25 | * 修正 v2 版本插件的 bug ([3a86f3c](https://github.com/arvinxx/umi-electron-template/commit/3a86f3c)) 26 | 27 | 28 | ### 👷 构建系统 29 | 30 | * 优化配置项 ([fe276d3](https://github.com/arvinxx/umi-electron-template/commit/fe276d3)) 31 | 32 | 33 | ### 📝 文档 34 | 35 | * 补充说明 ([f6bd7fc](https://github.com/arvinxx/umi-electron-template/commit/f6bd7fc)) 36 | * **说明文档**: 调整说明文档 ([139e1b9](https://github.com/arvinxx/umi-electron-template/commit/139e1b9)) 37 | 38 | 39 | ### 🔧 持续集成 40 | 41 | * 修正 auto-merge 报错 ([02e615b](https://github.com/arvinxx/umi-electron-template/commit/02e615b)) 42 | * 修正 lint ci ([889c469](https://github.com/arvinxx/umi-electron-template/commit/889c469)) 43 | * 修正自动 merge 的问题 ([89d463a](https://github.com/arvinxx/umi-electron-template/commit/89d463a)) 44 | * 调整 release ci 配置 ([f9979fa](https://github.com/arvinxx/umi-electron-template/commit/f9979fa)) 45 | * 调整 release ci 配置 ([9ed3995](https://github.com/arvinxx/umi-electron-template/commit/9ed3995)) 46 | * 调整 release ci 配置 ([1233a8b](https://github.com/arvinxx/umi-electron-template/commit/1233a8b)) 47 | 48 | 49 | ### 💥 BREAKING CHANGES 50 | 51 | * 重构框架 52 | 53 | ## [1.9.1](https://github.com/arvinxx/umi-electron-template/compare/v1.9.0...v1.9.1) (2021-02-20) 54 | 55 | 56 | ### 🐛 修复 57 | 58 | * 回退 umi-plugin-electron-builder 版本修复打开报错 ([14528d2](https://github.com/arvinxx/umi-electron-template/commit/14528d2)) 59 | 60 | 61 | ### 👷 构建系统 62 | 63 | * 修正 zip 包构建 bug ([401b2db](https://github.com/arvinxx/umi-electron-template/commit/401b2db)) 64 | 65 | # [1.9.0](https://github.com/arvinxx/umi-electron-template/compare/v1.8.2...v1.9.0) (2021-02-20) 66 | 67 | 68 | ### ✨ 新特性 69 | 70 | * 添加一个原生依赖 robotjs ([ef7489b](https://github.com/arvinxx/umi-electron-template/commit/ef7489b)) 71 | 72 | 73 | ### 🎫 杂项 74 | 75 | * 修改数据库名称 ([2cffdea](https://github.com/arvinxx/umi-electron-template/commit/2cffdea)) 76 | * 修正 umi type alias ([1d9ab90](https://github.com/arvinxx/umi-electron-template/commit/1d9ab90)) 77 | * 修正 umi type 导出配置 ([420cf2c](https://github.com/arvinxx/umi-electron-template/commit/420cf2c)) 78 | * 更新双目录架构配置项 ([2e955c3](https://github.com/arvinxx/umi-electron-template/commit/2e955c3)) 79 | * 调整 postinstall 的 APP_ROOT ([b5cafb4](https://github.com/arvinxx/umi-electron-template/commit/b5cafb4)) 80 | 81 | 82 | ### 👷 构建系统 83 | 84 | * **依赖**: bump @ant-design/icons from 4.4.0 to 4.5.0 ([6785859](https://github.com/arvinxx/umi-electron-template/commit/6785859)) 85 | * **依赖**: bump @types/node from 12.20.1 to 14.14.30 ([04085e6](https://github.com/arvinxx/umi-electron-template/commit/04085e6)) 86 | * **依赖**: bump @types/node from 14.14.25 to 14.14.27 ([ab14991](https://github.com/arvinxx/umi-electron-template/commit/ab14991)) 87 | * **依赖**: bump @types/node from 14.14.27 to 14.14.28 ([7b16385](https://github.com/arvinxx/umi-electron-template/commit/7b16385)) 88 | * **依赖**: bump @types/react from 17.0.1 to 17.0.2 ([893e2ff](https://github.com/arvinxx/umi-electron-template/commit/893e2ff)) 89 | * **依赖**: bump @types/react-dom from 17.0.0 to 17.0.1 ([6f1ab40](https://github.com/arvinxx/umi-electron-template/commit/6f1ab40)) 90 | * **依赖**: bump @types/react-test-renderer from 17.0.0 to 17.0.1 ([3245b25](https://github.com/arvinxx/umi-electron-template/commit/3245b25)) 91 | * **依赖**: bump antd from 4.12.2 to 4.12.3 ([1f7841e](https://github.com/arvinxx/umi-electron-template/commit/1f7841e)) 92 | * **依赖**: bump eslint from 7.19.0 to 7.20.0 ([9340361](https://github.com/arvinxx/umi-electron-template/commit/9340361)) 93 | * **依赖**: bump semantic-release from 17.3.7 to 17.3.8 ([6fb1371](https://github.com/arvinxx/umi-electron-template/commit/6fb1371)) 94 | * **依赖**: bump semantic-release from 17.3.8 to 17.3.9 ([c56782e](https://github.com/arvinxx/umi-electron-template/commit/c56782e)) 95 | * **依赖**: bump ts-jest from 26.5.0 to 26.5.1 ([ccca464](https://github.com/arvinxx/umi-electron-template/commit/ccca464)) 96 | * **依赖**: bump typeorm from 0.2.30 to 0.2.31 ([bde6b12](https://github.com/arvinxx/umi-electron-template/commit/bde6b12)) 97 | * **依赖**: bump typescript from 4.1.3 to 4.1.4 ([b3e4997](https://github.com/arvinxx/umi-electron-template/commit/b3e4997)) 98 | * **依赖**: bump typescript from 4.1.4 to 4.1.5 ([05cd9f3](https://github.com/arvinxx/umi-electron-template/commit/05cd9f3)) 99 | * **依赖**: bump umi-plugin-electron-builder from 1.0.1 to 1.0.2 ([d4e93f3](https://github.com/arvinxx/umi-electron-template/commit/d4e93f3)) 100 | * **依赖**: bump umi-plugin-electron-builder from 1.0.15 to 1.0.16 ([1dc7ec6](https://github.com/arvinxx/umi-electron-template/commit/1dc7ec6)) 101 | * **依赖**: bump umi-plugin-electron-builder from 1.0.2 to 1.0.15 ([a46b61c](https://github.com/arvinxx/umi-electron-template/commit/a46b61c)) 102 | 103 | 104 | ### 🔧 持续集成 105 | 106 | * 取消 linux 环境 ([86cd967](https://github.com/arvinxx/umi-electron-template/commit/86cd967)) 107 | * 更新缓存 action ([f51de03](https://github.com/arvinxx/umi-electron-template/commit/f51de03)) 108 | * 测试缓存 action ([6e4e848](https://github.com/arvinxx/umi-electron-template/commit/6e4e848)) 109 | * 调整 release commit 内容 ([d673b8b](https://github.com/arvinxx/umi-electron-template/commit/d673b8b)) 110 | 111 | 112 | ### wip 113 | 114 | * 更新双目录结构配置 ([329e19f](https://github.com/arvinxx/umi-electron-template/commit/329e19f)) 115 | 116 | ## [1.8.2](https://github.com/arvinxx/umi-electron-template/compare/v1.8.1...v1.8.2) (2021-02-09) 117 | 118 | 119 | ### ♻ 重构 120 | 121 | * 重构开发框架 ([c218ccd](https://github.com/arvinxx/umi-electron-template/commit/c218ccd)) 122 | 123 | 124 | ### 🎫 杂项 125 | 126 | * **脚本**: 修改开发脚本 ([6087cbe](https://github.com/arvinxx/umi-electron-template/commit/6087cbe)) 127 | 128 | 129 | ### 🐛 修复 130 | 131 | * 修复数据库链接问题 ([4d90e2f](https://github.com/arvinxx/umi-electron-template/commit/4d90e2f)) 132 | 133 | 134 | ### 👷 构建系统 135 | 136 | * **依赖**: bump electron from 11.2.2 to 11.2.3 ([4f1b48b](https://github.com/arvinxx/umi-electron-template/commit/4f1b48b)) 137 | 138 | 139 | ### 📝 文档 140 | 141 | * **说明文档**: 补充说明文档 ([89268e3](https://github.com/arvinxx/umi-electron-template/commit/89268e3)) 142 | 143 | 144 | ### 🔧 持续集成 145 | 146 | * 修复测试脚本 ([4e58260](https://github.com/arvinxx/umi-electron-template/commit/4e58260)) 147 | 148 | ## [1.8.1](https://github.com/arvinxx/umi-electron-template/compare/v1.8.0...v1.8.1) (2021-02-06) 149 | 150 | 151 | ### 🎫 杂项 152 | 153 | * **自动发布**: v1.8.1-beta.1 [skip ci] ([584bd64](https://github.com/arvinxx/umi-electron-template/commit/584bd64)) 154 | * **自动发布**: v1.8.1-beta.2 [skip ci] ([eca969b](https://github.com/arvinxx/umi-electron-template/commit/eca969b)) 155 | 156 | 157 | ### 🐛 修复 158 | 159 | * 优化发布流程 ([6a2e586](https://github.com/arvinxx/umi-electron-template/commit/6a2e586)) 160 | * 优化流程 ([9b2303d](https://github.com/arvinxx/umi-electron-template/commit/9b2303d)) 161 | 162 | 163 | ### 🔧 持续集成 164 | 165 | * 优化 release 流程 ([6b91bab](https://github.com/arvinxx/umi-electron-template/commit/6b91bab)) 166 | * 优化 Release 流程 ([1b2e3b3](https://github.com/arvinxx/umi-electron-template/commit/1b2e3b3)) 167 | * 优化发布流程 ([227fac1](https://github.com/arvinxx/umi-electron-template/commit/227fac1)) 168 | * 优化发布流程 ([0e45c2d](https://github.com/arvinxx/umi-electron-template/commit/0e45c2d)) 169 | * 优化发布流程 ([2d02df5](https://github.com/arvinxx/umi-electron-template/commit/2d02df5)) 170 | * 优化发布流程 ([f54f2bb](https://github.com/arvinxx/umi-electron-template/commit/f54f2bb)) 171 | * 优化发布流程 ([eb5cdce](https://github.com/arvinxx/umi-electron-template/commit/eb5cdce)) 172 | * 优化缓存流程 ([d0c0943](https://github.com/arvinxx/umi-electron-template/commit/d0c0943)) 173 | * 优化缓存流程 ([93a8445](https://github.com/arvinxx/umi-electron-template/commit/93a8445)) 174 | * 尝试新的 cache 路径 ([5dab8ab](https://github.com/arvinxx/umi-electron-template/commit/5dab8ab)) 175 | * 尝试新的 cache 路径 ([6f2a462](https://github.com/arvinxx/umi-electron-template/commit/6f2a462)) 176 | * 恢复之前的 cache 路径 ([36a8dd9](https://github.com/arvinxx/umi-electron-template/commit/36a8dd9)) 177 | 178 | ## [1.8.1-beta.2](https://github.com/arvinxx/umi-electron-template/compare/v1.8.1-beta.1...v1.8.1-beta.2) (2021-02-06) 179 | 180 | 181 | ### 🐛 修复 182 | 183 | * 优化发布流程 ([6a2e586](https://github.com/arvinxx/umi-electron-template/commit/6a2e586)) 184 | 185 | 186 | ### 🔧 持续集成 187 | 188 | * 优化发布流程 ([227fac1](https://github.com/arvinxx/umi-electron-template/commit/227fac1)) 189 | * 优化发布流程 ([0e45c2d](https://github.com/arvinxx/umi-electron-template/commit/0e45c2d)) 190 | * 优化发布流程 ([2d02df5](https://github.com/arvinxx/umi-electron-template/commit/2d02df5)) 191 | * 优化发布流程 ([f54f2bb](https://github.com/arvinxx/umi-electron-template/commit/f54f2bb)) 192 | * 优化发布流程 ([eb5cdce](https://github.com/arvinxx/umi-electron-template/commit/eb5cdce)) 193 | 194 | ## [1.8.1-beta.1](https://github.com/arvinxx/umi-electron-template/compare/v1.8.0...v1.8.1-beta.1) (2021-02-06) 195 | 196 | 197 | ### 🐛 修复 198 | 199 | * 优化流程 ([9b2303d](https://github.com/arvinxx/umi-electron-template/commit/9b2303d)) 200 | 201 | 202 | ### 🔧 持续集成 203 | 204 | * 优化 release 流程 ([6b91bab](https://github.com/arvinxx/umi-electron-template/commit/6b91bab)) 205 | * 优化 Release 流程 ([1b2e3b3](https://github.com/arvinxx/umi-electron-template/commit/1b2e3b3)) 206 | * 优化缓存流程 ([d0c0943](https://github.com/arvinxx/umi-electron-template/commit/d0c0943)) 207 | * 优化缓存流程 ([93a8445](https://github.com/arvinxx/umi-electron-template/commit/93a8445)) 208 | * 尝试新的 cache 路径 ([5dab8ab](https://github.com/arvinxx/umi-electron-template/commit/5dab8ab)) 209 | * 尝试新的 cache 路径 ([6f2a462](https://github.com/arvinxx/umi-electron-template/commit/6f2a462)) 210 | * 恢复之前的 cache 路径 ([36a8dd9](https://github.com/arvinxx/umi-electron-template/commit/36a8dd9)) 211 | 212 | # [1.8.0](https://github.com/arvinxx/umi-electron-template/compare/v1.7.2...v1.8.0) (2021-02-06) 213 | 214 | 215 | ### ✨ 新特性 216 | 217 | * 测试 electron updater ([d38d781](https://github.com/arvinxx/umi-electron-template/commit/d38d781)) 218 | * 测试添加自动更新能力 ([506e46e](https://github.com/arvinxx/umi-electron-template/commit/506e46e)) 219 | 220 | 221 | ### 🎫 杂项 222 | 223 | * 重新生成 yarn.lock 文件 ([6a31798](https://github.com/arvinxx/umi-electron-template/commit/6a31798)) 224 | * **自动发布**: v1.8.0-beta.4 [skip ci] ([2958653](https://github.com/arvinxx/umi-electron-template/commit/2958653)) 225 | * 修正 ci 脚本 ([9fc9d14](https://github.com/arvinxx/umi-electron-template/commit/9fc9d14)) 226 | * 重新生成 yarn.lock 文件 ([d16f139](https://github.com/arvinxx/umi-electron-template/commit/d16f139)) 227 | * 重新生成 yarn.lock 文件 ([610ed7c](https://github.com/arvinxx/umi-electron-template/commit/610ed7c)) 228 | * **ci**: 优化构建流程 ([595908d](https://github.com/arvinxx/umi-electron-template/commit/595908d)) 229 | * **ci**: 补充缓存生成 ([66c5f2b](https://github.com/arvinxx/umi-electron-template/commit/66c5f2b)) 230 | * **自动发布**: v1.8.0-beta.3 [skip ci] ([2361473](https://github.com/arvinxx/umi-electron-template/commit/2361473)) 231 | * 取消 registry 设置 ([53017ae](https://github.com/arvinxx/umi-electron-template/commit/53017ae)) 232 | * **自动发布**: v1.8.0-beta.2 [skip ci] ([d781be1](https://github.com/arvinxx/umi-electron-template/commit/d781be1)) 233 | * 修复 macOS 环境 ([bb15f9d](https://github.com/arvinxx/umi-electron-template/commit/bb15f9d)) 234 | * 修复没有引入 ts-node 的错误 ([de23bb2](https://github.com/arvinxx/umi-electron-template/commit/de23bb2)) 235 | * 重新生成 yarn.lock 文件 ([4a32125](https://github.com/arvinxx/umi-electron-template/commit/4a32125)) 236 | * **自动发布**: v1.8.0-beta.1 [skip ci] ([2a99c10](https://github.com/arvinxx/umi-electron-template/commit/2a99c10)) 237 | 238 | 239 | ### 🐛 修复 240 | 241 | * 优化错误日志的生成地址 ([afea89d](https://github.com/arvinxx/umi-electron-template/commit/afea89d)) 242 | * 修复 macOS 生成的压缩包 ([9509a2d](https://github.com/arvinxx/umi-electron-template/commit/9509a2d)) 243 | * 修正 mac 平台下 zip 包无法打开的问题 ([1b270b4](https://github.com/arvinxx/umi-electron-template/commit/1b270b4)) 244 | * 调整 publish 配置 ([ba4311e](https://github.com/arvinxx/umi-electron-template/commit/ba4311e)) 245 | 246 | 247 | ### 📝 文档 248 | 249 | * 更新文档 ([d16bd18](https://github.com/arvinxx/umi-electron-template/commit/d16bd18)) 250 | 251 | 252 | ### 🔧 持续集成 253 | 254 | * 优化 ci 流程 ([b21fb03](https://github.com/arvinxx/umi-electron-template/commit/b21fb03)) 255 | * 优化 ci 流程 ([2b4705b](https://github.com/arvinxx/umi-electron-template/commit/2b4705b)) 256 | * 优化 ci 流程 ([3b30986](https://github.com/arvinxx/umi-electron-template/commit/3b30986)) 257 | * 优化 ci 缓存配置 ([a6cc26a](https://github.com/arvinxx/umi-electron-template/commit/a6cc26a)) 258 | * 优化 ci 配置 ([c5181ba](https://github.com/arvinxx/umi-electron-template/commit/c5181ba)) 259 | * 优化 Release 流程 ([83f06e2](https://github.com/arvinxx/umi-electron-template/commit/83f06e2)) 260 | * 优化 Release 流程 ([71b441c](https://github.com/arvinxx/umi-electron-template/commit/71b441c)) 261 | * 优化发版 ci 流程 ([93835bd](https://github.com/arvinxx/umi-electron-template/commit/93835bd)) 262 | * 优化缓存 ([956c62b](https://github.com/arvinxx/umi-electron-template/commit/956c62b)) 263 | * 优化缓存 ([7d95f3a](https://github.com/arvinxx/umi-electron-template/commit/7d95f3a)) 264 | * 优化缓存 ([c3101d5](https://github.com/arvinxx/umi-electron-template/commit/c3101d5)) 265 | * 优化缓存策略 ([f8574f3](https://github.com/arvinxx/umi-electron-template/commit/f8574f3)) 266 | * 优化缓存策略 ([ddf2970](https://github.com/arvinxx/umi-electron-template/commit/ddf2970)) 267 | * 优化缓存设置 ([7f9d088](https://github.com/arvinxx/umi-electron-template/commit/7f9d088)) 268 | * 优化缓存速度 ([e244c7b](https://github.com/arvinxx/umi-electron-template/commit/e244c7b)) 269 | * 优化缓存配置 ([e9678a7](https://github.com/arvinxx/umi-electron-template/commit/e9678a7)) 270 | * 修复 lint 错误 ([c8288a0](https://github.com/arvinxx/umi-electron-template/commit/c8288a0)) 271 | * 修复 macOS CI 环境 Bug ([0619224](https://github.com/arvinxx/umi-electron-template/commit/0619224)) 272 | * 修复测试 ci 配置 ([8799639](https://github.com/arvinxx/umi-electron-template/commit/8799639)) 273 | * 修复测试 ci 配置 ([8c439cd](https://github.com/arvinxx/umi-electron-template/commit/8c439cd)) 274 | * 修复配置 ([f7953a3](https://github.com/arvinxx/umi-electron-template/commit/f7953a3)) 275 | * 修复配置 ([7f8b3a3](https://github.com/arvinxx/umi-electron-template/commit/7f8b3a3)) 276 | * 修改缓存路径 ([11e6a91](https://github.com/arvinxx/umi-electron-template/commit/11e6a91)) 277 | * 修改缓存路径 ([225588f](https://github.com/arvinxx/umi-electron-template/commit/225588f)) 278 | * 修改缓存路径 ([e828893](https://github.com/arvinxx/umi-electron-template/commit/e828893)) 279 | * 修改缓存路径 ([566d7ec](https://github.com/arvinxx/umi-electron-template/commit/566d7ec)) 280 | * 修改缓存路径 ([e120ef2](https://github.com/arvinxx/umi-electron-template/commit/e120ef2)) 281 | * 复用 ci 缓存 ([3291373](https://github.com/arvinxx/umi-electron-template/commit/3291373)) 282 | * 尝试优化缓存速度 ([ad03e64](https://github.com/arvinxx/umi-electron-template/commit/ad03e64)) 283 | * 尝试修正 ci 流程 ([2251095](https://github.com/arvinxx/umi-electron-template/commit/2251095)) 284 | * 尝试修正缓存无法命中的问题 ([b946626](https://github.com/arvinxx/umi-electron-template/commit/b946626)) 285 | * 尝试移除 lock 文件 ([631f879](https://github.com/arvinxx/umi-electron-template/commit/631f879)) 286 | * 尝试移除 lock 文件 ([d122c86](https://github.com/arvinxx/umi-electron-template/commit/d122c86)) 287 | * 尝试移除 lock 文件 ([9aeeacc](https://github.com/arvinxx/umi-electron-template/commit/9aeeacc)) 288 | * 测试 cached-dependencies ([9a3ef98](https://github.com/arvinxx/umi-electron-template/commit/9a3ef98)) 289 | * 清理 test ci 流程 ([97d1e64](https://github.com/arvinxx/umi-electron-template/commit/97d1e64)) 290 | * 细化缓存类型 ([afb8a52](https://github.com/arvinxx/umi-electron-template/commit/afb8a52)) 291 | * 细化缓存类型 ([1798a61](https://github.com/arvinxx/umi-electron-template/commit/1798a61)) 292 | * 补充 yarn cache 路径 ([bd4f7c0](https://github.com/arvinxx/umi-electron-template/commit/bd4f7c0)) 293 | * 补充 yarn cache 路径 ([cc0cf63](https://github.com/arvinxx/umi-electron-template/commit/cc0cf63)) 294 | 295 | # [1.8.0-beta.4](https://github.com/arvinxx/umi-electron-template/compare/v1.8.0-beta.3...v1.8.0-beta.4) (2021-02-05) 296 | 297 | 298 | ### 🎫 杂项 299 | 300 | * 重新生成 yarn.lock 文件 ([d16f139](https://github.com/arvinxx/umi-electron-template/commit/d16f139)) 301 | * 重新生成 yarn.lock 文件 ([610ed7c](https://github.com/arvinxx/umi-electron-template/commit/610ed7c)) 302 | 303 | 304 | ### 🐛 修复 305 | 306 | * 调整 publish 配置 ([ba4311e](https://github.com/arvinxx/umi-electron-template/commit/ba4311e)) 307 | 308 | 309 | ### 🔧 持续集成 310 | 311 | * 优化缓存设置 ([7f9d088](https://github.com/arvinxx/umi-electron-template/commit/7f9d088)) 312 | 313 | # [1.8.0-beta.3](https://github.com/arvinxx/umi-electron-template/compare/v1.8.0-beta.2...v1.8.0-beta.3) (2021-02-05) 314 | 315 | 316 | ### 🎫 杂项 317 | 318 | * 取消 registry 设置 ([53017ae](https://github.com/arvinxx/umi-electron-template/commit/53017ae)) 319 | 320 | 321 | ### 🐛 修复 322 | 323 | * 修复 macOS 生成的压缩包 ([9509a2d](https://github.com/arvinxx/umi-electron-template/commit/9509a2d)) 324 | 325 | 326 | ### 📝 文档 327 | 328 | * 更新文档 ([d16bd18](https://github.com/arvinxx/umi-electron-template/commit/d16bd18)) 329 | 330 | # [1.8.0-beta.2](https://github.com/arvinxx/umi-electron-template/compare/v1.8.0-beta.1...v1.8.0-beta.2) (2021-02-05) 331 | 332 | 333 | ### 🎫 杂项 334 | 335 | * 修复 macOS 环境 ([bb15f9d](https://github.com/arvinxx/umi-electron-template/commit/bb15f9d)) 336 | * 修复没有引入 ts-node 的错误 ([de23bb2](https://github.com/arvinxx/umi-electron-template/commit/de23bb2)) 337 | * 修正 ci 脚本 ([9fc9d14](https://github.com/arvinxx/umi-electron-template/commit/9fc9d14)) 338 | * 重新生成 yarn.lock 文件 ([4a32125](https://github.com/arvinxx/umi-electron-template/commit/4a32125)) 339 | * **ci**: 优化构建流程 ([595908d](https://github.com/arvinxx/umi-electron-template/commit/595908d)) 340 | * **ci**: 补充缓存生成 ([66c5f2b](https://github.com/arvinxx/umi-electron-template/commit/66c5f2b)) 341 | 342 | 343 | ### 🐛 修复 344 | 345 | * 修正 mac 平台下 zip 包无法打开的问题 ([1b270b4](https://github.com/arvinxx/umi-electron-template/commit/1b270b4)) 346 | 347 | 348 | ### 🔧 持续集成 349 | 350 | * 优化 ci 流程 ([3b30986](https://github.com/arvinxx/umi-electron-template/commit/3b30986)) 351 | * 优化 ci 配置 ([c5181ba](https://github.com/arvinxx/umi-electron-template/commit/c5181ba)) 352 | * 修复 macOS CI 环境 Bug ([0619224](https://github.com/arvinxx/umi-electron-template/commit/0619224)) 353 | * 修复测试 ci 配置 ([8799639](https://github.com/arvinxx/umi-electron-template/commit/8799639)) 354 | * 修复测试 ci 配置 ([8c439cd](https://github.com/arvinxx/umi-electron-template/commit/8c439cd)) 355 | 356 | # [1.8.0-beta.1](https://github.com/arvinxx/umi-electron-template/compare/v1.7.2...v1.8.0-beta.1) (2021-02-05) 357 | 358 | 359 | ### ✨ 新特性 360 | 361 | * **杂项**: 测试 electron updater ([d38d781](https://github.com/arvinxx/umi-electron-template/commit/d38d781)) 362 | * **杂项**: 测试添加自动更新能力 ([506e46e](https://github.com/arvinxx/umi-electron-template/commit/506e46e)) 363 | 364 | 365 | ### 🐛 修复 366 | 367 | * **杂项**: 优化错误日志的生成地址 ([afea89d](https://github.com/arvinxx/umi-electron-template/commit/afea89d)) 368 | 369 | 370 | ### 🔧 持续集成 371 | 372 | * **杂项**: 优化发版 ci 流程 ([93835bd](https://github.com/arvinxx/umi-electron-template/commit/93835bd)) 373 | 374 | ## [1.7.2](https://github.com/arvinxx/umi-electron-template/compare/v1.7.1...v1.7.2) (2021-02-05) 375 | 376 | 377 | ### ♻ 重构 378 | 379 | * **杂项**: 优化日志服务 ([a5379e4](https://github.com/arvinxx/umi-electron-template/commit/a5379e4)) 380 | * **杂项**: 重构成 IOC 模式 ([111f392](https://github.com/arvinxx/umi-electron-template/commit/111f392)) 381 | 382 | 383 | ### 🎫 杂项 384 | 385 | * **杂项**: 修正 lint 错误 ([e4a731c](https://github.com/arvinxx/umi-electron-template/commit/e4a731c)) 386 | 387 | 388 | ### 🐛 修复 389 | 390 | * **杂项**: 修正日志后缀 ([b1c915d](https://github.com/arvinxx/umi-electron-template/commit/b1c915d)) 391 | 392 | 393 | ### 👷 构建系统 394 | 395 | * **依赖**: bump @types/node from 14.14.22 to 14.14.25 ([0e5d6ac](https://github.com/arvinxx/umi-electron-template/commit/0e5d6ac)) 396 | * **依赖**: bump antd from 4.12.1 to 4.12.2 ([0b783dc](https://github.com/arvinxx/umi-electron-template/commit/0b783dc)) 397 | 398 | 399 | ### 📝 文档 400 | 401 | * **说明文档**: 优化说明文档 ([910e216](https://github.com/arvinxx/umi-electron-template/commit/910e216)) 402 | 403 | ## [1.7.1](https://github.com/arvinxx/umi-electron-template/compare/v1.7.0...v1.7.1) (2021-02-04) 404 | 405 | 406 | ### 🐛 修复 407 | 408 | * **build**: 修复构建后报模块无法找到的错误 ([69da161](https://github.com/arvinxx/umi-electron-template/commit/69da161)) 409 | 410 | # [1.7.0](https://github.com/arvinxx/umi-electron-template/compare/v1.6.0...v1.7.0) (2021-02-04) 411 | 412 | 413 | ### ♻ 重构 414 | 415 | * **杂项**: 重构 renderer 与 main 桥接部分 ([2428002](https://github.com/arvinxx/umi-electron-template/commit/2428002)) 416 | * **杂项**: 重构 renderer 与 main 桥接部分 ([5df427f](https://github.com/arvinxx/umi-electron-template/commit/5df427f)) 417 | * **杂项**: 重构 window 实现 ([88e498b](https://github.com/arvinxx/umi-electron-template/commit/88e498b)) 418 | 419 | 420 | ### ✨ 新特性 421 | 422 | * **杂项**: 为 renderer 添加日志记录能力 ([6db971f](https://github.com/arvinxx/umi-electron-template/commit/6db971f)) 423 | * **杂项**: 添加产品级日志能力 ([e8c7e8c](https://github.com/arvinxx/umi-electron-template/commit/e8c7e8c)) 424 | 425 | 426 | ### 🎫 杂项 427 | 428 | * **依赖**: 添加日志相关依赖 ([b4d21b1](https://github.com/arvinxx/umi-electron-template/commit/b4d21b1)) 429 | * **日志**: 补充日志配置项 ([0cd60ff](https://github.com/arvinxx/umi-electron-template/commit/0cd60ff)) 430 | 431 | 432 | ### 👷 构建系统 433 | 434 | * **依赖**: bump @ant-design/pro-layout from 6.13.0 to 6.14.0 ([0b69eac](https://github.com/arvinxx/umi-electron-template/commit/0b69eac)) 435 | * **依赖**: bump @types/react from 17.0.0 to 17.0.1 ([c751f1f](https://github.com/arvinxx/umi-electron-template/commit/c751f1f)) 436 | * **依赖**: bump ahooks from 2.9.4 to 2.9.6 ([61e553b](https://github.com/arvinxx/umi-electron-template/commit/61e553b)) 437 | * **依赖**: bump antd from 4.11.2 to 4.12.1 ([852acb5](https://github.com/arvinxx/umi-electron-template/commit/852acb5)) 438 | 439 | 440 | ### 📝 文档 441 | 442 | * **说明文档**: 优化说明文档 ([97e0f2f](https://github.com/arvinxx/umi-electron-template/commit/97e0f2f)) 443 | 444 | # [1.6.0](https://github.com/arvinxx/umi-electron-template/compare/v1.5.0...v1.6.0) (2021-02-03) 445 | 446 | 447 | ### ✨ 新特性 448 | 449 | * **杂项**: 构建 sqlite3 数据库能力 ([be96459](https://github.com/arvinxx/umi-electron-template/commit/be96459)) 450 | 451 | 452 | ### 🎫 杂项 453 | 454 | * **deps**: 回退 sqlite3 版本 ([3ad14e0](https://github.com/arvinxx/umi-electron-template/commit/3ad14e0)) 455 | * **日志**: 更改日志语言为中文 ([15a2155](https://github.com/arvinxx/umi-electron-template/commit/15a2155)) 456 | 457 | 458 | ### 👷 构建系统 459 | 460 | * **deps-dev**: bump @testing-library/react from 11.2.3 to 11.2.5 ([53e2fe6](https://github.com/arvinxx/umi-electron-template/commit/53e2fe6)) 461 | * **deps-dev**: bump electron from 11.2.1 to 11.2.2 ([d7efe64](https://github.com/arvinxx/umi-electron-template/commit/d7efe64)) 462 | 463 | 464 | ### 📝 文档 465 | 466 | * **说明文档**: 更新 README.md ([4000f69](https://github.com/arvinxx/umi-electron-template/commit/4000f69)) 467 | * **说明文档**: 更新模板特性 ([67b9256](https://github.com/arvinxx/umi-electron-template/commit/67b9256)) 468 | 469 | # [1.5.0](https://github.com/arvinxx/umi-electron-template/compare/v1.4.0...v1.5.0) (2021-02-03) 470 | 471 | 472 | ### ✨ Features 473 | 474 | * **杂项**: 添加数据持久化模型 ([4041874](https://github.com/arvinxx/umi-electron-template/commit/4041874)) 475 | 476 | 477 | ### 🎫 Chores 478 | 479 | * **日志**: 更改日志语言为中文 ([6491edd](https://github.com/arvinxx/umi-electron-template/commit/6491edd)) 480 | 481 | 482 | ### 🐛 Bug Fixes 483 | 484 | * **杂项**: 修复数据库错误 ([0dd05cd](https://github.com/arvinxx/umi-electron-template/commit/0dd05cd)) 485 | 486 | 487 | ### 📝 Documentation 488 | 489 | * **日志**: 更新日志 ([b590848](https://github.com/arvinxx/umi-electron-template/commit/b590848)) 490 | * **日志**: 更新日志 ([ddc4e29](https://github.com/arvinxx/umi-electron-template/commit/ddc4e29)) 491 | * **说明文档**: 更新 README.md ([ae16342](https://github.com/arvinxx/umi-electron-template/commit/ae16342)) 492 | 493 | # [1.4.0](https://github.com/arvinxx/umi-electron-template/compare/v1.3.3...v1.4.0) (2021-02-02) 494 | 495 | ### ✨ Features 496 | 497 | - **公证签名**: 优化导入签名公证的方法 ([4128e93](https://github.com/arvinxx/umi-electron-template/commit/4128e93)) 498 | - **公证签名**: 添加证书签名与公证 ([eae8ee8](https://github.com/arvinxx/umi-electron-template/commit/eae8ee8)) 499 | 500 | ### 🐛 Bug Fixes 501 | 502 | - **杂项**: 修复开发与打包页面路由错误的问题 ([2de2df5](https://github.com/arvinxx/umi-electron-template/commit/2de2df5)) 503 | 504 | ## [1.3.3](https://github.com/arvinxx/umi-electron-template/compare/v1.3.2...v1.3.3) (2021-02-02) 505 | 506 | ### 🐛 Bug Fixes 507 | 508 | - **杂项**: 修复 release ci 版本号不升级的 bug ([f7da0c3](https://github.com/arvinxx/umi-electron-template/commit/f7da0c3)) 509 | 510 | ## [1.3.2](https://github.com/arvinxx/umi-electron-template/compare/v1.3.1...v1.3.2) (2021-02-02) 511 | 512 | ### 🐛 Bug Fixes 513 | 514 | - **杂项**: 修复开发与打包页面路由错误的问题 ([0a6d144](https://github.com/arvinxx/umi-electron-template/commit/0a6d144)) 515 | - **杂项**: 尝试修复 release ci 版本号不升级 ([35060f9](https://github.com/arvinxx/umi-electron-template/commit/35060f9)) 516 | 517 | ## [1.3.1](https://github.com/arvinxx/umi-electron-template/compare/v1.3.0...v1.3.1) (2021-02-02) 518 | 519 | ### 🐛 Bug Fixes 520 | 521 | - **杂项**: 尝试修复 release ci 版本号不升级 ([9f5eba8](https://github.com/arvinxx/umi-electron-template/commit/9f5eba8)) 522 | 523 | # [1.3.0](https://github.com/arvinxx/umi-electron-template/compare/v1.2.3...v1.3.0) (2021-02-02) 524 | 525 | ### ♻ Code Refactoring 526 | 527 | - **杂项**: 重构 main 端方法 ([38f8cf2](https://github.com/arvinxx/umi-electron-template/commit/38f8cf2)) 528 | 529 | ### ✨ Features 530 | 531 | - **style**: 集成 tailwindcss 框架 ([3bfe813](https://github.com/arvinxx/umi-electron-template/commit/3bfe813)) 532 | - **杂项**: 添加切换暗色模式按钮 ([a97d0b7](https://github.com/arvinxx/umi-electron-template/commit/a97d0b7)) 533 | - **杂项**: 补充必要的工具函数 ([0f96ec1](https://github.com/arvinxx/umi-electron-template/commit/0f96ec1)) 534 | 535 | ### 🎫 Chores 536 | 537 | - **ci**: 优化输出配置 ([cd038ae](https://github.com/arvinxx/umi-electron-template/commit/cd038ae)) 538 | - **ci**: 优化输出配置 ([511e14b](https://github.com/arvinxx/umi-electron-template/commit/511e14b)) 539 | - **ci**: 优化输出配置 ([a009962](https://github.com/arvinxx/umi-electron-template/commit/a009962)) 540 | - **ci**: 优化输出配置 ([aece210](https://github.com/arvinxx/umi-electron-template/commit/aece210)) 541 | - **ci**: 优化输出配置 ([0ad779b](https://github.com/arvinxx/umi-electron-template/commit/0ad779b)) 542 | - **ci**: 优化输出配置 ([33bbf83](https://github.com/arvinxx/umi-electron-template/commit/33bbf83)) 543 | - **ci**: 优化输出配置 ([9daea46](https://github.com/arvinxx/umi-electron-template/commit/9daea46)) 544 | - **ci**: 优化输出配置 ([e56c3d9](https://github.com/arvinxx/umi-electron-template/commit/e56c3d9)) 545 | - **ci**: 优化输出配置 ([214f493](https://github.com/arvinxx/umi-electron-template/commit/214f493)) 546 | - **ci**: 优化输出配置 ([a6a7002](https://github.com/arvinxx/umi-electron-template/commit/a6a7002)) 547 | - **ci**: 优化输出配置 ([ad747a5](https://github.com/arvinxx/umi-electron-template/commit/ad747a5)) 548 | - **ci**: 添加发版状态说明 ci ([56ffdb9](https://github.com/arvinxx/umi-electron-template/commit/56ffdb9)) 549 | - **ci**: 调整发版状态文本 ([28bb47f](https://github.com/arvinxx/umi-electron-template/commit/28bb47f)) 550 | - **deps**: 清理模块 ([a442890](https://github.com/arvinxx/umi-electron-template/commit/a442890)) 551 | - **devtools**: 优化 devtools ([39b0e52](https://github.com/arvinxx/umi-electron-template/commit/39b0e52)) 552 | - **杂项**: 更新配置文件 ([d8ac1fe](https://github.com/arvinxx/umi-electron-template/commit/d8ac1fe)) 553 | - **杂项**: 测试 license 输出 ([1251cae](https://github.com/arvinxx/umi-electron-template/commit/1251cae)) 554 | - **杂项**: 目录架构调整成 main 和 renderer 类型 ([e4d119a](https://github.com/arvinxx/umi-electron-template/commit/e4d119a)) 555 | - **杂项**: 补充类型定义 ([390cc27](https://github.com/arvinxx/umi-electron-template/commit/390cc27)) 556 | - **自动发布**: 优化发版配置 ([9c038b2](https://github.com/arvinxx/umi-electron-template/commit/9c038b2)) 557 | - **自动发布**: 优化发版配置 ([a2ab483](https://github.com/arvinxx/umi-electron-template/commit/a2ab483)) 558 | - **自动发布**: 优化发版配置 ([6f29baa](https://github.com/arvinxx/umi-electron-template/commit/6f29baa)) 559 | - **自动发布**: 优化发版配置 ([f7cf423](https://github.com/arvinxx/umi-electron-template/commit/f7cf423)) 560 | - **自动发布**: 优化发版配置 ([a859500](https://github.com/arvinxx/umi-electron-template/commit/a859500)) 561 | - **自动发布**: 优化发版配置 ([58463a9](https://github.com/arvinxx/umi-electron-template/commit/58463a9)) 562 | - **自动发布**: 优化发版配置 ([a78b7d7](https://github.com/arvinxx/umi-electron-template/commit/a78b7d7)) 563 | - **自动发布**: 优化发版配置 ([b04d0da](https://github.com/arvinxx/umi-electron-template/commit/b04d0da)) 564 | 565 | ### 🐛 Bug Fixes 566 | 567 | - **license**: 修复 license 编码问题 ([947ee78](https://github.com/arvinxx/umi-electron-template/commit/947ee78)) 568 | 569 | ### 👷 Build System 570 | 571 | - **deps-dev**: bump @ant-design/pro-layout from 6.12.0 to 6.13.0 ([fd81712](https://github.com/arvinxx/umi-electron-template/commit/fd81712)) 572 | - **deps-dev**: bump @types/diff from 4.0.2 to 5.0.0 ([3dc1369](https://github.com/arvinxx/umi-electron-template/commit/3dc1369)) 573 | - **deps-dev**: bump antd from 4.10.3 to 4.11.2 ([508c716](https://github.com/arvinxx/umi-electron-template/commit/508c716)) 574 | - **deps-dev**: bump commitlint-config-gitmoji from 2.1.2 to 2.2.1 ([7a23b89](https://github.com/arvinxx/umi-electron-template/commit/7a23b89)) 575 | - **deps-dev**: bump conventional-changelog-gitmoji-config ([86d0235](https://github.com/arvinxx/umi-electron-template/commit/86d0235)) 576 | - **deps-dev**: bump cross-env from 5.2.1 to 7.0.3 ([c6d09c8](https://github.com/arvinxx/umi-electron-template/commit/c6d09c8)) 577 | - **deps-dev**: bump diff from 4.0.2 to 5.0.0 ([9c8903a](https://github.com/arvinxx/umi-electron-template/commit/9c8903a)) 578 | - **deps-dev**: bump eslint from 7.18.0 to 7.19.0 ([894b614](https://github.com/arvinxx/umi-electron-template/commit/894b614)) 579 | - **deps-dev**: bump jest from 25.5.4 to 26.6.3 ([36fd298](https://github.com/arvinxx/umi-electron-template/commit/36fd298)) 580 | - **deps-dev**: bump ts-jest from 26.4.4 to 26.5.0 ([65b9714](https://github.com/arvinxx/umi-electron-template/commit/65b9714)) 581 | 582 | ### 💄 Styles 583 | 584 | - **杂项**: 添加 token ([c0c3663](https://github.com/arvinxx/umi-electron-template/commit/c0c3663)) 585 | 586 | ### 📝 Documentation 587 | 588 | - **杂项**: 更新说明文档 ([4a63ab9](https://github.com/arvinxx/umi-electron-template/commit/4a63ab9)) 589 | 590 | ### 🔧 Continuous Integration 591 | 592 | - **杂项**: 修复 lint 方法 ([ba70f73](https://github.com/arvinxx/umi-electron-template/commit/ba70f73)) 593 | - **杂项**: 修复 lint 方法 ([754654e](https://github.com/arvinxx/umi-electron-template/commit/754654e)) 594 | - **杂项**: 尝试修复 release ci ([64c277d](https://github.com/arvinxx/umi-electron-template/commit/64c277d)) 595 | - **杂项**: 尝试修复 release ci ([70ec67f](https://github.com/arvinxx/umi-electron-template/commit/70ec67f)) 596 | - **杂项**: 尝试修复 release ci 版本号 ([0b37cf8](https://github.com/arvinxx/umi-electron-template/commit/0b37cf8)) 597 | 598 | ## [1.2.3](https://github.com/arvinxx/umi-electron-template/compare/v1.2.2...v1.2.3) (2021-01-24) 599 | 600 | ### 🐛 Bug Fixes | 修复 601 | 602 | - **(license)**: 修复 license 编码问题 ([bacd731](https://github.com/arvinxx/umi-electron-template/commit/bacd731)) 603 | 604 | ## [1.2.2](https://github.com/arvinxx/umi-electron-template/compare/v1.2.1...v1.2.2) (2021-01-24) 605 | 606 | ### 🐛 Bug Fixes | 修复 607 | 608 | - **(license)**: 修复 license 编码问题 ([5cc82cb](https://github.com/arvinxx/umi-electron-template/commit/5cc82cb)) 609 | - **(license)**: 调整编码方式 ([56c5516](https://github.com/arvinxx/umi-electron-template/commit/56c5516)) 610 | - **(license)**: 调整编码方式 ([6ec2693](https://github.com/arvinxx/umi-electron-template/commit/6ec2693)) 611 | - **(license)**: 调整编码方式 ([6bef8dc](https://github.com/arvinxx/umi-electron-template/commit/6bef8dc)) 612 | 613 | ## [1.2.1](https://github.com/arvinxx/umi-electron-template/compare/v1.2.0...v1.2.1) (2021-01-24) 614 | 615 | ### 🐛 Bug Fixes | 修复 616 | 617 | - **(license)**: 修复 license 编码问题 ([7c5caec](https://github.com/arvinxx/umi-electron-template/commit/7c5caec)) 618 | 619 | # [1.2.0](https://github.com/arvinxx/umi-electron-template/compare/v1.1.3...v1.2.0) (2021-01-23) 620 | 621 | ### ♻ Code Refactoring | 重构 622 | 623 | - **(类型)**: 优化类型定义文件 ([48acbf4](https://github.com/arvinxx/umi-electron-template/commit/48acbf4)) 624 | 625 | ### ✨ Features | 新特性 626 | 627 | - **(ci)**: 添加测试 ci ([fb2b3c6](https://github.com/arvinxx/umi-electron-template/commit/fb2b3c6)) 628 | 629 | ### 🎫 Chores 630 | 631 | - **(deps)**: 清理无用依赖 ([bb9b96e](https://github.com/arvinxx/umi-electron-template/commit/bb9b96e)) 632 | 633 | ## [1.1.3](https://github.com/arvinxx/umi-electron-template/compare/v1.1.2...v1.1.3) (2021-01-23) 634 | 635 | ### 🐛 Bug Fixes | 修复 636 | 637 | - **(ci)**: 测试添加 blockmap 文件 ([395ad0b](https://github.com/arvinxx/umi-electron-template/commit/395ad0b)) 638 | 639 | ## [1.1.2](https://github.com/arvinxx/umi-electron-template/compare/v1.1.1...v1.1.2) (2021-01-23) 640 | 641 | ### 🐛 Bug Fixes | 修复 642 | 643 | - **(ci)**: 修复没有上传 linux 构建产物的问题 ([1ee9f48](https://github.com/arvinxx/umi-electron-template/commit/1ee9f48)) 644 | 645 | ## [1.1.1](https://github.com/arvinxx/umi-electron-template/compare/v1.1.0...v1.1.1) (2021-01-23) 646 | 647 | ### 🐛 Bug Fixes | 修复 648 | 649 | - **(ci)**: 修复 linux 发包错误 ([964afe2](https://github.com/arvinxx/umi-electron-template/commit/964afe2)) 650 | 651 | # [1.1.0](https://github.com/arvinxx/umi-electron-template/compare/v1.0.0...v1.1.0) (2021-01-23) 652 | 653 | ### ✨ Features | 新特性 654 | 655 | - **(ci)**: 添加发布流程 ([d0f079a](https://github.com/arvinxx/umi-electron-template/commit/d0f079a)) 656 | 657 | ### 🎫 Chores 658 | 659 | - **(ci)**: 测试发布配置项 ([0c6d8c2](https://github.com/arvinxx/umi-electron-template/commit/0c6d8c2)) 660 | - **(ci)**: 测试发布配置项 ([96803bd](https://github.com/arvinxx/umi-electron-template/commit/96803bd)) 661 | - **(ci)**: 测试发布配置项 ([d708fe3](https://github.com/arvinxx/umi-electron-template/commit/d708fe3)) 662 | - **(ci)**: 测试发布配置项 ([387c712](https://github.com/arvinxx/umi-electron-template/commit/387c712)) 663 | - **(ci)**: 测试发布配置项 ([386d44f](https://github.com/arvinxx/umi-electron-template/commit/386d44f)) 664 | - **(ci)**: 测试发布配置项 ([4b07158](https://github.com/arvinxx/umi-electron-template/commit/4b07158)) 665 | - **(ci)**: 测试发布配置项 ([d38a57e](https://github.com/arvinxx/umi-electron-template/commit/d38a57e)) 666 | - **(ci)**: 添加 windows 发布环境 ([c51f224](https://github.com/arvinxx/umi-electron-template/commit/c51f224)) 667 | - **(deps)**: 更新依赖文件 ([d1ce278](https://github.com/arvinxx/umi-electron-template/commit/d1ce278)) 668 | - **(deps)**: 清理无用依赖 ([5c86684](https://github.com/arvinxx/umi-electron-template/commit/5c86684)) 669 | - **(deps)**: 清理无用依赖 ([2dabb88](https://github.com/arvinxx/umi-electron-template/commit/2dabb88)) 670 | - **(deps)**: 清理无用依赖 ([1264ff2](https://github.com/arvinxx/umi-electron-template/commit/1264ff2)) 671 | - **(deps)**: 清理无用依赖 ([e268b09](https://github.com/arvinxx/umi-electron-template/commit/e268b09)) 672 | - **(deps)**: 清理无用依赖 ([87ea9cb](https://github.com/arvinxx/umi-electron-template/commit/87ea9cb)) 673 | 674 | ### 👷‍ Build System 675 | 676 | - **(deps-dev)**: bump electron-debug from 2.2.0 to 3.2.0 ([205613a](https://github.com/arvinxx/umi-electron-template/commit/205613a)) 677 | 678 | ### 📝 Documentation | 文档 679 | 680 | - **(license)**: 添加协议 ([320f198](https://github.com/arvinxx/umi-electron-template/commit/320f198)) 681 | - **(说明文档)**: 更新说明文档 ([0892c3c](https://github.com/arvinxx/umi-electron-template/commit/0892c3c)) 682 | 683 | # 1.0.0 (2021-01-23) 684 | 685 | ### ✨ Features | 新特性 686 | 687 | - **(ci)**: 添加 auto merge ci ([2dfb36c](https://github.com/arvinxx/umi-electron-template/commit/2dfb36c)) 688 | 689 | ### 🎫 Chores 690 | 691 | - **(ci)**: 添加 ci 流程 ([7017284](https://github.com/arvinxx/umi-electron-template/commit/7017284)) 692 | - **(init)**: 初始化项目脚手架 ([7a59ff2](https://github.com/arvinxx/umi-electron-template/commit/7a59ff2)) 693 | - **(自动发布)**: 调整发布配置 ([0758330](https://github.com/arvinxx/umi-electron-template/commit/0758330)) 694 | - **(配置)**: 调整 prettier 配置项 ([e0fa628](https://github.com/arvinxx/umi-electron-template/commit/e0fa628)) 695 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2021 Arvin Xu 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 | # Umi Electron Template 2 | 3 | ![][version-url] [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) ![][license-url] 4 | 5 | 6 | 7 | [version-url]: https://img.shields.io/github/v/release/arvinxx/umi-electron-template 8 | [license-url]: https://img.shields.io/github/license/arvinxx/umi-electron-template 9 | 10 | 一个基于 [umi][umi] 和 [umi-plugin-electron-builder][umi-plugin-electron-builder] 的开发模板 11 | 12 | ![预览](https://gw.alipayobjects.com/zos/antfincdn/k7TRgZNHSJ/1bbf755c-a3bf-45bd-a3f8-64745a93f8b2.png) 13 | 14 | ## 特性 15 | 16 | ### 架构 17 | 18 | - 基于 [umi-plugin-electron-builder][umi-plugin-electron-builder] 构建,享受完整 [umi][umi] 开发生态; 19 | - 采用 [electron-builder][electron-builder] 打包构建工具; 20 | - 使用 Main 与 Renderer 双目录架构; 21 | - 基于 [inversify][inversify] 实现 DI/IoC 22 | 23 | ### 内置功能 24 | 25 | - **样式框架**: 集成 [antd-style][tailwindcss]; 26 | - **数据持久化**: 集成 [sqlite3][sqlite3] 作为本地数据库, [TypeORM][typeorm] 作为 ORM; 27 | - **签名公证**: 集成 macOS App 签名与公证,包含在 CI/CD 流程中; 28 | 29 | ### 开发体验 30 | 31 | - 集成 [react-devtools][react-devtools] 与 [Redux Dev Tools][redux-devtools]; 32 | - 基于 [Gitmoji Commit Workflow][gitmoji-commit-workflow], 实现自动化版本管理与发布; 33 | 34 | 35 | 36 | [umi]: https://umijs.org/ 37 | [umi-plugin-electron-builder]: https://github.com/BySlin/umi-plugin-electron-builder 38 | [react-devtools]: https://www.npmjs.com/package/react-devtools 39 | [electron-builder]: https://www.electron.build/ 40 | [redux-devtools]: https://github.com/reduxjs/redux-devtools 41 | [gitmoji-commit-workflow]: https://github.com/arvinxx/gitmoji-commit-workflow/ 42 | [tailwindcss]: https://antd-style.arvinx.app/ 43 | [sqlite3]: https://github.com/mapbox/node-sqlite3 44 | [typeorm]: https://typeorm.io/#/ 45 | [inversify]: https://github.com/inversify/InversifyJS 46 | 47 | ## 快速上手 48 | 49 | ### 安装 50 | 51 | 通过 git 下载这个仓库到本地 52 | 53 | 然后通过 yarn 下载安装依赖 54 | 55 | ```bash 56 | yarn 57 | ``` 58 | 59 | ### 开发 60 | 61 | 通过以下命令启动渲染进程(默认端口:7777) 62 | 63 | ```bash 64 | yarn start 65 | ``` 66 | 67 | ### 构建 68 | 69 | ```bash 70 | yarn build 71 | ``` 72 | 73 | 构建文件会输出到 `release` 目录下: 74 | 75 | ``` 76 | release 77 | ├── builder-effective-config.yaml 78 | ├── bundled 79 | │ ├── home.html 80 | │ ├── index.html 81 | │ ├── main.js 82 | │ ├── main.js.map 83 | │ ├── node_modules 84 | │ ├── package.json 85 | │ ├── static 86 | │ ├── umi.css 87 | │ └── umi.js 88 | ├── latest-mac.yml 89 | ├── mac 90 | │ └── Umi Electron Template.app 91 | ├── umi-electron-template_setup_1.8.1.dmg 92 | └── umi-electron-template_setup_1.8.1.dmg.blockmap 93 | 94 | ``` 95 | 96 | ## 开发指南 97 | 98 | 详见 [开发指南](./docs/guide.md) 99 | 100 | ## License 101 | 102 | [MIT](./LICENSE) ® Arvin Xu 103 | -------------------------------------------------------------------------------- /docs/communication.md: -------------------------------------------------------------------------------- 1 | # 通信 2 | 3 | ## 通信方式 4 | 5 | 在 `src/main/bridge` 和 `src/renderer/bridge` 中分别书写通信的方法 6 | 7 | ## 附录: 是否该使用 Remote 模块 8 | 9 | 在 [Electron’s ‘remote’ module considered harmful | by Jeremy Rose | Medium](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31) 中 10 | Electron’s ‘remote’ module considered harmful | by Jeremy Rose | Medium 11 | 说 Remote 很慢,通信时会阻塞 UI。 一个测试是 remote 获取属性的效率是 local 的万分之一。 12 | 一个测试用例: 13 | 14 | ```js 15 | // Main process 16 | global.thing = { 17 | rectangle: { 18 | getBounds() { return { x: 0, y: 0, width: 100, height: 100 } } 19 | setBounds(bounds) { /* ... */ } 20 | } 21 | } 22 | // Renderer process 23 | const thing = remote.getGlobal('thing') 24 | const { x, y, width, height } = thing.rectangle.getBounds() 25 | thing.rectangle.setBounds({ x, y, width, height: height + 100 }) 26 | 27 | ``` 28 | 29 | 上述代码会跑 9 个 ipc 流程。 30 | -------------------------------------------------------------------------------- /docs/guide.md: -------------------------------------------------------------------------------- 1 | # 开发指南 2 | 3 | ## 框架设计思想 4 | 5 | 框架的设计思想为 MVC Services 方式 6 | 7 | ### Main 8 | 9 | 框架整体上分为 MVC、common、services 和 process 四大结构 10 | services 自己封装了一些诸如消息通知,http 请求,用 localStorage 本地化存储等服务,开发者可以自行扩展,并按需引用, 11 | 12 | process 中主要针对主进程和渲染进程分别写了 MainProcessHelper 和 RendererProcessHelper, 13 | 14 | 用来辅助主进程和渲染进程的通信,同时 15 | 16 | ### Renderer 17 | 18 | ### common 19 | 20 | common 中有 Logger,Config,Router 三个组件,分别用于日志,配置和路由。 21 | 22 | ## 框架约定 23 | 24 | ### Renderer 25 | 26 | 采用 umi 的约定 27 | 28 | ## 框架引用的第三方组件 29 | 30 | - log4js 日志 https://www.npmjs.com/package/log4js 31 | -------------------------------------------------------------------------------- /docs/structure/index.md: -------------------------------------------------------------------------------- 1 | # 框架结构 2 | 3 | 框架分为 Main 端和 Renderer 端,为 Two Package Structure。 4 | 5 | ``` 6 | root/ 7 | ├── src 8 | │ ├── common # 公用的相关文件(IPC Channel指令等) 9 | │ ├── main # Main 端 10 | │ └── renderer # Renderer 端 11 | ``` 12 | 13 | - **Main 端**: 为 Electron 主进程,是 Node 环境(一个 Chrome 浏览器)。可与系统环境交互,具有较大的运行权限。详细架构见 [Main 架构](./main.md)。 14 | - **Renderer 端**: 为 Electron 的渲染进程,需要通过 `BrowserWindows` 开启后才可见。运行环境为 Browser(可以理解为普通网页)。无法接触到系统,需要通过 Main 端间接实现与系统的交互。详细架构见 [Renderer 架构](./renderer.md)。 15 | 16 | ## 技术选型 17 | 18 | ### Main 端 19 | 20 | Electron + SQLite + TypeORM + inversify 21 | 22 | ### Renderer 端 23 | 24 | Umi + React + antd ,开发语言使用 Typescript。 25 | -------------------------------------------------------------------------------- /docs/structure/main.md: -------------------------------------------------------------------------------- 1 | # Main 架构 2 | 3 | 与开发功能核心相关的结构如下 : 4 | 5 | ``` 6 | main 7 | ├── app # App 框架 8 | ├── models # 数据模型 9 | ├── services # 服务 10 | ├── views # UI 11 | ├── utils # 工具函数 12 | ├── ioc # IoC 容器 13 | ├── bootstrap.ts # app 启动逻辑 14 | └── main.ts # main 端启动脚本 15 | ``` 16 | 17 | ## `main.ts` 入口文件 18 | 19 | 这个脚本是 [umi-plugin-electron-builder][umi-plugin-electron-builder] 约定保留脚本 将启动方法在这个脚本中执行: 20 | 21 | ```ts 22 | import { bootstrap } from './bootstrap'; 23 | 24 | bootstrap().catch(console.error); 25 | ``` 26 | 27 | ## `bootstrap.ts` 启动方法 28 | 29 | 在 `bootstrap.ts` 中定义了启动方法 `bootstrap`,执行分为 `beforeInit` 和 `init` 两个阶段: 30 | 31 | - `beforeInit`: 执行需要在 app 初始化前的一些操作 比如注册 `schema` 协议、注入容器的异步依赖(即数据库部分) 、锁定单实例等。 32 | - `init`: 初始化容器,并调用 `App` 的 `init` 方法,执行服务、UI 的初始化。 33 | 34 | ## `app` 目录 35 | 36 | app 目录下目前包含 三个容器对象 App Service 和 Window 37 | 38 | ``` 39 | app 40 | ├── App.ts # App 容器 41 | ├── Service.ts # 服务容器 42 | ├── View.ts # 视窗容器 43 | └── index.ts 44 | ``` 45 | 46 | - `App`: Electron 在 main 端的容器 包含所有必要对象, 通过 App 类来控制整个产品的生命周期; 47 | - `Service`: Service 是服务容器对象 对产品提供所有需要的服务能力 例如翻译、登录注册、拉取新版本等; 48 | - `View`: View 是视图容器对象 包含了所有和用户交互的对象: 窗口、菜单、托盘等。 49 | 50 | ### App 类 51 | 52 | ```typescript 53 | class App { 54 | // 初始化方法 55 | constructor() { 56 | app.whenReady().then(() => { 57 | // 在这里调用服务和视图的 init 方法 实现服务和视图的初始化 58 | this.services.init(); 59 | this.views.init(); 60 | }); 61 | 62 | // 其他 app 相关方法暂时都写在这里 63 | app.on('window-all-closed', () => { 64 | app.quit(); 65 | }); 66 | } 67 | 68 | // 视图容器 69 | views: View; 70 | 71 | // 服务容器 72 | services: Service; 73 | } 74 | ``` 75 | 76 | ### Service 类 77 | 78 | 在 `Service` 类中手动注入相应的服务类,然后在 `init` 方法中初始化上桥。 79 | 80 | ```typescript 81 | class Service { 82 | /** 服务类 * */ 83 | 84 | user: UserService; 85 | 86 | system: SystemService; 87 | 88 | device: DeviceService; 89 | 90 | init() { 91 | // 服务上桥 供 renderer 端 remote 调用 92 | global.services = { 93 | user: this.user, 94 | system: this.system, 95 | device: this.device, 96 | }; 97 | } 98 | } 99 | ``` 100 | 101 | TODO: 之后可能会替换成用 `ipc` 的方法 (相关见 [通信部分研究](../communication.md))。 102 | 103 | ### View 类 104 | 105 | 结构和 `Service` 一样,在这里包含 `BrowserWindows` 、 `Menu` 和 `Tray` 类。 106 | 107 | ```typescript 108 | class View { 109 | home: HomeWindow; 110 | 111 | init() { 112 | // 视窗上桥 113 | global.windows = { 114 | home: this.home, 115 | }; 116 | } 117 | } 118 | ``` 119 | 120 | ## `ioc` 目录 121 | 122 | 该目录下包含了实现控制反转能力的模块, 使用 [inversify][inversify] 实现。 123 | 控制反转的好处在于只要引入相应的装饰器标识符,就可以自动把该对象引入到类中。如此一来,就直接拿到类的方法和属性了。 124 | 125 | 例如在 `UserService` 中注入 `TYPES.UserRepository` 就可以在 `model` 属性上拿到在数据库中的 `User` 对象。 126 | 127 | PS:中间引入的过程在 `inversify.config.ts` 中 128 | 129 | ```typescript 130 | class UserService { 131 | @inject(TYPES.UserRepository) 132 | private model: Repository; 133 | } 134 | ``` 135 | 136 | ## `views` 目录 137 | 138 | 该目录下包含所有交互相关的能力: `BrowserWindows` `Menu` `Tray` `Shortcut` 等 139 | 140 | - BrowserWindows: 窗口 141 | - Menu: 菜单 142 | - Tray: 托盘 143 | - Shortcut: 快捷键 144 | 145 | ## `models` 目录 146 | 147 | 此目录包含数据库模型,本地数据库使用 SQLite3 , ORM 采用 [TypeORM][typeorm] 148 | 149 | 以 Status 为例: 150 | 151 | ```typescript 152 | @Entity('Status') 153 | export class Status { 154 | @PrimaryGeneratedColumn() 155 | id!: number; 156 | 157 | /** 158 | * 是否激活 159 | */ 160 | @Column() 161 | active!: boolean; 162 | 163 | /** 164 | * ocr 是否可用 165 | */ 166 | @Column() 167 | ocr!: boolean; 168 | 169 | /** 170 | * 设备是否可用 (超2台不可用) 171 | */ 172 | @Column() 173 | device!: boolean; 174 | 175 | /** 176 | * 总使用次数 177 | */ 178 | @Column() 179 | totalOcrCounts!: boolean; 180 | 181 | /** 182 | * 总翻译字符数 183 | */ 184 | @Column() 185 | totalCharLength!: boolean; 186 | 187 | /** 188 | * 更新时间 189 | */ 190 | @Column() 191 | updatedAt!: Date; 192 | } 193 | ``` 194 | 195 | ## `services` 目录 196 | 197 | 放 main 端服务能力, 大部分与系统交互的业务逻辑都放到 services 层中 , 例如校验有效性 翻译等等 198 | 199 | [typeorm]: https://typeorm.io/#/ 200 | [inversify]: https://github.com/inversify/InversifyJS 201 | [umi-plugin-electron-builder]: https://github.com/BySlin/umi-plugin-electron-builder 202 | -------------------------------------------------------------------------------- /docs/structure/renderer.md: -------------------------------------------------------------------------------- 1 | # Renderer 端 2 | 3 | Renderer 为纯 Web 端,采用 Umi + React+ AntD 技术栈。与 umi 架构下的网页端开发保持一致。不过多介绍。 4 | -------------------------------------------------------------------------------- /mock/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinxx/umi-electron-template/97b23a0661f70f3ef548bcd116f71ccc236dd0bf/mock/.gitkeep -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "umi-electron-template", 3 | "version": "2.0.0", 4 | "private": true, 5 | "description": "umi electron template", 6 | "repository": "https://github.com/arvinxx/umi-electron-template.git", 7 | "author": "Arvin Xu", 8 | "scripts": { 9 | "build": "npm run build:renderer && npm run build:electron", 10 | "build:electron": "npm run build --prefix=packages/main", 11 | "build:renderer": "npm run build --prefix=packages/renderer", 12 | "clean": "rm -rf dist release .eslintcache", 13 | "dev:main": "npm run start --prefix=packages/main", 14 | "dev:renderer": "npm run start --prefix=packages/renderer", 15 | "electron:mac-zip": "ts-node scripts/buildMacZip.ts", 16 | "postinstall": "cross-env ELECTRON_RUN_AS_NODE=1 electron scripts/update-electron-vendors.mjs", 17 | "lint": "pnpm --filter=\"./packages/**\" run lint-eslint", 18 | "lint-staged": "lint-staged", 19 | "lint:fix": "max eslint --fix", 20 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 21 | "release": "semantic-release", 22 | "start": "concurrently \"npm run dev:main\" \"npm run dev:renderer\"", 23 | "test": "jest", 24 | "test:coverage": "jest --coverage" 25 | }, 26 | "lint-staged": { 27 | "*.{js,jsx,less,md,json}": [ 28 | "prettier --write" 29 | ], 30 | "*.ts?(x)": [ 31 | "prettier --parser=typescript --write", 32 | "pnpm run lint:fix" 33 | ] 34 | }, 35 | "devDependencies": { 36 | "@commitlint/cli": "^17", 37 | "@types/js-yaml": "^4", 38 | "@types/node": "^18", 39 | "@umijs/lint": "^4", 40 | "commitlint-config-gitmoji": "^2", 41 | "concurrently": "^7", 42 | "cross-env": "^7", 43 | "dotenv": "^10", 44 | "electron": "^24", 45 | "eslint": "^8", 46 | "father": "^4", 47 | "husky": "^8", 48 | "js-yaml": "^4", 49 | "lint-staged": "^10", 50 | "prettier": "^2", 51 | "prettier-plugin-organize-imports": "^3", 52 | "prettier-plugin-packagejson": "^2", 53 | "semantic-release": "^20", 54 | "semantic-release-config-gitmoji": "^1", 55 | "ts-node": "^10", 56 | "tslib": "^2", 57 | "typescript": "^5", 58 | "unplugin-auto-expose": "0.0.4" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /packages/common/.fatherrc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'father'; 2 | 3 | export default defineConfig({ 4 | cjs: { output: 'lib', platform: 'browser' }, 5 | }); 6 | -------------------------------------------------------------------------------- /packages/common/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@umi-electron-template/common", 3 | "version": "2.0.0", 4 | "private": true, 5 | "description": "max electron template", 6 | "author": "Arvin Xu", 7 | "main": "src/index.ts", 8 | "scripts": { 9 | "build": "father build", 10 | "postinstall": "npm run build", 11 | "lint-eslint": "max lint", 12 | "lint-staged": "lint-staged", 13 | "lint:fix": "max eslint --fix", 14 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 15 | "test": "jest --passWithNoTests", 16 | "test:coverage": "jest --coverage --passWithNoTests" 17 | }, 18 | "dependencies": { 19 | "electron-is": "^3", 20 | "umi-request": "^1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/common/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './utils'; 3 | -------------------------------------------------------------------------------- /packages/common/src/types/browser.ts: -------------------------------------------------------------------------------- 1 | export enum BrowserWindowsIdentifier { 2 | home = 'home', 3 | } 4 | -------------------------------------------------------------------------------- /packages/common/src/types/events.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * main -> renderer 的广播事件 3 | */ 4 | export interface MainEvents { 5 | initDatabase: 'loading' | 'failed' | 'success'; 6 | } 7 | 8 | /** 9 | * renderer -> main 的请求事件 10 | */ 11 | export interface RendererEvents { 12 | /** 13 | * SystemService 14 | * 检查可用性 15 | */ 16 | '/system/check-accessibility': boolean; 17 | 18 | /** 19 | * 添加新用户 20 | */ 21 | '/user/add': any; 22 | /** 23 | * 查找所有用户 24 | */ 25 | '/user/find-all': any; 26 | } 27 | -------------------------------------------------------------------------------- /packages/common/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './browser'; 2 | export * from './events'; 3 | -------------------------------------------------------------------------------- /packages/common/src/utils/env.ts: -------------------------------------------------------------------------------- 1 | export const { PORT } = process.env; 2 | -------------------------------------------------------------------------------- /packages/common/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './env'; 2 | export * from './is'; 3 | export * from './request'; 4 | -------------------------------------------------------------------------------- /packages/common/src/utils/is.ts: -------------------------------------------------------------------------------- 1 | import { osx, windows as _windows, main, renderer } from 'electron-is/is'; 2 | 3 | /** 4 | * 判断是否是 mac 平台 5 | */ 6 | export const isMacOS = osx(); 7 | 8 | /** 9 | * 判断是否是 windows 10 | */ 11 | export const isWindows = _windows(); 12 | 13 | export const isMain = main(); 14 | 15 | export const isRenderer = renderer(); 16 | 17 | export const isDev = process.env.NODE_ENV === 'development'; 18 | 19 | export const isTest = process.env.NODE_ENV === 'test'; 20 | -------------------------------------------------------------------------------- /packages/common/src/utils/request.ts: -------------------------------------------------------------------------------- 1 | import { extend } from 'umi-request'; 2 | import { PORT } from './env'; 3 | import { isDev, isTest } from './is'; 4 | 5 | /** 6 | * request 网络请求工具 7 | * 更详细的 api 文档: https://github.com/umijs/umi-request 8 | */ 9 | 10 | const codeMessage = { 11 | 200: '服务器成功返回请求的数据。', 12 | 201: '新建或修改数据成功。', 13 | 202: '一个请求已经进入后台排队(异步任务)。', 14 | 204: '删除数据成功。', 15 | 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', 16 | 401: '用户没有权限(令牌、用户名、密码错误)。', 17 | 403: '用户得到授权,但是访问是被禁止的。', 18 | 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', 19 | 406: '请求的格式不可得。', 20 | 410: '请求的资源被永久删除,且不会再得到的。', 21 | 422: '当创建一个对象时,发生一个验证错误。', 22 | 500: '服务器发生错误,请检查服务器。', 23 | 502: '网关错误。', 24 | 503: '服务不可用,服务器暂时过载或维护。', 25 | 504: '网关超时。', 26 | }; 27 | 28 | type ErrorCode = keyof typeof codeMessage; 29 | 30 | /** 31 | * 异常处理程序 32 | */ 33 | const errorHandler = (error: { response: Response }): Response => { 34 | const { response } = error; 35 | if (response && response.status) { 36 | const errorText = 37 | codeMessage[response.status as ErrorCode] || response.statusText; 38 | const { status, url } = response; 39 | 40 | console.error({ 41 | message: `请求错误 ${status}: ${url}`, 42 | description: errorText, 43 | }); 44 | } else if (!response) { 45 | console.error(String(error)); 46 | } 47 | return response; 48 | }; 49 | 50 | const getBaseUrl = () => { 51 | if (isDev || isTest) return `http://localhost:${PORT || 8051}/api`; 52 | 53 | // 在这里替换 生产端 URL 54 | return 'https://product.url'; 55 | }; 56 | 57 | /** 58 | * 配置request请求时的默认参数 59 | */ 60 | export const request = extend({ 61 | errorHandler, // 默认错误处理 62 | prefix: getBaseUrl(), 63 | credentials: 'include', // 默认请求是否带上cookie 64 | }); 65 | -------------------------------------------------------------------------------- /packages/common/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/main/build/Icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinxx/umi-electron-template/97b23a0661f70f3ef548bcd116f71ccc236dd0bf/packages/main/build/Icon.icns -------------------------------------------------------------------------------- /packages/main/build/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinxx/umi-electron-template/97b23a0661f70f3ef548bcd116f71ccc236dd0bf/packages/main/build/background.png -------------------------------------------------------------------------------- /packages/main/build/developer-id-app-certs.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinxx/umi-electron-template/97b23a0661f70f3ef548bcd116f71ccc236dd0bf/packages/main/build/developer-id-app-certs.p12 -------------------------------------------------------------------------------- /packages/main/build/embedded.provisionprofile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinxx/umi-electron-template/97b23a0661f70f3ef548bcd116f71ccc236dd0bf/packages/main/build/embedded.provisionprofile -------------------------------------------------------------------------------- /packages/main/build/entitlements.mac.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/main/build/entitlements.mas.inherit.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.inherit 8 | 9 | com.apple.security.cs.allow-jit 10 | 11 | com.apple.security.cs.allow-unsigned-executable-memory 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/main/build/entitlements.mas.loginhelper.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/main/build/entitlements.mas.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.app-sandbox 8 | 9 | com.apple.security.cs.allow-jit 10 | 11 | com.apple.security.application-groups 12 | 4684H589ZU.tech.wuling.duoyi 13 | com.apple.security.files.user-selected.read-only 14 | 15 | com.apple.security.files.user-selected.read-write 16 | 17 | com.apple.security.network.client 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/main/build/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinxx/umi-electron-template/97b23a0661f70f3ef548bcd116f71ccc236dd0bf/packages/main/build/icon.ico -------------------------------------------------------------------------------- /packages/main/build/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinxx/umi-electron-template/97b23a0661f70f3ef548bcd116f71ccc236dd0bf/packages/main/build/icon.png -------------------------------------------------------------------------------- /packages/main/build/installerIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinxx/umi-electron-template/97b23a0661f70f3ef548bcd116f71ccc236dd0bf/packages/main/build/installerIcon.ico -------------------------------------------------------------------------------- /packages/main/build/license.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinxx/umi-electron-template/97b23a0661f70f3ef548bcd116f71ccc236dd0bf/packages/main/build/license.txt -------------------------------------------------------------------------------- /packages/main/build/volume.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arvinxx/umi-electron-template/97b23a0661f70f3ef548bcd116f71ccc236dd0bf/packages/main/build/volume.icns -------------------------------------------------------------------------------- /packages/main/electron-builder.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | directories: { 3 | output: '../../release', 4 | buildResources: 'build', 5 | }, 6 | files: ['dist'], 7 | extraMetadata: { 8 | version: process.env.npm_package_version, 9 | }, 10 | 11 | /** 12 | * app 基础信息 13 | */ 14 | appId: 'com.arvinxx.umi-electron-template', 15 | productName: 'Umi Electron Template', 16 | copyright: 'Copyright © 2021 - Present Arvin Xu | All Right Reserved.', 17 | 18 | /** 19 | * 配置 notarize dmg 20 | * 在 `.env` 里添加两个环境变量 21 | * 22 | * APPLE_ID=你的apple id 23 | * APPLE_ID_PASSWORD= app-specific 密码 可以在 appleid.apple.com 创建 24 | * 25 | */ 26 | afterSign: 27 | process.env.NOTARIZE === 'false' 28 | ? () => { 29 | console.log('Skip notarize...'); 30 | } 31 | : 'electron-builder-notarize', 32 | 33 | /** 34 | * win 配置项 35 | */ 36 | win: { 37 | artifactName: '${name}_setup_${version}.${ext}', 38 | target: ['nsis'], 39 | }, 40 | nsis: { 41 | oneClick: false, 42 | perMachine: true, 43 | allowToChangeInstallationDirectory: true, 44 | license: 'build/license.txt', 45 | }, 46 | 47 | /** 48 | * mac 配置项 49 | */ 50 | mac: { 51 | category: 'public.app-category.developer-tools', 52 | target: ['dmg'], 53 | artifactName: '${name}_setup_${version}.${ext}', 54 | hardenedRuntime: true, 55 | gatekeeperAssess: false, 56 | darkModeSupport: true, 57 | entitlements: 'build/entitlements.mac.plist', 58 | entitlementsInherit: 'build/entitlements.mac.plist', 59 | }, 60 | dmg: { 61 | icon: 'build/volume.icns', 62 | background: 'build/background.png', 63 | title: '${productName}', 64 | iconSize: 80, 65 | window: { 66 | height: 422, 67 | width: 600, 68 | }, 69 | contents: [ 70 | { 71 | type: 'file', 72 | x: 144, 73 | y: 199, 74 | }, 75 | { 76 | type: 'link', 77 | path: '/Applications', 78 | x: 451, 79 | y: 199, 80 | }, 81 | ], 82 | }, 83 | mas: { 84 | hardenedRuntime: false, 85 | darkModeSupport: true, 86 | provisioningProfile: 'build/embedded.provisionprofile', 87 | category: 'public.app-category.productivity', 88 | entitlements: 'build/entitlements.mas.plist', 89 | entitlementsInherit: 'build/entitlements.mas.inherit.plist', 90 | asarUnpack: [], 91 | }, 92 | 93 | /** 94 | * linux 配置项 95 | */ 96 | linux: { 97 | artifactName: '${name}_setup_${version}.${ext}', 98 | icon: 'build/icon.png', 99 | synopsis: 'umi electron template', 100 | category: 'Development', 101 | }, 102 | 103 | /** 104 | * Publish 配置 105 | */ 106 | publish: ['github'], 107 | 108 | /** 109 | * 构建配置项 110 | */ 111 | compression: 'maximum', // 压缩比例 112 | npmRebuild: false, 113 | // asar: { 114 | // smartUnpack: true, 115 | // }, 116 | }; 117 | -------------------------------------------------------------------------------- /packages/main/electron.vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, externalizeDepsPlugin } from 'electron-vite'; 2 | import { join } from 'node:path'; 3 | import { preload } from 'unplugin-auto-expose'; 4 | 5 | const isDev = process.env.MODE !== 'development'; 6 | 7 | // electron 24 版本使用 node18 8 | const target = 'node18'; 9 | 10 | const externalPlugin = externalizeDepsPlugin({ 11 | include: ['builder-util-runtime', 'umi-request'], 12 | }); 13 | 14 | export default defineConfig({ 15 | main: { 16 | resolve: { 17 | alias: { 18 | '@': join(__dirname, 'src/'), 19 | '@umi-electron-template/common': join(__dirname, '../common/src'), 20 | }, 21 | }, 22 | build: { 23 | ssr: true, 24 | sourcemap: 'inline', 25 | minify: !isDev, 26 | target, 27 | lib: { 28 | entry: 'src/index.ts', 29 | }, 30 | outDir: 'dist/main', 31 | emptyOutDir: true, 32 | }, 33 | plugins: [externalPlugin], 34 | }, 35 | preload: { 36 | build: { 37 | ssr: true, 38 | sourcemap: 'inline', 39 | target, 40 | minify: !isDev, 41 | lib: { 42 | entry: join(__dirname, '../preload/src/index.ts'), 43 | }, 44 | outDir: 'dist/preload', 45 | emptyOutDir: true, 46 | }, 47 | plugins: [preload.vite(), externalPlugin], 48 | }, 49 | 50 | // 忽略 renderer 的构建 51 | renderer: { 52 | root: 'scripts', 53 | build: { 54 | rollupOptions: { 55 | input: 'scripts/zombieRender/index.html', 56 | }, 57 | outDir: 'node_modules/.cache/electron-vite/renderer', 58 | }, 59 | }, 60 | }); 61 | -------------------------------------------------------------------------------- /packages/main/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@umi-electron-template/main", 3 | "version": "2.0.0", 4 | "private": true, 5 | "description": "umi electron template", 6 | "author": "Arvin Xu", 7 | "main": "dist/main/index.js", 8 | "scripts": { 9 | "prebuild": "electron-vite build", 10 | "build": "npm run prebuild && electron-builder build --config electron-builder.config.js", 11 | "clean": "rm -rf dist release .eslintcache ./src/.umi", 12 | "dev": "electron-vite dev -w", 13 | "electron:build-local": "NOTARIZE=false npm run build -- --dir --config.asar=false", 14 | "electron:build:linux": "npm run build --linux", 15 | "electron:build:mac": "npm run build --mac", 16 | "electron:build:win": "npm run build --win", 17 | "postinstall": "electron-builder install-app-deps", 18 | "lint-eslint": "max lint", 19 | "preview": "electron-vite preview", 20 | "test": "vitest --passWithNoTests", 21 | "test:coverage": "vitest run --coverage", 22 | "type-check": "tsc -p tsconfig-check.json", 23 | "postuninstall": "electron-builder install-app-deps" 24 | }, 25 | "dependencies": { 26 | "chalk": "^4", 27 | "electron-is": "^3", 28 | "electron-updater": "^4.6.5", 29 | "log4js": "^6.4.1", 30 | "os-name": "^4", 31 | "reflect-metadata": "^0.1.13", 32 | "source-map-support": "^0.5.21", 33 | "umi-request": "^1" 34 | }, 35 | "devDependencies": { 36 | "@types/fs-extra": "^9", 37 | "@umi-electron-template/common": "2.0.0", 38 | "concurrently": "^8", 39 | "cross-env": "^7", 40 | "electron": "^24", 41 | "electron-builder": "^23", 42 | "electron-builder-notarize": "^1", 43 | "electron-debug": "^3", 44 | "electron-devtools-installer": "^3", 45 | "electron-vite": "^1", 46 | "happy-dom": "^9", 47 | "react-devtools": "^4", 48 | "vitest": "latest" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/main/scripts/zombieRender/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Electron 6 | 7 | 8 | 没有任何用处,只是保证 electron-vite 可以正常启动 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/main/src/browserItems.ts: -------------------------------------------------------------------------------- 1 | import type { BrowserWindowOpts } from '@/core/Browser'; 2 | import { BrowserWindowsIdentifier } from '@umi-electron-template/common'; 3 | 4 | export const home: BrowserWindowOpts = { 5 | identifier: BrowserWindowsIdentifier.home, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/main/src/core/App.ts: -------------------------------------------------------------------------------- 1 | import type { TServiceModule } from '@/services'; 2 | import { createLogProxy, createProtocol } from '@/utils'; 3 | import { app, ipcMain } from 'electron'; 4 | import { dev, windows } from 'electron-is'; 5 | import { EventEmitter } from 'events'; 6 | 7 | import BrowserManager from './BrowserManager'; 8 | import Logger from './Logger'; 9 | import { ServiceStorage } from './ServiceStorage'; 10 | 11 | import * as browserItems from '../browserItems'; 12 | 13 | const importAll = (r: any) => Object.values(r).map((v: any) => v.default); 14 | 15 | export type ServiceMap = Map; 16 | 17 | export class App extends EventEmitter { 18 | browserManager: BrowserManager; 19 | 20 | /** 21 | * app 包含的服务能力 22 | */ 23 | services: any = new WeakMap(); 24 | 25 | /** 26 | * 日志服务 27 | */ 28 | logger: Logger; 29 | 30 | /** 31 | * 承接 webview fetch 的事件表 32 | */ 33 | serviceEventMap: ServiceMap = new Map(); 34 | 35 | constructor() { 36 | super(); 37 | 38 | // 载入 services 39 | const services: TServiceModule[] = importAll( 40 | // @ts-ignore 41 | import.meta.globEager('../services/*Service.ts'), 42 | ); 43 | 44 | services.forEach((service) => this.addService(service)); 45 | 46 | // 批量注册 service 中 event 事件 供 webview 消费 47 | this.serviceEventMap.forEach((serviceInfo, key) => { 48 | // 获取相应方法 49 | const { service, methodName } = serviceInfo; 50 | 51 | ipcMain.handle(key, async (e, ...data) => { 52 | // 输出日志 53 | this.logger.module('Fetch', key); 54 | if (data) this.logger.data(...data); 55 | 56 | try { 57 | return await service[methodName](...data); 58 | } catch (error) { 59 | this.logger.error(error); 60 | 61 | // @ts-ignore 62 | return { error: error.message }; 63 | } 64 | }); 65 | }); 66 | 67 | // 启动窗口管理器 68 | this.browserManager = new BrowserManager(this); 69 | 70 | // 日志系统 71 | this.logger = new Logger(); 72 | } 73 | 74 | onActivate = () => { 75 | this.browserManager.browsers.get('home')!.show(); 76 | }; 77 | 78 | beforeQuit = () => {}; 79 | 80 | /** 81 | * 启动 app 82 | */ 83 | bootstrap = () => { 84 | // protocol.registerSchemesAsPrivileged([ 85 | // { scheme: 'app', privileges: { secure: true, standard: true } }, 86 | // ]); 87 | 88 | // 控制单例 89 | const isSingle = app.requestSingleInstanceLock(); 90 | if (!isSingle) { 91 | app.exit(0); 92 | } 93 | 94 | app.whenReady().then(() => { 95 | // 注册 app 协议 96 | createProtocol('app'); 97 | 98 | this.logger.logSystemInfo(); 99 | 100 | // 载入 browsers 101 | this.initBrowsers(); 102 | 103 | this.logger.info('app 初始化完毕!'); 104 | this.logger.divider('🎉'); 105 | }); 106 | 107 | app.on('window-all-closed', () => { 108 | if (windows()) { 109 | app.quit(); 110 | } 111 | }); 112 | 113 | app.on('activate', this.onActivate); 114 | // 115 | app.on('before-quit', () => { 116 | this.beforeQuit(); 117 | app.exit(); 118 | }); 119 | }; 120 | 121 | /** 122 | * 添加窗口 123 | 124 | */ 125 | initBrowsers() { 126 | Object.values(browserItems).forEach((item) => { 127 | this.browserManager.retrieveOrInitialize(item); 128 | }); 129 | } 130 | 131 | /** 132 | * 添加 service 133 | * @param ServiceClass 134 | */ 135 | addService(ServiceClass: TServiceModule) { 136 | const service = new ServiceClass(this); 137 | this.services.set(ServiceClass, service); 138 | 139 | ServiceStorage.services.get(ServiceClass)?.forEach((event) => { 140 | // 将 event 装饰器中的对象全部存到 ServiceEventMap 中 141 | this.serviceEventMap.set(event.name, { 142 | service, 143 | methodName: event.methodName, 144 | }); 145 | }); 146 | } 147 | 148 | /** 149 | * 初始化之前的操作 150 | */ 151 | beforeInit() { 152 | // 替换报错 logger 153 | if (!dev()) { 154 | console.error = createLogProxy( 155 | 'error', 156 | Logger.getLogger('error'), 157 | )(console.error); 158 | } 159 | 160 | // 初始化数据库部分 161 | // await loadContainerAsync(); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /packages/main/src/core/Browser.ts: -------------------------------------------------------------------------------- 1 | import type { MainEvents } from '@umi-electron-template/common'; 2 | import { BrowserWindowsIdentifier, isDev } from '@umi-electron-template/common'; 3 | import type { BrowserWindowConstructorOptions } from 'electron'; 4 | import { app, BrowserWindow, protocol } from 'electron'; 5 | import { dev } from 'electron-is'; 6 | import EventEmitter from 'events'; 7 | 8 | import type { App } from './App'; 9 | 10 | protocol.registerSchemesAsPrivileged([ 11 | { scheme: 'app', privileges: { secure: true, standard: true } }, 12 | ]); 13 | 14 | export interface BrowserWindowOpts extends BrowserWindowConstructorOptions { 15 | /** 16 | * URL 17 | */ 18 | identifier: BrowserWindowsIdentifier; 19 | title?: string; 20 | width?: number; 21 | height?: number; 22 | devTools?: boolean; 23 | } 24 | 25 | export default class Browser extends EventEmitter { 26 | /** 27 | * 外部的 app 28 | * @private 29 | */ 30 | private app: App; 31 | /** 32 | * 内部的 electron 窗口 33 | * @private 34 | */ 35 | private _browserWindow?: BrowserWindow; 36 | 37 | /** 38 | * 标识符 39 | */ 40 | identifier: string; 41 | 42 | /** 43 | * 生成时的选项 44 | */ 45 | options: BrowserWindowOpts; 46 | 47 | /** 48 | * 对外暴露的获取窗口的方法 49 | */ 50 | get browserWindow() { 51 | return this.retrieveOrInitialize(); 52 | } 53 | 54 | /** 55 | * 构建 BrowserWindows 对象的方法 56 | * @param options 57 | * @param application 58 | */ 59 | constructor(options: BrowserWindowOpts, application: App) { 60 | super(); 61 | this.app = application; 62 | this.identifier = options.identifier; 63 | this.options = options; 64 | 65 | // 初始化 66 | this.retrieveOrInitialize(); 67 | 68 | // 当关闭时将窗口实例销毁 69 | this.browserWindow.on('closed', () => { 70 | this.destroy(); 71 | }); 72 | } 73 | 74 | /** 75 | * 加载地址路径 76 | * @param name 在 renderer 中的路径名称 77 | */ 78 | loadUrl = (name: BrowserWindowsIdentifier) => { 79 | if (isDev) { 80 | this.browserWindow.loadURL(`http://localhost:7777/${name}.html`); 81 | } else { 82 | this.browserWindow.loadURL(`app://./${name}.html`); 83 | } 84 | }; 85 | 86 | /** 87 | * 加载 Dev 工具 88 | */ 89 | loadDevTools = () => { 90 | // 生产环境直接结束 91 | if (!(dev() || process.env.DEBUG === '1')) return; 92 | 93 | app.whenReady().then(() => { 94 | const { 95 | default: installExtension, 96 | // React Dev tools 暂时没法修复 (Electron 版本 >= 9.0) 97 | // https://github.com/electron/electron/issues/23662 98 | // REACT_DEVELOPER_TOOLS, 99 | REDUX_DEVTOOLS, 100 | // eslint-disable-next-line global-require 101 | } = require('electron-devtools-installer'); 102 | 103 | const extensions = [ 104 | // REACT_DEVELOPER_TOOLS, 105 | REDUX_DEVTOOLS, 106 | ]; 107 | 108 | try { 109 | installExtension(extensions).then((name: string) => { 110 | this.app.logger.trace(`Added Extension: ${name}`); 111 | }); 112 | } catch (e) { 113 | this.app.logger.error('An error occurred: ', e); 114 | } 115 | }); 116 | }; 117 | 118 | show() { 119 | this.browserWindow.show(); 120 | } 121 | 122 | hide() { 123 | this.browserWindow.hide(); 124 | } 125 | 126 | /** 127 | * 销毁实例 128 | */ 129 | destroy() { 130 | this._browserWindow = undefined; 131 | } 132 | 133 | /** 134 | * 初始化 135 | */ 136 | retrieveOrInitialize() { 137 | // 当有这个窗口 且这个窗口没有被注销时 138 | if (this._browserWindow && !this._browserWindow.isDestroyed()) { 139 | return this._browserWindow; 140 | } 141 | 142 | const { identifier, title, width, height, devTools, ...res } = this.options; 143 | 144 | this._browserWindow = new BrowserWindow({ 145 | ...res, 146 | width, 147 | height, 148 | title, 149 | 150 | webPreferences: { 151 | nodeIntegration: true, 152 | 153 | // 上下文隔离环境 154 | // https://www.electronjs.org/docs/tutorial/context-isolation 155 | contextIsolation: true, 156 | // devTools: isDev, 157 | }, 158 | }); 159 | 160 | this.loadUrl(identifier); 161 | 162 | this.loadDevTools(); 163 | 164 | // 显示 devtools 就打开 165 | if (devTools) { 166 | this._browserWindow.webContents.openDevTools(); 167 | } 168 | return this._browserWindow; 169 | } 170 | 171 | /** 172 | * 向 webview 派发事件 173 | * @param eventName 174 | * @param data 175 | */ 176 | dispatchEvent( 177 | eventName: T, 178 | data?: MainEvents[T], 179 | ) { 180 | let tempName = Math.random().toString(36).slice(-8); 181 | 182 | tempName = `a_${tempName}`; 183 | 184 | this.browserWindow.webContents.executeJavaScript(` 185 | const ${tempName} = new Event('electron:${eventName}'); 186 | ${tempName}.data = ${JSON.stringify(data)}; 187 | window.dispatchEvent(${tempName}); 188 | `); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /packages/main/src/core/BrowserManager.ts: -------------------------------------------------------------------------------- 1 | import type { MainEvents } from '@umi-electron-template/common'; 2 | 3 | import type { App } from './App'; 4 | import type { BrowserWindowOpts } from './Browser'; 5 | import Browser from './Browser'; 6 | 7 | export default class BrowserManager { 8 | app: App; 9 | 10 | browsers: Map = new Map(); 11 | 12 | constructor(app: App) { 13 | this.app = app; 14 | } 15 | 16 | /** 17 | * 启动或初始化 18 | * @param options 19 | */ 20 | retrieveOrInitialize(options: BrowserWindowOpts) { 21 | let browser = this.browsers.get(options.identifier); 22 | if (browser) { 23 | return browser; 24 | } 25 | 26 | browser = new Browser(options, this.app); 27 | 28 | // 监听 fetch 方法 29 | 30 | this.browsers.set(options.identifier, browser); 31 | 32 | return browser; 33 | } 34 | 35 | broadcast(eventName: T, data?: MainEvents[T]) { 36 | this.browsers.forEach((browser) => { 37 | browser?.dispatchEvent(eventName, data); 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/main/src/core/Logger/config.ts: -------------------------------------------------------------------------------- 1 | import { isDev } from '@umi-electron-template/common'; 2 | import { app } from 'electron'; 3 | import type { Configuration, Layout } from 'log4js'; 4 | import { join } from 'path'; 5 | 6 | const logDir = join(app.getPath('userData'), 'Logs'); 7 | 8 | const level = isDev ? 'trace' : 'info'; 9 | 10 | // 自定义日志格式 11 | const layout: Layout = { 12 | type: 'pattern', 13 | pattern: '%d{yyyy-MM-dd hh:mm:ss.SSS} [%p] %m', 14 | }; 15 | 16 | const config: Configuration = { 17 | appenders: { 18 | // 控制台输出 19 | console: { type: 'console' }, 20 | // 日志文件 21 | app: { 22 | type: 'file', 23 | filename: join(logDir, 'app', 'log.log'), 24 | // 日志切割后文件名后缀格式 25 | pattern: 'yyyy-MM-dd.log', 26 | }, 27 | // 数据库日志 28 | database: { 29 | type: 'file', 30 | filename: join(logDir, 'database', 'log.log'), 31 | pattern: 'yyyy-MM-dd.log', 32 | layout, 33 | }, 34 | error: { 35 | type: 'file', 36 | filename: join(logDir, 'error', 'log.log'), 37 | pattern: 'yyyy-MM-dd.log', 38 | }, 39 | }, 40 | categories: { 41 | default: { appenders: ['app', 'console'], level }, 42 | app: { appenders: ['app', 'console'], level }, 43 | main: { appenders: ['app', 'console'], level }, 44 | renderer: { appenders: ['app', 'console'], level }, 45 | // 数据库日志 46 | database: { appenders: ['database', 'console'], level }, 47 | // 错误日志,输出 error 及以上级别的日志 48 | error: { appenders: ['error'], level: 'error' }, 49 | }, 50 | }; 51 | 52 | export default config; 53 | -------------------------------------------------------------------------------- /packages/main/src/core/Logger/customLogger.ts: -------------------------------------------------------------------------------- 1 | import log4js from 'log4js'; 2 | 3 | import config from './config'; 4 | import { GetLogger, LogLevel, LogScope, LogWithScope } from './types'; 5 | 6 | declare module 'log4js' { 7 | // 为 Logger 补充自定义方法 8 | export interface Logger { 9 | divider(symbol?: string, length?: number): void; 10 | 11 | logWithScope(newScope: LogScope, ...args: any[]): void; 12 | 13 | infoWithScope(newScope: LogScope, ...args: any[]): void; 14 | 15 | errorWithScope(newScope: LogScope, ...args: any[]): void; 16 | 17 | traceWithScope(newScope: LogScope, ...args: any[]): void; 18 | 19 | warnWithScope(newScope: LogScope, ...args: any[]): void; 20 | 21 | debugWithScope(newScope: LogScope, ...args: any[]): void; 22 | } 23 | } 24 | 25 | log4js.configure(config); 26 | 27 | /** 28 | * 创建 withScope logger 代理 29 | * @param logLevel 30 | */ 31 | const withScopeFactory = (logLevel: LogLevel): LogWithScope => { 32 | return (newScope: LogScope, message: any, ...args: any[]) => { 33 | const logger = log4js.getLogger(newScope); 34 | logger[logLevel](message, ...args); 35 | }; 36 | }; 37 | 38 | export const getLogger: GetLogger = (scope) => { 39 | const logger = log4js.getLogger(scope); 40 | // 添加 divider 方法 41 | 42 | logger.divider = (str = '-', length = 10) => { 43 | let line = ''; 44 | for (let i = 0; i < length; i += 1) { 45 | line += str; 46 | } 47 | logger.info(line); 48 | }; 49 | 50 | // 添加 withScope 方法 51 | logger.infoWithScope = withScopeFactory('info'); 52 | logger.errorWithScope = withScopeFactory('error'); 53 | logger.traceWithScope = withScopeFactory('trace'); 54 | logger.warnWithScope = withScopeFactory('warn'); 55 | logger.debugWithScope = withScopeFactory('debug'); 56 | 57 | return logger; 58 | }; 59 | 60 | export const logger = getLogger(); 61 | -------------------------------------------------------------------------------- /packages/main/src/core/Logger/index.ts: -------------------------------------------------------------------------------- 1 | import { isDev } from '@umi-electron-template/common'; 2 | import chalk from 'chalk'; 3 | import { app } from 'electron'; 4 | import { arch, cpus, platform, release, totalmem } from 'os'; 5 | import osName from 'os-name'; 6 | 7 | import { getLogger } from './customLogger'; 8 | import { LogLevel, LogScope } from './types'; 9 | 10 | interface LogInfo { 11 | level: LogLevel; 12 | message: string; 13 | key: LogScope; 14 | } 15 | 16 | interface WithLogParams { 17 | // eslint-disable-next-line @typescript-eslint/ban-types 18 | before?: LogInfo | Function; 19 | // eslint-disable-next-line @typescript-eslint/ban-types 20 | after?: LogInfo | Function; 21 | } 22 | 23 | export { logAfter, logBefore } from './logDecorator'; 24 | 25 | export default class Logger { 26 | private logger = getLogger('main'); 27 | 28 | /** 29 | * 记录系统日志 30 | */ 31 | logSystemInfo = () => { 32 | if (isDev) return; 33 | 34 | this.logger.divider('🚀'); 35 | this.logger.info('开始启动 App...'); 36 | 37 | this.logger.divider(); 38 | this.logger.info(`操作系统: ${platform()} ${release()}(${arch()})`); 39 | this.logger.info(`系统版本:${osName()}`); 40 | this.logger.info(`处理器: ${cpus().length}核`); 41 | this.logger.info( 42 | `总内存: ${(totalmem() / 1024 / 1024 / 1024).toFixed(0)}G`, 43 | ); 44 | this.logger.info(`安装路径:${app.getAppPath()}`); 45 | this.logger.divider(); 46 | }; 47 | 48 | /** 49 | * 给对象带上日志切面 50 | * @param before 51 | * @param after 52 | */ 53 | static withLog = 54 | ({ before, after }: WithLogParams) => 55 | // eslint-disable-next-line @typescript-eslint/ban-types 56 | (func: Function) => { 57 | if (before) { 58 | if (typeof before === 'function') { 59 | before(); 60 | } else { 61 | const logger = getLogger(before.key); 62 | logger[before.level](before.message); 63 | } 64 | } 65 | 66 | func(); 67 | 68 | if (after) { 69 | if (typeof after === 'function') { 70 | after(); 71 | } else { 72 | const logger = getLogger(after.key); 73 | logger[after.level](after.message); 74 | } 75 | } 76 | }; 77 | 78 | info(msg: string) { 79 | this.logger.info(msg); 80 | } 81 | 82 | divider(msg: string) { 83 | this.logger.divider(msg); 84 | } 85 | 86 | static getLogger = getLogger; 87 | 88 | trace(msg: any, ...arg: any[]) { 89 | this.logger.trace(msg, ...arg); 90 | } 91 | 92 | error(msg: any, ...arg: any[]) { 93 | this.logger.error(msg, ...arg); 94 | } 95 | 96 | /** 97 | * 输出格式为: `[moduleName] 这是一条kitchen log...` 98 | */ 99 | module(moduleName: string, ...args: any[]) { 100 | console.log(chalk.blue(`[${moduleName}]`), ...args); 101 | } 102 | 103 | data(...data: any[]) { 104 | console.log(chalk.grey(`[Data]`), ...data); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /packages/main/src/core/Logger/logDecorator.ts: -------------------------------------------------------------------------------- 1 | import { logger } from './customLogger'; 2 | import { LogLevel, LogScope } from './types'; 3 | 4 | const log = (propertyName: string, params: string | LogParams) => { 5 | // 如果是 纯文本 直接输出 6 | if (typeof params === 'string') { 7 | logger.infoWithScope(propertyName as LogScope, params); 8 | } else { 9 | // 如果是对象 必须传入三个参数 然后输出 10 | const { level, message, scope } = params; 11 | logger[`${level}WithScope`](scope || propertyName, message); 12 | } 13 | }; 14 | 15 | interface LogParams { 16 | message: string; 17 | scope: LogScope; 18 | level: LogLevel; 19 | } 20 | 21 | /** 22 | * 在执行前调用 log 23 | */ 24 | export const logBefore = 25 | (params: string | LogParams) => 26 | (target: object, propertyName: string, descriptor: PropertyDescriptor) => { 27 | const method = descriptor.value; 28 | 29 | descriptor.value = function (...args: any[]) { 30 | log('main', params); 31 | return method.apply(this, args); 32 | }; 33 | }; 34 | 35 | /** 36 | * 在执行后调用 log 37 | */ 38 | export const logAfter = 39 | (params: string | LogParams) => 40 | (target: object, propertyName: string, descriptor: PropertyDescriptor) => { 41 | const method = descriptor.value; 42 | 43 | descriptor.value = function (...args: any[]) { 44 | try { 45 | return method.apply(this, args); 46 | } finally { 47 | log('main', params); 48 | } 49 | }; 50 | }; 51 | -------------------------------------------------------------------------------- /packages/main/src/core/Logger/types.ts: -------------------------------------------------------------------------------- 1 | import { Logger as _Logger } from 'log4js'; 2 | 3 | type Logger = _Logger; 4 | 5 | /** 6 | * 日志范围 7 | */ 8 | export type LogScope = 'database' | 'app' | 'renderer' | 'main' | 'error'; 9 | export type LogLevel = 'info' | 'error' | 'trace' | 'warn' | 'debug'; 10 | 11 | export type GetLogger = (scope?: LogScope) => Logger; 12 | 13 | export type LogWithScope = (newScope: LogScope, ...args: any[]) => void; 14 | -------------------------------------------------------------------------------- /packages/main/src/core/ServiceStorage.ts: -------------------------------------------------------------------------------- 1 | import { logAfter, logBefore } from './Logger'; 2 | 3 | /** 4 | * 存储插件中的 service 5 | */ 6 | export class ServiceStorage { 7 | static services: WeakMap< 8 | any, 9 | { name: string; methodName: string; showLog?: boolean }[] 10 | > = new WeakMap(); 11 | 12 | /** 13 | * 处理所有服务的初始化 14 | */ 15 | @logBefore('[服务]初始化服务...') 16 | @logAfter('[服务]初始化完成!') 17 | init() { 18 | // 服务上桥 19 | // global.services = { 20 | // user: this.user, 21 | // system: this.system, 22 | // }; 23 | // 检查 macOS 权限上桥 24 | // ipcMain.handle( 25 | // CHANNELS.CHECK_ACCESSIBILITY_FOR_MAC_OS, 26 | // this.system.checkAccessibilityForMacOS, 27 | // ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/main/src/index.ts: -------------------------------------------------------------------------------- 1 | import { App } from './core/App'; 2 | 3 | new App().bootstrap(); 4 | -------------------------------------------------------------------------------- /packages/main/src/services/SystemService.ts: -------------------------------------------------------------------------------- 1 | import { isMacOS } from '@umi-electron-template/common'; 2 | import { systemPreferences } from 'electron'; 3 | import { event, ServiceModule } from './index'; 4 | 5 | export default class SystemService extends ServiceModule { 6 | /** 7 | * 检查可用性 8 | */ 9 | @event('/system/check-accessibility') 10 | checkAccessibilityForMacOS() { 11 | if (!isMacOS) return; 12 | return systemPreferences.isTrustedAccessibilityClient(true); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/main/src/services/UserService.ts: -------------------------------------------------------------------------------- 1 | import { ServiceModule } from './index'; 2 | 3 | export default class UserService extends ServiceModule {} 4 | -------------------------------------------------------------------------------- /packages/main/src/services/index.ts: -------------------------------------------------------------------------------- 1 | import type { RendererEvents } from '@umi-electron-template/common'; 2 | 3 | import type { App } from '../core/App'; 4 | import { ServiceStorage } from '../core/ServiceStorage'; 5 | 6 | const baseDecorator = 7 | (name: string, showLog = true) => 8 | (target: any, methodName: string, descriptor: any) => { 9 | const actions = ServiceStorage.services.get(target.constructor) || []; 10 | actions.push({ 11 | name, 12 | methodName, 13 | showLog, 14 | }); 15 | ServiceStorage.services.set(target.constructor, actions); 16 | return descriptor; 17 | }; 18 | 19 | /** 20 | * service 用的 event 装饰器 21 | */ 22 | export const event = (url: keyof RendererEvents) => baseDecorator(url); 23 | 24 | export class ServiceModule { 25 | constructor(public app: App) { 26 | this.app = app; 27 | } 28 | } 29 | 30 | export type TServiceModule = typeof ServiceModule; 31 | -------------------------------------------------------------------------------- /packages/main/src/utils/AutoUpdater.ts: -------------------------------------------------------------------------------- 1 | import { autoUpdater } from 'electron-updater'; 2 | 3 | export class AppUpdater { 4 | constructor() { 5 | autoUpdater.checkForUpdatesAndNotify(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/main/src/utils/createProtocol.ts: -------------------------------------------------------------------------------- 1 | import { protocol } from 'electron'; 2 | import path from 'path'; 3 | import { URL } from 'url'; 4 | 5 | export const createProtocol = (scheme: string) => { 6 | protocol.registerFileProtocol(scheme, (request, respond) => { 7 | let pathName = new URL(request.url).pathname; 8 | pathName = decodeURI(pathName); // Needed in case URL contains spaces 9 | 10 | const filePath = path.join(__dirname, '../renderer', pathName); 11 | respond({ path: filePath }); 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /packages/main/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AutoUpdater'; 2 | export * from './createProtocol'; 3 | export * from './log'; 4 | -------------------------------------------------------------------------------- /packages/main/src/utils/log.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 创建日志代理方法 3 | * @param logLevel 日志级别 4 | * @param mainLogger 日志对象 5 | * @return {function} 6 | */ 7 | export const createLogProxy = 8 | (logLevel: string, mainLogger: any) => 9 | ( 10 | // eslint-disable-next-line @typescript-eslint/ban-types 11 | fn: Function, 12 | ) => 13 | (...args: any) => { 14 | fn(...args); 15 | mainLogger[logLevel](...args); 16 | }; 17 | -------------------------------------------------------------------------------- /packages/main/tsconfig-check.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/main/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src", "config"], 4 | "compilerOptions": { 5 | "module": "NodeNext", 6 | "target": "ESNext", 7 | "moduleResolution": "NodeNext", 8 | "baseUrl": ".", 9 | "paths": { 10 | "@/*": ["src/*"], 11 | "@@/*": ["src/.umi/*"] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/main/types/Logger.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace Main { 2 | import type { Logger as _Logger } from 'log4js'; 3 | 4 | type Logger = _Logger; 5 | 6 | /** 7 | * 日志范围 8 | */ 9 | type LogScope = 'database' | 'app' | 'renderer' | 'main' | 'error'; 10 | type LogLevel = 'info' | 'error' | 'trace' | 'warn' | 'debug'; 11 | 12 | type GetLogger = (scope?: LogScope) => Logger; 13 | 14 | type LogWithScope = (newScope: Main.LogScope, ...args: any[]) => void; 15 | } 16 | -------------------------------------------------------------------------------- /packages/preload/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@umi-electron-template/preload", 3 | "version": "2.0.0", 4 | "private": true, 5 | "description": "max electron template", 6 | "author": "Arvin Xu", 7 | "scripts": { 8 | "lint-eslint": "max lint", 9 | "lint-staged": "lint-staged", 10 | "lint:fix": "max eslint --fix", 11 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 12 | "test": "jest --passWithNoTests", 13 | "test:coverage": "jest --coverage --passWithNoTests" 14 | }, 15 | "dependencies": { 16 | "@electron-toolkit/preload": "^1.0.3", 17 | "electron": "^24" 18 | }, 19 | "devDependencies": { 20 | "vite": "^4" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/preload/src/index.ts: -------------------------------------------------------------------------------- 1 | import { ElectronAPI, electronAPI } from '@electron-toolkit/preload'; 2 | import { contextBridge } from 'electron'; 3 | 4 | declare global { 5 | interface Window { 6 | electron: ElectronAPI; 7 | api: unknown; 8 | } 9 | } 10 | 11 | // Custom APIs for renderer 12 | const api = {}; 13 | 14 | // Use `contextBridge` APIs to expose Electron APIs to 15 | // renderer only if context isolation is enabled, otherwise 16 | // just add to the DOM global. 17 | if (process.contextIsolated) { 18 | try { 19 | contextBridge.exposeInMainWorld('electron', electronAPI); 20 | contextBridge.exposeInMainWorld('api', api); 21 | } catch (error) { 22 | console.error(error); 23 | } 24 | } else { 25 | // @ts-ignore (define in dts) 26 | window.electron = electronAPI; 27 | // @ts-ignore (define in dts) 28 | window.api = api; 29 | } 30 | -------------------------------------------------------------------------------- /packages/renderer/.umirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@umijs/max'; 2 | import { resolve } from 'path'; 3 | 4 | export default defineConfig({ 5 | npmClient: 'pnpm', 6 | mpa: { 7 | layout: '@/layouts/BasicLayout', 8 | }, 9 | outputPath: resolve(__dirname, '../main/dist/renderer'), 10 | monorepoRedirect: {}, 11 | }); 12 | -------------------------------------------------------------------------------- /packages/renderer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@umi-electron-template/renderer", 3 | "version": "2.0.0", 4 | "private": true, 5 | "description": "max electron template", 6 | "author": "Arvin Xu", 7 | "main": "main.js", 8 | "scripts": { 9 | "build": "max build", 10 | "dev": "PORT=7777 max dev", 11 | "postinstall": "max setup", 12 | "lint-eslint": "max lint", 13 | "lint:fix": "max eslint --fix", 14 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 15 | "start": "npm run dev", 16 | "test": "jest", 17 | "test:coverage": "jest --coverage", 18 | "type-check": "tsc -p tsconfig-check.json" 19 | }, 20 | "dependencies": { 21 | "@ant-design/icons": "^5", 22 | "@arvinxu/macos-traffic-light": "^3", 23 | "@umi-electron-template/common": "2.0.0", 24 | "@umijs/max": "^4", 25 | "ahooks": "^3", 26 | "antd": "^5", 27 | "antd-style": "^3", 28 | "react": "^18", 29 | "react-dom": "^18", 30 | "react-layout-kit": "^1", 31 | "zustand": "^4" 32 | }, 33 | "devDependencies": { 34 | "@testing-library/react": "^13", 35 | "@types/react": "^18", 36 | "@types/react-dom": "^18" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/renderer/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useDarkMode'; 2 | export * from './useMainProcess'; 3 | -------------------------------------------------------------------------------- /packages/renderer/src/hooks/useAppEvent.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import type { MainEvents } from '@umi-electron-template/common'; 3 | 4 | /** 5 | * 在 renderer 监听 main 发过来的 event 6 | */ 7 | const useAppEvent = ( 8 | eventName: T, 9 | callback: (e: Event & { data?: MainEvents[T] }) => void, 10 | deps = [], 11 | ) => { 12 | const kitchenEvent = `electron:${eventName}`; 13 | useEffect(() => { 14 | window.addEventListener(kitchenEvent, callback); 15 | return () => { 16 | window.removeEventListener(kitchenEvent, callback); 17 | }; 18 | }, deps); 19 | }; 20 | 21 | export default useAppEvent; 22 | -------------------------------------------------------------------------------- /packages/renderer/src/hooks/useDarkMode.ts: -------------------------------------------------------------------------------- 1 | import { useLocalStorageState } from 'ahooks'; 2 | 3 | /** 4 | * DarkMode 需要的状态 5 | */ 6 | export const useDarkMode = () => { 7 | // DarkMode 可见 8 | const [theme, setTheme] = useLocalStorageState<'light' | 'dark'>('theme', { 9 | defaultValue: 'light', 10 | }); 11 | 12 | const switchDarkMode = () => { 13 | setTheme(theme === 'light' ? 'dark' : 'light'); 14 | }; 15 | 16 | return { theme, switchDarkMode }; 17 | }; 18 | -------------------------------------------------------------------------------- /packages/renderer/src/hooks/useMainProcess.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 打开外部链接 3 | */ 4 | export const useShell = () => { 5 | return { 6 | openUrl: (url: string) => { 7 | console.log(url); 8 | }, 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/renderer/src/layouts/BasicLayout.tsx: -------------------------------------------------------------------------------- 1 | import { useThemeStore } from '@/store/theme'; 2 | import { App } from 'antd'; 3 | import { ThemeProvider } from 'antd-style'; 4 | import 'antd/dist/reset.css'; 5 | import type { FC, PropsWithChildren } from 'react'; 6 | 7 | import useStyles from './style'; 8 | 9 | const BasicLayout: FC = ({ children }) => { 10 | const { themeMode } = useThemeStore(); 11 | 12 | const { styles } = useStyles(); 13 | 14 | const switchDarkMode = () => { 15 | useThemeStore.setState({ 16 | themeMode: themeMode === 'light' ? 'dark' : 'light', 17 | }); 18 | }; 19 | return ( 20 | 21 | {children} 22 |
23 | {'切换模式'} 32 |
33 |
34 | ); 35 | }; 36 | 37 | export default ({ children }: PropsWithChildren) => { 38 | const { themeMode } = useThemeStore(); 39 | 40 | return ( 41 | 42 | {children} 43 | 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /packages/renderer/src/layouts/style.ts: -------------------------------------------------------------------------------- 1 | import { createStyles } from 'antd-style'; 2 | 3 | export default createStyles(({ css, token }) => ({ 4 | button: css` 5 | position: fixed; 6 | right: 24px; 7 | bottom: 24px; 8 | z-index: 1200; 9 | display: flex; 10 | align-items: center; 11 | justify-content: center; 12 | width: 32px; 13 | height: 32px; 14 | background: ${token.colorBgElevated}; 15 | border-radius: 16px; 16 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); 17 | cursor: pointer; 18 | `, 19 | img: css` 20 | width: 20px; 21 | height: 20px; 22 | `, 23 | container: css` 24 | height: 100vh; 25 | background: ${token.colorBgLayout}; 26 | `, 27 | })); 28 | -------------------------------------------------------------------------------- /packages/renderer/src/pages/database/index.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react'; 2 | import { Button, Card } from 'antd'; 3 | 4 | import useStyles from './style'; 5 | import { dispatch } from '@/utils/dispatch'; 6 | 7 | const Home: FC = () => { 8 | const { styles } = useStyles(); 9 | return ( 10 |
11 | 12 | 20 | 21 |
22 | ); 23 | }; 24 | 25 | export default Home; 26 | -------------------------------------------------------------------------------- /packages/renderer/src/pages/database/style.ts: -------------------------------------------------------------------------------- 1 | import { createStyles, css } from 'antd-style'; 2 | 3 | export default createStyles(({ token }) => ({ 4 | container: css` 5 | background: ${token.colorBgLayout}; 6 | `, 7 | card: css` 8 | //@apply mt-4 w-80; 9 | `, 10 | })); 11 | -------------------------------------------------------------------------------- /packages/renderer/src/pages/home/index.tsx: -------------------------------------------------------------------------------- 1 | import type { FC } from 'react'; 2 | import { Button, Space } from 'antd'; 3 | import { Center, Flexbox } from 'react-layout-kit'; 4 | 5 | import { routeTo } from '@/utils'; 6 | import { useShell } from '@/hooks'; 7 | import useAppEvent from '@/hooks/useAppEvent'; 8 | 9 | import useStyles from './style'; 10 | 11 | const Home: FC = () => { 12 | const { openUrl } = useShell(); 13 | const { styles } = useStyles(); 14 | useAppEvent( 15 | 'initDatabase', 16 | (e) => { 17 | console.log(e.data); 18 | }, 19 | [], 20 | ); 21 | 22 | return ( 23 |
24 | 25 |
26 | welcome 33 |
34 |

欢迎使用 Umi Electron Template !

35 |
36 | 更多资料请浏览 37 | 空谷的 Electron 笔记 38 |
39 | 40 | 47 | 55 | 56 |
57 |
58 | ); 59 | }; 60 | 61 | export default Home; 62 | -------------------------------------------------------------------------------- /packages/renderer/src/pages/home/style.ts: -------------------------------------------------------------------------------- 1 | import { createStyles, css } from 'antd-style'; 2 | 3 | export default createStyles(({ token }) => ({ 4 | container: css` 5 | background: ${token.colorBgLayout}; 6 | 7 | padding: 48px; 8 | `, 9 | 10 | content: css` 11 | margin-bottom: 16px; 12 | `, 13 | 14 | link: css` 15 | color: ${token.colorPrimary}; 16 | `, 17 | 18 | img: css` 19 | width: 500px; 20 | `, 21 | })); 22 | -------------------------------------------------------------------------------- /packages/renderer/src/store/theme.ts: -------------------------------------------------------------------------------- 1 | import { ThemeMode } from 'antd-style'; 2 | import { create } from 'zustand'; 3 | 4 | export const useThemeStore = create(() => ({ themeMode: 'auto' as ThemeMode })); 5 | -------------------------------------------------------------------------------- /packages/renderer/src/utils/dispatch.ts: -------------------------------------------------------------------------------- 1 | import type { RendererEvents } from '@umi-electron-template/common'; 2 | 3 | /** 4 | * webview 端请求 sketch 端 event 数据的方法 5 | */ 6 | export const dispatch = async ( 7 | event: T, 8 | ...data: any[] 9 | ): Promise => { 10 | return; 11 | const ipcRenderer = require('electron').ipcRenderer; 12 | return await ipcRenderer.invoke(event, ...data); 13 | }; 14 | -------------------------------------------------------------------------------- /packages/renderer/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './route'; 2 | -------------------------------------------------------------------------------- /packages/renderer/src/utils/route.ts: -------------------------------------------------------------------------------- 1 | export const routeTo = (url: string) => { 2 | window.open(`${url}.html`); 3 | }; 4 | -------------------------------------------------------------------------------- /packages/renderer/tsconfig-check.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/renderer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@/*": ["src/*"], 7 | "@@/*": ["src/.umi/*"] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/**' 3 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /scripts/buildMacZip.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from 'child_process'; 2 | import fs from 'fs'; 3 | import yaml from 'js-yaml'; 4 | import { join } from 'path'; 5 | 6 | import { name as appName, version } from '../package.json'; 7 | // @ts-ignore 8 | import options from '../packages/main/electron-builder.config'; 9 | 10 | const dir = join(__dirname, '../release'); 11 | 12 | const appPath = `${dir}/mac/${options.productName}.app`; 13 | 14 | const zipFileName = `${appName}_setup_${version}_mac.zip`; 15 | 16 | const zipFilePath = `${dir}/${zipFileName}`; 17 | 18 | const appBuilder = join( 19 | __dirname, 20 | '../node_modules/app-builder-bin/mac/app-builder', 21 | ); 22 | 23 | console.log('Zipping...'); 24 | 25 | execSync( 26 | `ditto -c -k --sequesterRsrc --keepParent "${appPath}" "${zipFilePath}"`, 27 | ); 28 | 29 | console.log('Finished zipping!'); 30 | 31 | console.log('Collect data...'); 32 | 33 | const blockmap = JSON.parse( 34 | execSync( 35 | `${appBuilder} blockmap -i ${zipFilePath} -o ${dir}/th.zip`, 36 | ).toString(), 37 | ); 38 | console.log(blockmap); 39 | 40 | // eslint-disable-next-line radix 41 | blockmap.blockMapSize = parseInt( 42 | execSync( 43 | `ls -l ${dir}/th.zip | awk '{print $5}' && rm ${dir}/th.zip`, 44 | ).toString(), 45 | ); 46 | 47 | const doc = yaml.load(fs.readFileSync(`${dir}/latest-mac.yml`, 'utf8')) as any; 48 | 49 | doc.files.unshift({ 50 | url: zipFileName, 51 | ...blockmap, 52 | }); 53 | 54 | doc.path = zipFileName; 55 | doc.sha512 = blockmap.sha512; 56 | 57 | fs.writeFileSync( 58 | `${dir}/latest-mac.yml`, 59 | yaml.dump(doc, { lineWidth: 65535 }), 60 | 'utf8', 61 | ); 62 | -------------------------------------------------------------------------------- /scripts/update-electron-vendors.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * This script should be run in electron context 3 | * @example 4 | * ELECTRON_RUN_AS_NODE=1 electron scripts/update-electron-vendors.mjs 5 | */ 6 | 7 | import { writeFileSync } from 'fs'; 8 | 9 | const electronRelease = process.versions; 10 | 11 | const node = electronRelease.node.split('.')[0]; 12 | const chrome = electronRelease.v8.split('.').splice(0, 2).join(''); 13 | 14 | writeFileSync( 15 | './.electron-vendors.cache.json', 16 | JSON.stringify({ chrome, node }), 17 | ); 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "module": "CommonJS", 5 | "moduleResolution": "node", 6 | "importHelpers": true, 7 | "esModuleInterop": true, 8 | "resolveJsonModule": true, 9 | "sourceMap": true, 10 | "jsx": "react-jsx", 11 | // 12 | "strict": true, 13 | "noUnusedLocals": true, 14 | "noFallthroughCasesInSwitch": true, 15 | "noImplicitReturns": true, 16 | "inlineSources": true, 17 | "allowSyntheticDefaultImports": true, 18 | /** 开启装饰器 **/ 19 | "emitDecoratorMetadata": true, 20 | "experimentalDecorators": true, 21 | "skipLibCheck": true, 22 | "noEmitOnError": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.less'; 2 | declare module '*.png'; 3 | declare module 'less-vars-to-js'; 4 | declare module '*.svg' { 5 | export function ReactComponent( 6 | props: React.SVGProps, 7 | ): React.ReactElement; 8 | const url: string; 9 | export default url; 10 | } 11 | -------------------------------------------------------------------------------- /version/getVersion.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Entry function for get app version. 3 | * In current implementation, it returns `version` from `package.json`, but you can implement any logic here. 4 | * Runs several times for each vite configs and electron-builder config. 5 | * @return {string} 6 | */ 7 | export function getVersion() { 8 | return process.env.npm_package_version; 9 | } 10 | -------------------------------------------------------------------------------- /version/inject-app-version-plugin.mjs: -------------------------------------------------------------------------------- 1 | import { getVersion } from './getVersion.mjs'; 2 | 3 | /** 4 | * Somehow inject app version to vite build context 5 | * @return {import('vite').Plugin} 6 | */ 7 | export const injectAppVersion = () => ({ 8 | name: 'inject-version', 9 | config: () => { 10 | // TODO: Find better way to inject app version 11 | process.env.VITE_APP_VERSION = getVersion(); 12 | }, 13 | }); 14 | --------------------------------------------------------------------------------