├── _icons
├── add
├── icon.icns
├── icon.ico
├── icon.png
├── 30pxblue.png
├── 60pxblue.png
├── 90pxblue.png
├── 128pxblack.png
├── 128pxblue.png
├── 128pxwhite.png
├── 256pxblack.png
├── 256pxblue.png
├── 256pxwhite.png
├── 30pxblack.png
├── 30pxwhite.png
├── 512pxblack.png
├── 512pxblue.png
├── 512pxwhite.png
├── 60pxblack.png
├── 60pxwhite.png
├── 90pxblack.png
├── 90pxwhite.png
├── logotype1blue.png
├── logotype2blue.png
├── logotype1black.png
├── logotype1white.png
├── logotype2black.png
├── logotype2white.png
├── 30pxblack.svg
├── 30pxblue.svg
├── 30pxwhite.svg
├── 60pxblack.svg
├── 90pxblack.svg
├── 60pxblue.svg
├── 60pxwhite.svg
├── 128pxblack.svg
├── 90pxblue.svg
├── 90pxwhite.svg
├── 128pxblue.svg
├── 128pxwhite.svg
├── 256pxblack.svg
├── 256pxwhite.svg
├── 256pxblue.svg
├── 512pxblack.svg
├── 512pxblue.svg
├── 512pxwhite.svg
├── logotype1black.svg
├── logotype2black.svg
├── logotype1blue.svg
├── logotype1white.svg
├── logotype2blue.svg
└── logotype2white.svg
├── src
├── data
│ └── .gitkeep
├── utilities
│ └── workerSample.ts
├── vue-shims.d.ts
├── renderer
│ ├── assets
│ │ ├── logo.png
│ │ └── style
│ │ │ ├── main.scss
│ │ │ └── animations.scss
│ ├── store
│ │ ├── index.js
│ │ └── modules
│ │ │ └── index.js
│ ├── App.vue
│ ├── views
│ │ ├── Help.vue
│ │ ├── About.vue
│ │ └── Home.vue
│ ├── components
│ │ └── SystemInformation.vue
│ ├── router
│ │ └── index.js
│ └── main.js
├── index.ejs
└── main
│ └── index.js
├── static
└── .gitkeep
├── .vscode
├── settings.json
├── tasks.json
└── launch.json
├── screenshot.png
├── .prettierrc
├── .editorconfig
├── .github
├── main.workflow
└── FUNDING.yml
├── .gitignore
├── .whitesource
├── .eslintignore
├── appveyor.yml
├── .babelrc
├── tsconfig.json
├── .all-contributorsrc
├── LICENSE
├── .eslintrc.js
├── .travis.yml
├── _scripts
├── build.js
├── webpack.workers.config.js
├── webpack.main.config.js
├── dev-runner.js
├── webpack.renderer.config.js
└── webpack.web.config.js
├── package.json
└── README.md
/_icons/add:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/data/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/src/utilities/workerSample.ts:
--------------------------------------------------------------------------------
1 | export {}
2 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/screenshot.png
--------------------------------------------------------------------------------
/_icons/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/icon.icns
--------------------------------------------------------------------------------
/_icons/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/icon.ico
--------------------------------------------------------------------------------
/_icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/icon.png
--------------------------------------------------------------------------------
/_icons/30pxblue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/30pxblue.png
--------------------------------------------------------------------------------
/_icons/60pxblue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/60pxblue.png
--------------------------------------------------------------------------------
/_icons/90pxblue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/90pxblue.png
--------------------------------------------------------------------------------
/_icons/128pxblack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/128pxblack.png
--------------------------------------------------------------------------------
/_icons/128pxblue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/128pxblue.png
--------------------------------------------------------------------------------
/_icons/128pxwhite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/128pxwhite.png
--------------------------------------------------------------------------------
/_icons/256pxblack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/256pxblack.png
--------------------------------------------------------------------------------
/_icons/256pxblue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/256pxblue.png
--------------------------------------------------------------------------------
/_icons/256pxwhite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/256pxwhite.png
--------------------------------------------------------------------------------
/_icons/30pxblack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/30pxblack.png
--------------------------------------------------------------------------------
/_icons/30pxwhite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/30pxwhite.png
--------------------------------------------------------------------------------
/_icons/512pxblack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/512pxblack.png
--------------------------------------------------------------------------------
/_icons/512pxblue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/512pxblue.png
--------------------------------------------------------------------------------
/_icons/512pxwhite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/512pxwhite.png
--------------------------------------------------------------------------------
/_icons/60pxblack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/60pxblack.png
--------------------------------------------------------------------------------
/_icons/60pxwhite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/60pxwhite.png
--------------------------------------------------------------------------------
/_icons/90pxblack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/90pxblack.png
--------------------------------------------------------------------------------
/_icons/90pxwhite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/90pxwhite.png
--------------------------------------------------------------------------------
/_icons/logotype1blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/logotype1blue.png
--------------------------------------------------------------------------------
/_icons/logotype2blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/logotype2blue.png
--------------------------------------------------------------------------------
/src/vue-shims.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import Vue from 'vue'
3 | export default Vue
4 | }
5 |
--------------------------------------------------------------------------------
/_icons/logotype1black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/logotype1black.png
--------------------------------------------------------------------------------
/_icons/logotype1white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/logotype1white.png
--------------------------------------------------------------------------------
/_icons/logotype2black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/logotype2black.png
--------------------------------------------------------------------------------
/_icons/logotype2white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/_icons/logotype2white.png
--------------------------------------------------------------------------------
/src/renderer/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mubaidr/vue-electron-template/HEAD/src/renderer/assets/logo.png
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "singleQuote": true,
4 | "tabWidth": 2,
5 | "trailingComma": "es5",
6 | "useTabs": false
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "type": "shell",
4 | "tasks": [
5 | {
6 | "label": "debug",
7 | "command": "npm",
8 | "args": ["run", "debug"]
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = crlf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/.github/main.workflow:
--------------------------------------------------------------------------------
1 | workflow "New workflow" {
2 | on = "push"
3 | resolves = ["GitHub Action for npm"]
4 | }
5 |
6 | action "GitHub Action for npm" {
7 | uses = "actions/npm@59b64a598378f31e49cb76f27d6f3312b582f680"
8 | runs = "npm run build"
9 | }
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | dist/electron/*
3 | dist/web/*
4 | build/*
5 | !build/icons
6 | coverage
7 | node_modules/
8 | npm-debug.log
9 | npm-debug.log.*
10 | thumbs.db
11 | !.gitkeep
12 | data/tmp/
13 | .tmp/
14 | tmp/
15 | .cache
16 | dist
17 | coverage
18 | __coverage__
19 |
--------------------------------------------------------------------------------
/.whitesource:
--------------------------------------------------------------------------------
1 | ##########################################################
2 | #### WhiteSource "Bolt for Github" configuration file ####
3 | ##########################################################
4 |
5 | # Configuration #
6 | #---------------#
7 | ws.repo.scan=true
8 | vulnerable.check.run.conclusion.level=failure
9 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | dist/electron/*
3 | dist/web/*
4 | build/*
5 | !build/icons
6 | coverage
7 | node_modules/
8 | npm-debug.log
9 | npm-debug.log.*
10 | thumbs.db
11 | !.gitkeep
12 | data/tmp/
13 | .tmp/
14 | tmp/
15 | .cache
16 | dist
17 | coverage
18 | __coverage__
19 | node_modules
20 | _scripts
21 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | image: Visual Studio 2017
2 |
3 | platform:
4 | - x64
5 |
6 | cache:
7 | - node_modules
8 | - '%USERPROFILE%\.electron'
9 |
10 | init:
11 | - git config --global core.autocrlf input
12 |
13 | install:
14 | - ps: Install-Product node 12 x64
15 | - npm install
16 |
17 | build_script:
18 | - npm run build
19 |
20 | test: off
21 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/env",
5 | {
6 | "targets": {
7 | "chrome": "89",
8 | "node": "14.16"
9 | },
10 | "modules": "commonjs"
11 | }
12 | ]
13 | ],
14 | "plugins": [
15 | "@babel/proposal-class-properties",
16 | "@babel/proposal-object-rest-spread"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/src/renderer/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | // import createPersistedState from 'vuex-persistedstate'
4 |
5 | import modules from './modules'
6 |
7 | Vue.use(Vuex)
8 |
9 | export default new Vuex.Store({
10 | modules,
11 | strict: process.env.NODE_ENV !== 'production',
12 |
13 | // TODO: Enable when deploy
14 | // plugins: [createPersistedState()]
15 | })
16 |
--------------------------------------------------------------------------------
/src/renderer/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true,
4 | "esModuleInterop": true,
5 | "isolatedModules": true,
6 | "module": "es2015",
7 | "moduleResolution": "node",
8 | "resolveJsonModule": true,
9 | "strict": true,
10 | "target": "ES6",
11 | "types": ["node"]
12 | },
13 | "exclude": ["node_modules"],
14 | "files": ["src/vue-shims.d.ts"],
15 | "include": ["src/**/*.ts", "src/**/*.vue"]
16 | }
17 |
--------------------------------------------------------------------------------
/src/renderer/store/modules/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * The file enables `@/store/index.js` to import all vuex modules
3 | * in a one-shot manner. There should not be any reason to edit this file.
4 | */
5 |
6 | const files = require.context('.', false, /\.js$/)
7 | const modules = {}
8 |
9 | files.keys().forEach((key) => {
10 | if (key === './index.js') return
11 | modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
12 | })
13 |
14 | export default modules
15 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "configurations": [
3 | {
4 | "cwd": "${workspaceFolder}",
5 | "name": "Electron: Main",
6 | "port": 9222,
7 | "protocol": "inspector",
8 | "request": "attach",
9 | "sourceMaps": true,
10 | "type": "node"
11 | },
12 | {
13 | "name": "Electron: Renderer",
14 | "port": 9223,
15 | "request": "attach",
16 | "sourceMaps": true,
17 | "type": "chrome",
18 | "webRoot": "${workspaceFolder}"
19 | }
20 | ],
21 | "version": "0.2.0"
22 | }
23 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: mubaidr
4 | patreon: mubaidr
5 | open_collective: mubaidr
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: mubaidr
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with a single custom sponsorship URL
13 |
--------------------------------------------------------------------------------
/src/renderer/views/Help.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Help
5 |
6 |
7 | Add help content here
8 |
9 |
10 |
11 | System Information
12 |
13 |
14 |
15 |
16 |
17 |
18 |
27 |
28 |
33 |
--------------------------------------------------------------------------------
/src/renderer/assets/style/main.scss:
--------------------------------------------------------------------------------
1 | html {
2 | overflow: auto;
3 | }
4 |
5 | body {
6 | -webkit-user-select: none;
7 | -moz-user-select: -moz-none;
8 | -ms-user-select: none;
9 | user-select: none;
10 | }
11 |
12 | img {
13 | box-shadow: none;
14 | }
15 |
16 | .section {
17 | padding: 1.5em;
18 | }
19 |
20 | span + .material-icons {
21 | margin-left: 0.25em;
22 | }
23 |
24 | .material-icons + span {
25 | margin-left: 0.25em;
26 | }
27 |
28 | .has-pointer {
29 | cursor: pointer;
30 | }
31 |
32 | .no-padding {
33 | padding: 0 !important;
34 | }
35 |
36 | .file-name {
37 | padding-top: 0.25em;
38 | }
39 |
40 | /* custom Scroll bars */
41 | ::-webkit-scrollbar {
42 | width: 10px !important;
43 | height: 10px !important;
44 | }
45 |
46 | ::-webkit-scrollbar-track {
47 | background: #f0f0f0;
48 | }
49 |
50 | ::-webkit-scrollbar-thumb {
51 | background: #666666;
52 | }
53 |
--------------------------------------------------------------------------------
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "vue-electron-template",
3 | "projectOwner": "mubaidr",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": [
7 | "README.md"
8 | ],
9 | "imageSize": 100,
10 | "commit": false,
11 | "contributors": [
12 | {
13 | "login": "jbeguna04",
14 | "name": "Jibbie R. Eguna",
15 | "avatar_url": "https://avatars3.githubusercontent.com/u/35353768?v=4",
16 | "profile": "https://github.com/jbeguna04",
17 | "contributions": [
18 | "design"
19 | ]
20 | },
21 | {
22 | "login": "eiurur",
23 | "name": "eiurur",
24 | "avatar_url": "https://avatars0.githubusercontent.com/u/4101830?v=4",
25 | "profile": "https://github.com/eiurur",
26 | "contributions": [
27 | "code"
28 | ]
29 | }
30 | ],
31 | "contributorsPerLine": 7,
32 | "skipCi": true
33 | }
34 |
--------------------------------------------------------------------------------
/src/renderer/components/SystemInformation.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Package
7 | Version
8 |
9 |
10 |
11 |
12 | Platform
13 | {{ platform }}
14 |
15 |
16 | {{ lib }}
17 | {{ versions[lib] }}
18 |
19 |
20 |
21 |
22 |
23 |
24 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 | <% if (htmlWebpackPlugin.options.nodeModules) { %>
12 |
17 | <% } %>
18 |
19 |
20 |
21 |
22 |
23 |
24 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/renderer/views/About.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
About
4 |
20 |
21 |
System Information
22 |
23 |
24 |
25 |
26 |
27 |
36 |
37 |
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Muhammad Ubaid Raza
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 |
--------------------------------------------------------------------------------
/src/renderer/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Vue-Electron-Template
14 |
15 |
16 | The boilerplate for making electron applications using vue.js.
17 |
18 |
19 | info
20 | About
21 |
22 |
23 | help
24 | Help
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
41 |
42 |
47 |
--------------------------------------------------------------------------------
/src/renderer/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import About from '../views/About.vue'
4 | import Help from '../views/Help.vue'
5 | import Home from '../views/Home.vue'
6 |
7 | Vue.use(Router)
8 |
9 | const router = new Router({
10 | routes: [
11 | {
12 | path: '/',
13 | redirect: '/home',
14 | },
15 | {
16 | path: '/home',
17 | meta: {
18 | title: 'Home',
19 | icon: 'fa-home',
20 | },
21 | component: Home,
22 | },
23 | {
24 | path: '/about',
25 | meta: {
26 | title: 'About',
27 | icon: 'fa-info-circle',
28 | },
29 | component: About,
30 | },
31 | {
32 | path: '/help',
33 | meta: {
34 | title: 'Help',
35 | icon: 'fa-info-circle',
36 | },
37 | component: Help,
38 | },
39 | {
40 | path: '*',
41 | redirect: '/home',
42 | },
43 | ],
44 | })
45 |
46 | // dynamically set application title to current view
47 | router.afterEach((to) => {
48 | let title =
49 | to.path === '/home'
50 | ? process.env.PRODUCT_NAME
51 | : `${to.meta.title} - ${process.env.PRODUCT_NAME}`
52 |
53 | if (!title) {
54 | title = 'Home'
55 | }
56 |
57 | document.title = title
58 | })
59 |
60 | export default router
61 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // https://eslint.org/docs/user-guide/configuring#using-configuration-files-1
3 | root: true,
4 |
5 | // https://eslint.org/docs/user-guide/configuring#specifying-environments
6 | env: {
7 | browser: true,
8 | node: true,
9 | },
10 |
11 | // https://eslint.org/docs/user-guide/configuring#specifying-parser
12 | parser: 'vue-eslint-parser',
13 |
14 | // https://vuejs.github.io/eslint-plugin-vue/user-guide/#faq
15 | parserOptions: {
16 | parser: 'babel-eslint',
17 | ecmaVersion: 2018,
18 | sourceType: 'module',
19 | },
20 |
21 | // https://eslint.org/docs/user-guide/configuring#extending-configuration-files
22 | // order matters: from least important to most important in terms of overriding
23 | // Prettier + Vue: https://medium.com/@gogl.alex/how-to-properly-set-up-eslint-with-prettier-for-vue-or-nuxt-in-vscode-e42532099a9c
24 | extends: [
25 | 'eslint:recommended',
26 | 'plugin:vue/recommended',
27 | 'plugin:@typescript-eslint/eslint-recommended',
28 | 'plugin:@typescript-eslint/recommended',
29 | 'plugin:@typescript-eslint/recommended-requiring-type-checking',
30 | 'prettier',
31 | 'prettier/@typescript-eslint',
32 | 'prettier/vue',
33 | ],
34 |
35 | // https://eslint.org/docs/user-guide/configuring#configuring-plugins
36 | plugins: ['vue', '@typescript-eslint', 'prettier'],
37 |
38 | rules: {
39 | 'no-console': 0,
40 | semi: 0,
41 | },
42 | }
43 |
--------------------------------------------------------------------------------
/src/renderer/main.js:
--------------------------------------------------------------------------------
1 | import 'bulma-fluent/bulma.sass'
2 | import 'material-design-icons/iconfont/material-icons.css'
3 | import Vue from 'vue'
4 | import App from './App.vue'
5 | import './assets/style/animations.scss'
6 | import './assets/style/main.scss'
7 | import router from './router/index'
8 | import store from './store/index'
9 |
10 | const isDev = process.env.NODE_ENV === 'development'
11 |
12 | Vue.config.devtools = isDev
13 | Vue.config.performance = isDev
14 | Vue.config.productionTip = isDev
15 |
16 | // tslint:disable-next-line: no-unused-expression
17 | new Vue({
18 | el: '#app',
19 | router,
20 | store,
21 | render: (h) => h(App),
22 | })
23 |
24 | // to avoild accesing electorn api from web app build
25 | if (window && window.process && window.process.type === 'renderer') {
26 | const { ipcRenderer } = require('electron')
27 |
28 | // handle menu event updates from main script
29 | ipcRenderer.on('change-view', (event, data) => {
30 | if (data.route) {
31 | router.push(data.route)
32 | }
33 | })
34 | }
35 |
36 | // sample context menu
37 | // const { remote } = require('electron')
38 | // const { Menu, MenuItem } = remote
39 | // const menu = new Menu()
40 | // menu.append(new MenuItem({ label: 'Home' }))
41 | // menu.append(new MenuItem({ type: 'separator' }))
42 | // menu.append(new MenuItem({ label: 'Other' }))
43 |
44 | // window.addEventListener(
45 | // 'contextmenu',
46 | // (e) => {
47 | // e.preventDefault()
48 | // menu.popup({ window: remote.getCurrentWindow() })
49 | // },
50 | // false
51 | // )
52 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | matrix:
2 | include:
3 | - os: osx
4 | osx_image: xcode9.3
5 | language: node_js
6 | node_js: '12'
7 | env:
8 | - ELECTRON_CACHE=$HOME/.cache/electron
9 | - ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
10 |
11 | - os: linux
12 | services: docker
13 | language: node_js
14 | node_js: '12'
15 | env:
16 | - ELECTRON_CACHE=$HOME/.cache/electron
17 | - ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
18 |
19 | cache:
20 | directories:
21 | - node_modules
22 | - $HOME/.cache/electron
23 | - $HOME/.cache/electron-builder
24 |
25 | before_install:
26 | - |
27 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then
28 | mkdir -p /tmp/git-lfs && curl -L https://github.com/github/git-lfs/releases/download/v2.3.1/git-lfs-$([ "$TRAVIS_OS_NAME" == "linux" ] && echo "linux" || echo "darwin")-amd64-2.3.1.tar.gz | tar -xz -C /tmp/git-lfs --strip-components 1
29 | export PATH="/tmp/git-lfs:$PATH"
30 | fi
31 | before_script:
32 | - git lfs pull
33 |
34 | script:
35 | - |
36 | if [ "$TRAVIS_OS_NAME" == "linux" ]; then
37 | docker run --rm \
38 | --env-file <(env | grep -v '\r' | grep -iE 'DEBUG|NODE_|ELECTRON_|YARN_|NPM_|CI|CIRCLE|TRAVIS|APPVEYOR_|CSC_|_TOKEN|_KEY|AWS_|STRIP|BUILD_') \
39 | -v ${PWD}:/project \
40 | -v ~/.cache/electron:/root/.cache/electron \
41 | -v ~/.cache/electron-builder:/root/.cache/electron-builder \
42 | electronuserland/builder:wine
43 | fi
44 | - npm run build
45 |
46 | before_cache:
47 | - rm -rf $HOME/.cache/electron-builder/wine
48 |
49 | branches:
50 | except:
51 | - "/^v\\d+\\.\\d+\\.\\d+$/"
52 |
--------------------------------------------------------------------------------
/_scripts/build.js:
--------------------------------------------------------------------------------
1 | const os = require('os')
2 | const builder = require('electron-builder')
3 |
4 | const Platform = builder.Platform
5 | const { name, productName } = require('../package.json')
6 |
7 | let targets
8 | var platform = os.platform()
9 |
10 | if (platform == 'darwin') {
11 | targets = Platform.MAC.createTarget()
12 | } else if (platform == 'win32') {
13 | targets = Platform.WINDOWS.createTarget()
14 | } else if (platform == 'linux') {
15 | targets = Platform.LINUX.createTarget()
16 | }
17 |
18 | const config = {
19 | appId: `com.mubaidr.${name}`,
20 | copyright: 'Copyright ©2019 mubaidr@gmail.com',
21 | // asar: false,
22 | // compression: 'store',
23 | productName,
24 | directories: {
25 | output: './build/',
26 | },
27 | files: ['_icons/icon.*', './dist/**/*', '!./dist/web/**/*'],
28 | dmg: {
29 | contents: [
30 | {
31 | path: '/Applications',
32 | type: 'link',
33 | x: 410,
34 | y: 230,
35 | },
36 | {
37 | type: 'file',
38 | x: 130,
39 | y: 230,
40 | },
41 | ],
42 | window: {
43 | height: 380,
44 | width: 540,
45 | },
46 | },
47 | linux: {
48 | icon: '_icons/icon.png',
49 | target: ['deb', 'snap', 'AppImage'],
50 | },
51 | mac: {
52 | category: 'public.app-category.utilities',
53 | icon: '_icons/icon.icns',
54 | target: ['dmg', 'zip'],
55 | type: 'distribution',
56 | },
57 | win: {
58 | icon: '_icons/icon.ico',
59 | target: ['nsis', 'zip', 'portable'],
60 | },
61 | nsis: {
62 | allowToChangeInstallationDirectory: true,
63 | oneClick: false,
64 | },
65 | }
66 |
67 | builder
68 | .build({
69 | targets,
70 | config,
71 | })
72 | .then((m) => {
73 | console.log(m)
74 | })
75 | .catch((e) => {
76 | console.error(e)
77 | })
78 |
--------------------------------------------------------------------------------
/_scripts/webpack.workers.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 |
4 | const {
5 | dependencies,
6 | devDependencies,
7 | productName,
8 | } = require('../package.json')
9 |
10 | const externals = Object.keys(dependencies).concat(Object.keys(devDependencies))
11 | const isDevMode = process.env.NODE_ENV === 'development'
12 |
13 | const config = {
14 | name: 'workers',
15 | mode: process.env.NODE_ENV,
16 | devtool: isDevMode ? 'eval-source-map' : false,
17 | entry: {
18 | workerSample: path.join(__dirname, '../src/utilities/workerSample.ts'),
19 | },
20 | output: {
21 | libraryTarget: 'commonjs2',
22 | path: path.join(__dirname, '../dist'),
23 | filename: '[name].js',
24 | },
25 | externals: externals,
26 | module: {
27 | rules: [
28 | {
29 | test: /\.tsx?$/,
30 | use: 'ts-loader',
31 | exclude: /node_modules/,
32 | },
33 | {
34 | test: /\.js$/,
35 | use: 'babel-loader',
36 | exclude: /node_modules/,
37 | },
38 | {
39 | test: /\.node$/,
40 | use: 'node-loader',
41 | },
42 | ],
43 | },
44 | node: {
45 | global: true,
46 | __dirname: isDevMode,
47 | __filename: isDevMode,
48 | },
49 | plugins: [
50 | // new WriteFilePlugin(),
51 | new webpack.DefinePlugin({
52 | 'process.env.PRODUCT_NAME': JSON.stringify(productName),
53 | }),
54 | ],
55 | resolve: {
56 | alias: {
57 | '@': path.join(__dirname, '../src/'),
58 | src: path.join(__dirname, '../src/'),
59 | },
60 | extensions: ['.ts', '.js', '.json'],
61 | },
62 | target: 'node',
63 | }
64 |
65 | /**
66 | * Adjust rendererConfig for production settings
67 | */
68 | if (isDevMode) {
69 | // any dev only config
70 | config.plugins.push(new webpack.HotModuleReplacementPlugin())
71 | } else {
72 | config.plugins.push(
73 | new webpack.LoaderOptionsPlugin({
74 | minimize: true,
75 | })
76 | )
77 | }
78 |
79 | module.exports = config
80 |
--------------------------------------------------------------------------------
/_scripts/webpack.main.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const CopyWebpackPlugin = require('copy-webpack-plugin')
4 |
5 | const {
6 | dependencies,
7 | devDependencies,
8 | productName,
9 | } = require('../package.json')
10 |
11 | const externals = Object.keys(dependencies).concat(Object.keys(devDependencies))
12 | const isDevMode = process.env.NODE_ENV === 'development'
13 | const whiteListedModules = []
14 |
15 | const config = {
16 | name: 'main',
17 | mode: process.env.NODE_ENV,
18 | devtool: isDevMode ? 'eval-source-map' : false,
19 | entry: {
20 | main: path.join(__dirname, '../src/main/index.js'),
21 | },
22 | externals: externals.filter((d) => !whiteListedModules.includes(d)),
23 | module: {
24 | rules: [
25 | {
26 | test: /\.tsx?$/,
27 | use: 'ts-loader',
28 | exclude: /node_modules/,
29 | },
30 | {
31 | test: /\.js$/,
32 | use: 'babel-loader',
33 | exclude: /node_modules/,
34 | },
35 | {
36 | test: /\.node$/,
37 | use: 'node-loader',
38 | },
39 | ],
40 | },
41 | node: {
42 | global: true,
43 | __dirname: isDevMode,
44 | __filename: isDevMode,
45 | },
46 | plugins: [
47 | new webpack.DefinePlugin({
48 | 'process.env.PRODUCT_NAME': JSON.stringify(productName),
49 | }),
50 | ],
51 | output: {
52 | filename: '[name].js',
53 | libraryTarget: 'commonjs2',
54 | path: path.join(__dirname, '../dist'),
55 | },
56 | resolve: {
57 | extensions: ['.ts', '.js', '.json'],
58 | alias: {
59 | '@': path.join(__dirname, '../src/'),
60 | src: path.join(__dirname, '../src/'),
61 | },
62 | },
63 | target: 'electron-main',
64 | }
65 |
66 | if (isDevMode) {
67 | config.plugins.push(
68 | new webpack.DefinePlugin({
69 | __static: `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`,
70 | })
71 | )
72 | } else {
73 | config.plugins.push(
74 | new CopyWebpackPlugin({
75 | patterns: [
76 | {
77 | from: path.join(__dirname, '../src/data'),
78 | to: path.join(__dirname, '../dist/data'),
79 | },
80 | {
81 | from: path.join(__dirname, '../static'),
82 | to: path.join(__dirname, '../dist/static'),
83 | globOptions: {
84 | ignore: ['.*'],
85 | },
86 | },
87 | ],
88 | }),
89 | new webpack.LoaderOptionsPlugin({
90 | minimize: true,
91 | })
92 | )
93 | }
94 |
95 | module.exports = config
96 |
--------------------------------------------------------------------------------
/_icons/30pxblack.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/30pxblue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/30pxwhite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/60pxblack.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/90pxblack.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/60pxblue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/60pxwhite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/128pxblack.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/90pxblue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/90pxwhite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/128pxblue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/128pxwhite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/256pxblack.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/256pxwhite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/256pxblue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_scripts/dev-runner.js:
--------------------------------------------------------------------------------
1 | process.env.NODE_ENV = 'development'
2 | // process.env.ELECTRON_ENABLE_LOGGING = true
3 |
4 | const chalk = require('chalk')
5 | const electron = require('electron')
6 | const webpack = require('webpack')
7 | const WebpackDevServer = require('webpack-dev-server')
8 | const kill = require('tree-kill')
9 |
10 | const path = require('path')
11 | const { spawn } = require('child_process')
12 |
13 | const mainConfig = require('./webpack.main.config')
14 | const rendererConfig = require('./webpack.renderer.config')
15 | const workersConfig = require('./webpack.workers.config')
16 |
17 | let electronProcess = null
18 | let manualRestart = null
19 | const remoteDebugging = process.argv.includes('--remote-debug')
20 |
21 | if (remoteDebugging) {
22 | // disable dvtools open in electron
23 | process.env.RENDERER_REMOTE_DEBUGGING = true
24 | }
25 |
26 | async function killElectron(pid) {
27 | return new Promise((resolve, reject) => {
28 | if (pid) {
29 | kill(pid, 'SIGKILL', (err) => {
30 | if (err) reject(err)
31 |
32 | resolve()
33 | })
34 | } else {
35 | resolve()
36 | }
37 | })
38 | }
39 |
40 | async function restartElectron() {
41 | console.log(chalk.gray('\nStarting electron...'))
42 |
43 | const { pid } = electronProcess || {}
44 | await killElectron(pid)
45 |
46 | electronProcess = spawn(electron, [
47 | path.join(__dirname, '../dist/main.js'),
48 | // '--enable-logging', // Enable to show logs from all electron processes
49 | remoteDebugging ? '--inspect=9222' : '',
50 | remoteDebugging ? '--remote-debugging-port=9223' : '',
51 | ])
52 |
53 | electronProcess.stdout.on('data', (data) => {
54 | console.log(chalk.white(data.toString()))
55 | })
56 |
57 | electronProcess.stderr.on('data', (data) => {
58 | console.error(chalk.red(data.toString()))
59 | })
60 |
61 | electronProcess.on('exit', (code, signal) => {
62 | if (!manualRestart) process.exit(0)
63 | })
64 | }
65 |
66 | function startMain() {
67 | const webpackSetup = webpack([mainConfig, workersConfig])
68 |
69 | webpackSetup.compilers.forEach((compiler) => {
70 | const { name } = compiler
71 |
72 | switch (name) {
73 | case 'workers':
74 | compiler.hooks.afterEmit.tap('afterEmit', async () => {
75 | console.log(chalk.gray(`\nCompiled ${name} script!`))
76 | console.log(
77 | chalk.gray(`\nWatching file changes for ${name} script...`)
78 | )
79 | })
80 | break
81 | case 'main':
82 | default:
83 | compiler.hooks.afterEmit.tap('afterEmit', async () => {
84 | console.log(chalk.gray(`\nCompiled ${name} script!`))
85 |
86 | manualRestart = true
87 | await restartElectron()
88 |
89 | setTimeout(() => {
90 | manualRestart = false
91 | }, 2500)
92 |
93 | console.log(
94 | chalk.gray(`\nWatching file changes for ${name} script...`)
95 | )
96 | })
97 | break
98 | }
99 | })
100 |
101 | webpackSetup.watch(
102 | {
103 | aggregateTimeout: 500,
104 | },
105 | (err) => {
106 | if (err) console.error(chalk.red(err))
107 | }
108 | )
109 | }
110 |
111 | function startRenderer(callback) {
112 | const compiler = webpack(rendererConfig)
113 | const { name } = compiler
114 |
115 | compiler.hooks.afterEmit.tap('afterEmit', () => {
116 | console.log(chalk.gray(`\nCompiled ${name} script!`))
117 | console.log(chalk.gray(`\nWatching file changes for ${name} script...`))
118 | })
119 |
120 | const server = new WebpackDevServer(compiler, {
121 | contentBase: path.join(__dirname, '../'),
122 | hot: true,
123 | noInfo: true,
124 | overlay: true,
125 | clientLogLevel: 'warning',
126 | })
127 |
128 | server.listen(9080, '', (err) => {
129 | if (err) console.error(chalk.red(err))
130 |
131 | callback()
132 | })
133 | }
134 |
135 | startRenderer(startMain)
136 |
--------------------------------------------------------------------------------
/_icons/512pxblack.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/512pxblue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/512pxwhite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Muhammad Ubaid Raza ",
3 | "bugs": {
4 | "url": "https://github.com/mubaidr/vue-electron-template/issues"
5 | },
6 | "dependencies": {
7 | "@electron/remote": "^1.1.0",
8 | "bulma-fluent": "^0.4.3",
9 | "material-design-icons": "^3.0.1",
10 | "vue": "^2.6.12",
11 | "vue-electron": "^1.0.6",
12 | "vue-router": "^3.5.1",
13 | "vuex": "^3.6.2"
14 | },
15 | "description": "An electron-vue project",
16 | "devDependencies": {
17 | "@babel/core": "^7.13.15",
18 | "@babel/plugin-proposal-class-properties": "^7.13.0",
19 | "@babel/plugin-proposal-object-rest-spread": "^7.13.8",
20 | "@babel/preset-env": "^7.13.15",
21 | "@types/babel__core": "^7.1.14",
22 | "@types/babel__preset-env": "^7.9.1",
23 | "@types/copy-webpack-plugin": "^6.4.1",
24 | "@types/electron-devtools-installer": "^2.2.0",
25 | "@types/eslint": "^7.2.9",
26 | "@types/eslint-plugin-prettier": "^3.1.0",
27 | "@types/file-loader": "^4.2.1",
28 | "@types/mini-css-extract-plugin": "^1.4.1",
29 | "@types/prettier": "^2.2.3",
30 | "@types/sass": "^1.16.0",
31 | "@typescript-eslint/eslint-plugin": "^4.22.0",
32 | "@typescript-eslint/parser": "^4.22.0",
33 | "babel-eslint": "^10.1.0",
34 | "babel-loader": "^8.2.2",
35 | "chalk": "^4.1.0",
36 | "copy-webpack-plugin": "^8.1.1",
37 | "css-loader": "^5.2.1",
38 | "electron": "^12.0.2",
39 | "electron-builder": "^22.10.5",
40 | "electron-debug": "^3.2.0",
41 | "electron-devtools-installer": "^3.1.1",
42 | "electron-rebuild": "^2.3.5",
43 | "eslint": "^7.24.0",
44 | "eslint-config-prettier": "^8.1.0",
45 | "eslint-plugin-prettier": "^3.3.1",
46 | "eslint-plugin-vue": "^7.9.0",
47 | "fast-glob": "^3.2.5",
48 | "file-loader": "^6.2.0",
49 | "html-webpack-plugin": "^5.3.1",
50 | "mini-css-extract-plugin": "^1.4.1",
51 | "node-loader": "^2.0.0",
52 | "npm-run-all": "^4.1.5",
53 | "prettier": "^2.2.1",
54 | "sass": "^1.32.8",
55 | "sass-loader": "^11.0.1",
56 | "style-loader": "^2.0.0",
57 | "tree-kill": "1.2.2",
58 | "ts-loader": "^8.1.0",
59 | "typescript": "^4.2.4",
60 | "url-loader": "^4.1.1",
61 | "vue-eslint-parser": "^7.6.0",
62 | "vue-loader": "^15.9.6",
63 | "vue-style-loader": "^4.1.3",
64 | "vue-template-compiler": "^2.6.12",
65 | "webpack": "^5.31.2",
66 | "webpack-cli": "^4.6.0",
67 | "webpack-dev-server": "^3.11.2"
68 | },
69 | "license": "MIT",
70 | "main": "./dist/main.js",
71 | "name": "vue-electron-template",
72 | "private": true,
73 | "productName": "Vue Electron Template",
74 | "repository": {
75 | "type": "git",
76 | "url": "git+https://github.com/mubaidr/vue-electron-template.git"
77 | },
78 | "scripts": {
79 | "build": "run-s rebuild:electron pack build-release",
80 | "build-release": "node _scripts/build.js",
81 | "debug": "run-s rebuild:electron debug-runner",
82 | "debug-runner": "node _scripts/dev-runner.js --remote-debug",
83 | "dev": "run-s rebuild:electron dev-runner",
84 | "dev-runner": "node _scripts/dev-runner.js",
85 | "electron-builder-install": "electron-builder install-app-deps",
86 | "electron-rebuild": "electron-rebuild",
87 | "jest": "jest",
88 | "jest:coverage": "jest --collect-coverage",
89 | "jest:watch": "jest --watch",
90 | "lint": "eslint --fix --ext .js,.ts,.vue ./ && npm run prettier",
91 | "pack": "run-p pack:main pack:renderer pack:workers",
92 | "pack:main": "webpack --mode=production --config _scripts/webpack.main.config.js",
93 | "pack:renderer": "webpack --mode=production --config _scripts/webpack.renderer.config.js",
94 | "pack:web": "webpack --mode=production --config _scripts/webpack.web.config.js",
95 | "pack:workers": "webpack --mode=production --config _scripts/webpack.workers.config.js",
96 | "postinstall": "electron-rebuild",
97 | "prettier": "prettier --write \"{src,_scripts}/**/*.{js,ts,vue}\"",
98 | "rebuild:electron": "run-s electron-builder-install electron-rebuild",
99 | "rebuild:node": "npm rebuild",
100 | "release": "run-s test build",
101 | "test": "run-s rebuild:node pack:workers jest",
102 | "test:watch": "run-s rebuild:node pack:workers jest:watch"
103 | },
104 | "version": "0.0.1"
105 | }
106 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Vue-Electron-Template
4 |
5 | [](https://travis-ci.org/mubaidr/vue-electron-template)
6 | [](https://ci.appveyor.com/project/mubaidr/vue-electron-template)
7 | [](#contributors)
8 |
9 | Template for building desktop applications using [Electronjs](https://electronjs.org) and [Vue.js](https://vuejs.org)
10 |
11 | ## NOTICE
12 |
13 | [Vue3 Support](https://github.com/mubaidr/vue-electron-template/issues/907)
14 |
15 | ## Overview
16 |
17 | This template takes advantage of `webpack-5` with `vue-loader`, `electron-builder`, and some of the most used plugins like `vue-router`, `vuex` and so much more to provide an easy to use development (with vscode debugging) enviroment with hot module replacement.
18 |
19 | ### Features
20 |
21 | - [Bulma-Fluent](https://mubaidr.github.io/bulma-fluent/), a theme suitable for desktop application based on [Bulma](https://bulma.io/)
22 | - [vue-router](https://github.com/vuejs/vue-router)
23 | - [vuex](https://github.com/vuejs/vuex)
24 | - [vue-electron](https://github.com/SimulatedGREG/vue-electron)
25 | - [material-design-icons](http://google.github.io/material-design-icons/) installed
26 | - Some built-in animaitons [animations.scss](src\renderer\assets\style\animations.scss)
27 | - `SCSS`/`SASS` support with [vue-loader](https://github.com/vuejs/vue-loader/) (removes unused css/styles during build)
28 | - `Typescript` support (for `Vuejs` as well)
29 | - Worker scripts (to perform CPU-intensive operations), to use with nodejs `child_process` module. [Sample Worker File](src\utilities\workerSample.ts)
30 | - Easily package your electron app using [electron-builder](https://github.com/electron-userland/electron-builder)
31 | - `vue-devtools` installed
32 | - `DEV`, `DEBUG` & `BUILD` NPM scripts
33 | - `Babel` configured
34 | - `ESLint` configured
35 | - `vscode` debug config for renderer process debugging
36 | - Process restarting when working in main process & hot module replacement for renderer
37 | - Generates web/browser build in the `dist/web` directory too
38 | - `--debug` paramter to enable dev tools in production build executeable
39 |
40 | ### Screenshot
41 |
42 |
43 |
44 | ### Getting Started
45 |
46 | Clone this repository, install dependencies and run using either `dev`, `debug` or `build` command.
47 |
48 | ```bash
49 | # Clone this repository
50 | git clone https://github.com/mubaidr/vue-electron
51 |
52 | # change directory to cloned path
53 | cd vue-electron
54 |
55 | # Install dependencies
56 | npm install
57 |
58 | # Run in `debug` mode, to debug app using VSCODE
59 | npm run debug
60 |
61 | # Run in `dev` mode
62 | npm run dev
63 |
64 | # Build installer for this app
65 | npm run build
66 | ```
67 |
68 | ### Project structure
69 |
70 | `src/main` contains electron main script.
71 |
72 | `src/renderer` contains vue-js application.
73 |
74 | `src/utilities/workerSample.ts` a sample worker script.
75 |
76 | #### Credits
77 |
78 | All credits to authors of packages and tools used in the project.
79 |
80 | \* This template is inspired by [electron-vue](https://github.com/SimulatedGREG/electron-vue)
81 |
82 | ## Contributors
83 |
84 | Thanks goes to these wonderful people ([emoji key](https://github.com/all-contributors/all-contributors#emoji-key)):
85 |
86 |
87 |
88 |
89 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
102 |
--------------------------------------------------------------------------------
/_scripts/webpack.renderer.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 | const VueLoaderPlugin = require('vue-loader/lib/plugin')
5 | const CopyWebpackPlugin = require('copy-webpack-plugin')
6 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
7 |
8 | const {
9 | dependencies,
10 | devDependencies,
11 | productName,
12 | } = require('../package.json')
13 |
14 | const externals = Object.keys(dependencies).concat(Object.keys(devDependencies))
15 | const isDevMode = process.env.NODE_ENV === 'development'
16 | const whiteListedModules = ['vue']
17 |
18 | const config = {
19 | name: 'renderer',
20 | mode: process.env.NODE_ENV,
21 | devtool: isDevMode ? 'eval-source-map' : false,
22 | entry: {
23 | renderer: path.join(__dirname, '../src/renderer/main.js'),
24 | },
25 | output: {
26 | libraryTarget: 'commonjs2',
27 | path: path.join(__dirname, '../dist'),
28 | filename: '[name].js',
29 | },
30 | externals: externals.filter((d) => !whiteListedModules.includes(d)),
31 | module: {
32 | rules: [
33 | {
34 | test: /\.tsx?$/,
35 | use: [
36 | {
37 | loader: 'ts-loader',
38 | options: {
39 | appendTsSuffixTo: [/\.vue$/],
40 | },
41 | },
42 | ],
43 | exclude: /node_modules/,
44 | },
45 | {
46 | test: /\.js$/,
47 | use: 'babel-loader',
48 | exclude: /node_modules/,
49 | },
50 | {
51 | test: /\.node$/,
52 | use: 'node-loader',
53 | },
54 | {
55 | test: /\.vue$/,
56 | loader: 'vue-loader',
57 | },
58 | {
59 | test: /\.s(c|a)ss$/,
60 | use: [
61 | {
62 | loader: MiniCssExtractPlugin.loader,
63 | },
64 | {
65 | loader: 'css-loader',
66 | },
67 | {
68 | loader: 'sass-loader',
69 | options: {
70 | // eslint-disable-next-line
71 | implementation: require('sass'),
72 | },
73 | },
74 | ],
75 | },
76 | {
77 | test: /\.css$/,
78 | use: [
79 | {
80 | loader: MiniCssExtractPlugin.loader,
81 | },
82 | 'css-loader',
83 | ],
84 | },
85 | {
86 | test: /\.(png|jpe?g|gif|tif?f|bmp|webp|svg)(\?.*)?$/,
87 | use: {
88 | loader: 'url-loader',
89 | options: {
90 | esModule: false,
91 | limit: 10000,
92 | name: 'imgs/[name]--[folder].[ext]',
93 | },
94 | },
95 | },
96 | {
97 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
98 | use: {
99 | loader: 'url-loader',
100 | options: {
101 | esModule: false,
102 | limit: 10000,
103 | name: 'fonts/[name]--[folder].[ext]',
104 | },
105 | },
106 | },
107 | ],
108 | },
109 | node: {
110 | global: true,
111 | __dirname: isDevMode,
112 | __filename: isDevMode,
113 | },
114 | plugins: [
115 | // new WriteFilePlugin(),
116 | new HtmlWebpackPlugin({
117 | excludeChunks: ['processTaskWorker'],
118 | filename: 'index.html',
119 | template: path.resolve(__dirname, '../src/index.ejs'),
120 | nodeModules: isDevMode
121 | ? path.resolve(__dirname, '../node_modules')
122 | : false,
123 | }),
124 | new VueLoaderPlugin(),
125 | new webpack.DefinePlugin({
126 | 'process.env.PRODUCT_NAME': JSON.stringify(productName),
127 | }),
128 | new MiniCssExtractPlugin({
129 | filename: '[name].css',
130 | chunkFilename: '[id].css',
131 | }),
132 | ],
133 | resolve: {
134 | alias: {
135 | vue$: 'vue/dist/vue.common.js',
136 | '@': path.join(__dirname, '../src/'),
137 | src: path.join(__dirname, '../src/'),
138 | icons: path.join(__dirname, '../_icons/'),
139 | },
140 | extensions: ['.ts', '.js', '.vue', '.json'],
141 | },
142 | target: 'electron-renderer',
143 | }
144 |
145 | /**
146 | * Adjust rendererConfig for production settings
147 | */
148 | if (isDevMode) {
149 | // any dev only config
150 | config.plugins.push(
151 | new webpack.HotModuleReplacementPlugin(),
152 | new webpack.DefinePlugin({
153 | __static: `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`,
154 | })
155 | )
156 | } else {
157 | config.plugins.push(
158 | new CopyWebpackPlugin({
159 | patterns: [
160 | {
161 | from: path.join(__dirname, '../static'),
162 | to: path.join(__dirname, '../dist/static'),
163 | globOptions: {
164 | ignore: ['.*'],
165 | },
166 | },
167 | ],
168 | }),
169 | new webpack.LoaderOptionsPlugin({
170 | minimize: true,
171 | })
172 | )
173 | }
174 |
175 | module.exports = config
176 |
--------------------------------------------------------------------------------
/src/renderer/assets/style/animations.scss:
--------------------------------------------------------------------------------
1 | /* Animation keyframes */
2 | .animate-warn {
3 | animation-delay: 1s;
4 | animation-duration: 5s;
5 | animation-fill-mode: both;
6 | animation-iteration-count: infinite;
7 | animation-name: jump;
8 | transform-origin: 50%;
9 | will-change: transform;
10 | -webkit-animation-duration: 5s;
11 | -webkit-animation-fill-mode: both;
12 | -webkit-animation-name: jump;
13 | }
14 |
15 | .animate-danger {
16 | animation-delay: 1s;
17 | animation-duration: 5s;
18 | animation-fill-mode: both;
19 | animation-iteration-count: infinite;
20 | animation-name: shake;
21 | transform-origin: 50% 0;
22 | will-change: transform;
23 | -webkit-animation-duration: 5s;
24 | -webkit-animation-fill-mode: both;
25 | -webkit-animation-name: shake;
26 | }
27 |
28 | .animate-active {
29 | animation-delay: 1s;
30 | animation-duration: 5s;
31 | animation-fill-mode: both;
32 | animation-iteration-count: 1;
33 | animation-name: active;
34 | transform-origin: 50% 0;
35 | will-change: transform;
36 | -webkit-animation-duration: 5s;
37 | -webkit-animation-fill-mode: both;
38 | -webkit-animation-name: active;
39 | }
40 |
41 | @keyframes active {
42 | 0%,
43 | 100% {
44 | transform: rotate(0) scale(1);
45 | -webkit-transform: rotate(0) scale(1);
46 | }
47 | 50% {
48 | transform: rotate(0) scale(1.25);
49 | -webkit-transform: rotate(0) scale(1.25);
50 | }
51 | }
52 |
53 | @keyframes jump {
54 | 0%,
55 | 50%,
56 | 100% {
57 | transform: translateY(0);
58 | -webkit-transform: translateY(0);
59 | }
60 | 10%,
61 | 20%,
62 | 30%,
63 | 40% {
64 | transform: translateY(-3px);
65 | -webkit-transform: translateY(-3px);
66 | }
67 | 15%,
68 | 25%,
69 | 35%,
70 | 45% {
71 | transform: translateY(0);
72 | -webkit-transform: translateY(0);
73 | }
74 | }
75 |
76 | @keyframes shake {
77 | 0%,
78 | 100% {
79 | transform: translateX(0);
80 | -webkit-transform: translateX(0);
81 | }
82 | /* Fast Shake */
83 | 1%,
84 | 3%,
85 | 5%,
86 | 7%,
87 | 9% {
88 | transform: translateX(-2px);
89 | -webkit-transform: translateX(-2px);
90 | }
91 | 2%,
92 | 4%,
93 | 6%,
94 | 8%,
95 | 10% {
96 | transform: translateX(2px);
97 | -webkit-transform: translateX(2px);
98 | }
99 | /* Medium Shake */
100 | 12%,
101 | 16%,
102 | 20%,
103 | 24% {
104 | transform: translateX(-1px);
105 | -webkit-transform: translateX(-1px);
106 | }
107 | 14%,
108 | 18%,
109 | 22%,
110 | 26% {
111 | transform: translateX(1px);
112 | -webkit-transform: translateX(1px);
113 | }
114 | /* Slow Shake */
115 | 30%,
116 | 38%,
117 | 46% {
118 | transform: translateX(-0.5px);
119 | -webkit-transform: translateX(-0.5px);
120 | }
121 | 34%,
122 | 42%,
123 | 50% {
124 | transform: translateX(0.5px);
125 | -webkit-transform: translateX(0.5px);
126 | }
127 | }
128 |
129 | /* Items List Transitions */
130 | .list-in-enter-active,
131 | .list-in-leave-active {
132 | transition: all 0.25s ease;
133 | }
134 |
135 | .list-in-enter,
136 | .list-in-leave-to {
137 | opacity: 0;
138 | transform: scale(0.25);
139 | }
140 |
141 | /* List out */
142 | .list-out-enter-active,
143 | .list-out-leave-active {
144 | transition: all 0.25s ease;
145 | }
146 |
147 | .list-out-enter,
148 | .list-out-leave-to {
149 | opacity: 0;
150 | transform: scale(1.5);
151 | }
152 |
153 | /* List out delayed */
154 | .list-out-delayed-enter-active,
155 | .list-out-delayed-leave-active {
156 | transition: all 0.25s ease 0.1s;
157 | }
158 |
159 | .list-out-delayed-enter,
160 | .list-out-delayed-leave-to {
161 | opacity: 0;
162 | transform: scale(1.5);
163 | }
164 |
165 | /* Route change animations */
166 | .slide-up-enter-active,
167 | .slide-up-leave-active {
168 | transition: all 0.25s ease-out;
169 | }
170 |
171 | .slide-up-enter,
172 | .slide-up-leave-to {
173 | opacity: 0;
174 | transform: translateY(-10px);
175 | }
176 |
177 | /* Route change animations */
178 | .slide-down-enter-active,
179 | .slide-down-leave-active {
180 | transition: all 0.25s ease-out;
181 | }
182 |
183 | .slide-down-enter,
184 | .slide-down-leave-to {
185 | opacity: 0;
186 | transform: translateY(10px);
187 | }
188 |
189 | /* Test right */
190 | .slide-right-enter-active,
191 | .slide-right-leave-active {
192 | transition: all 0.25s ease-out;
193 | }
194 |
195 | .slide-right-enter,
196 | .slide-right-leave-to {
197 | opacity: 0;
198 | transform: translateX(-10px);
199 | }
200 |
201 | /* Test left */
202 | .slide-left-enter-active,
203 | .slide-left-leave-active {
204 | transition: all 0.25s ease-out;
205 | }
206 |
207 | .slide-left-enter,
208 | .slide-left-leave-to {
209 | opacity: 0;
210 | transform: translateX(10px);
211 | }
212 |
213 | /* List animation */
214 | .list-complete-item {
215 | transition: all 0.25s;
216 | }
217 |
218 | .list-complete-enter,
219 | .list-complete-leave-to {
220 | opacity: 0;
221 | transform: translateY(30px);
222 | }
223 |
224 | .list-complete-leave-active {
225 | position: absolute;
226 | }
227 |
228 | /* Rotation */
229 | @keyframes rotation {
230 | 0% {
231 | transform: rotate(0deg);
232 | }
233 | 100% {
234 | transform: rotate(360deg);
235 | }
236 | }
237 |
238 | .rotating {
239 | animation: rotation 0.5s infinite linear;
240 | }
241 |
--------------------------------------------------------------------------------
/_scripts/webpack.web.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 | const VueLoaderPlugin = require('vue-loader/lib/plugin')
5 | const CopyWebpackPlugin = require('copy-webpack-plugin')
6 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
7 |
8 | const { productName } = require('../package.json')
9 |
10 | const isDevMode = process.env.NODE_ENV === 'development'
11 |
12 | const config = {
13 | name: 'web',
14 | mode: process.env.NODE_ENV,
15 | devtool: isDevMode ? 'eval-source-map' : false,
16 | entry: {
17 | web: path.join(__dirname, '../src/renderer/main.js'),
18 | },
19 | output: {
20 | path: path.join(__dirname, '../dist/web'),
21 | filename: '[name].js',
22 | },
23 | module: {
24 | rules: [
25 | {
26 | test: /\.tsx?$/,
27 | use: [
28 | {
29 | loader: 'ts-loader',
30 | options: {
31 | appendTsSuffixTo: [/\.vue$/],
32 | },
33 | },
34 | ],
35 | exclude: /node_modules/,
36 | },
37 | {
38 | test: /\.js$/,
39 | use: 'babel-loader',
40 | exclude: /node_modules/,
41 | },
42 | {
43 | test: /\.vue$/,
44 | use: {
45 | loader: 'vue-loader',
46 | options: {
47 | extractCSS: true,
48 | loaders: {
49 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
50 | scss: 'vue-style-loader!css-loader!sass-loader',
51 | less: 'vue-style-loader!css-loader!less-loader',
52 | },
53 | },
54 | },
55 | },
56 | {
57 | test: /\.s(c|a)ss$/,
58 | use: [
59 | {
60 | loader: MiniCssExtractPlugin.loader,
61 | },
62 | {
63 | loader: 'css-loader',
64 | },
65 | {
66 | loader: 'sass-loader',
67 | options: {
68 | // eslint-disable-next-line
69 | implementation: require('sass'),
70 | },
71 | },
72 | ],
73 | },
74 | {
75 | test: /\.css$/,
76 | use: [
77 | {
78 | loader: MiniCssExtractPlugin.loader,
79 | },
80 | 'css-loader',
81 | ],
82 | },
83 | {
84 | test: /\.html$/,
85 | use: 'vue-html-loader',
86 | },
87 | {
88 | test: /\.(png|jpe?g|gif|tif?f|bmp|webp|svg)(\?.*)?$/,
89 | use: {
90 | loader: 'url-loader',
91 | options: {
92 | esModule: false,
93 | limit: 10000,
94 | name: 'imgs/[name]--[folder].[ext]',
95 | },
96 | },
97 | },
98 | {
99 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
100 | use: {
101 | loader: 'url-loader',
102 | options: {
103 | esModule: false,
104 | limit: 10000,
105 | name: 'fonts/[name]--[folder].[ext]',
106 | },
107 | },
108 | },
109 | ],
110 | },
111 | node: {
112 | __dirname: isDevMode,
113 | __filename: isDevMode,
114 | },
115 | resolve: {
116 | alias: {
117 | '@': path.join(__dirname, '../src/renderer'),
118 | vue$: 'vue/dist/vue.esm.js',
119 | src: path.join(__dirname, '../src/'),
120 | icons: path.join(__dirname, '../_icons/'),
121 | },
122 | extensions: ['.ts', '.js', '.vue', '.json', '.css'],
123 | fallback: {
124 | // fs: false,
125 | // os: require.resolve('os-browserify/browser'),
126 | // path: require.resolve('path-browserify'),
127 | fs: false,
128 | os: false,
129 | path: false,
130 | },
131 | },
132 | plugins: [
133 | // new WriteFilePlugin(),
134 | new HtmlWebpackPlugin({
135 | excludeChunks: ['processTaskWorker'],
136 | filename: 'index.html',
137 | template: path.resolve(__dirname, '../src/index.ejs'),
138 | nodeModules: false,
139 | }),
140 | new VueLoaderPlugin(),
141 | new webpack.DefinePlugin({
142 | 'process.env.PRODUCT_NAME': JSON.stringify(productName),
143 | }),
144 | new MiniCssExtractPlugin({
145 | filename: '[name].css',
146 | chunkFilename: '[id].css',
147 | }),
148 | ],
149 | target: 'web',
150 | }
151 |
152 | /**
153 | * Adjust web for production settings
154 | */
155 | if (isDevMode) {
156 | // any dev only config
157 | config.plugins.push(
158 | new webpack.HotModuleReplacementPlugin(),
159 | new webpack.DefinePlugin({
160 | __static: `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`,
161 | })
162 | )
163 | } else {
164 | config.plugins.push(
165 | new CopyWebpackPlugin({
166 | patterns: [
167 | {
168 | from: path.join(__dirname, '../static'),
169 | to: path.join(__dirname, '../dist/static'),
170 | globOptions: {
171 | ignore: ['.*'],
172 | },
173 | },
174 | ],
175 | }),
176 | new webpack.LoaderOptionsPlugin({
177 | minimize: true,
178 | })
179 | )
180 | }
181 |
182 | module.exports = config
183 |
--------------------------------------------------------------------------------
/src/main/index.js:
--------------------------------------------------------------------------------
1 | import { app, BrowserWindow, Menu } from 'electron'
2 | import pkg from '../../package.json'
3 |
4 | require('@electron/remote/main').initialize()
5 |
6 | // set app name
7 | app.name = pkg.productName
8 | // to hide deprecation message
9 | app.allowRendererProcessReuse = true
10 |
11 | // disable electron warning
12 | process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = false
13 |
14 | const gotTheLock = app.requestSingleInstanceLock()
15 | const isDev = process.env.NODE_ENV === 'development'
16 | const isDebug = process.argv.includes('--debug')
17 | let mainWindow
18 |
19 | // only allow single instance of application
20 | if (!isDev) {
21 | if (gotTheLock) {
22 | app.on('second-instance', () => {
23 | // Someone tried to run a second instance, we should focus our window.
24 | if (mainWindow && mainWindow.isMinimized()) {
25 | mainWindow.restore()
26 | }
27 | mainWindow.focus()
28 | })
29 | } else {
30 | app.quit()
31 | process.exit(0)
32 | }
33 | } else {
34 | // process.env.ELECTRON_ENABLE_LOGGING = true
35 |
36 | require('electron-debug')({
37 | showDevTools: false,
38 | })
39 | }
40 |
41 | async function installDevTools() {
42 | let installExtension = require('electron-devtools-installer')
43 | installExtension.default(installExtension.VUEJS_DEVTOOLS).catch((err) => {
44 | console.log('Unable to install `vue-devtools`: \n', err)
45 | })
46 | }
47 |
48 | function createWindow() {
49 | /**
50 | * Initial window options
51 | */
52 | mainWindow = new BrowserWindow({
53 | backgroundColor: '#fff',
54 | width: 960,
55 | height: 540,
56 | minWidth: 960,
57 | minHeight: 540,
58 | // useContentSize: true,
59 | webPreferences: {
60 | nodeIntegration: true,
61 | nodeIntegrationInWorker: false,
62 | contextIsolation: false,
63 | webSecurity: false,
64 | },
65 | show: false,
66 | })
67 |
68 | // eslint-disable-next-line
69 | setMenu()
70 |
71 | // load root file/url
72 | if (isDev) {
73 | mainWindow.loadURL('http://localhost:9080')
74 | } else {
75 | mainWindow.loadFile(`${__dirname}/index.html`)
76 |
77 | global.__static = require('path')
78 | .join(__dirname, '/static')
79 | .replace(/\\/g, '\\\\')
80 | }
81 |
82 | // Show when loaded
83 | mainWindow.on('ready-to-show', () => {
84 | mainWindow.show()
85 | mainWindow.focus()
86 | })
87 |
88 | mainWindow.on('closed', () => {
89 | console.log('\nApplication exiting...')
90 | })
91 | }
92 |
93 | app.on('ready', () => {
94 | createWindow()
95 |
96 | if (isDev) {
97 | installDevTools()
98 | mainWindow.webContents.openDevTools()
99 | }
100 |
101 | if (isDebug) {
102 | mainWindow.webContents.openDevTools()
103 | }
104 | })
105 |
106 | app.on('window-all-closed', () => {
107 | if (process.platform !== 'darwin') {
108 | app.quit()
109 | }
110 | })
111 |
112 | app.on('activate', () => {
113 | if (mainWindow === null) {
114 | createWindow()
115 | }
116 | })
117 |
118 | /**
119 | * Auto Updater
120 | *
121 | * Uncomment the following code below and install `electron-updater` to
122 | * support auto updating. Code Signing with a valid certificate is required.
123 | * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
124 | */
125 |
126 | /*
127 | import { autoUpdater } from 'electron-updater'
128 |
129 | autoUpdater.on('update-downloaded', () => {
130 | autoUpdater.quitAndInstall()
131 | })
132 |
133 | app.on('ready', () => {
134 | if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
135 | })
136 | */
137 |
138 | const sendMenuEvent = async (data) => {
139 | mainWindow.webContents.send('change-view', data)
140 | }
141 |
142 | const template = [
143 | {
144 | label: app.name,
145 | submenu: [
146 | {
147 | label: 'Home',
148 | accelerator: 'CommandOrControl+H',
149 | click() {
150 | sendMenuEvent({ route: '/' })
151 | },
152 | },
153 | { type: 'separator' },
154 | { role: 'minimize' },
155 | { role: 'togglefullscreen' },
156 | { type: 'separator' },
157 | { role: 'quit', accelerator: 'Alt+F4' },
158 | ],
159 | },
160 | {
161 | role: 'help',
162 | submenu: [
163 | {
164 | label: 'Get Help',
165 | role: 'help',
166 | accelerator: 'F1',
167 | click() {
168 | sendMenuEvent({ route: '/help' })
169 | },
170 | },
171 | {
172 | label: 'About',
173 | role: 'about',
174 | accelerator: 'CommandOrControl+A',
175 | click() {
176 | sendMenuEvent({ route: '/about' })
177 | },
178 | },
179 | ],
180 | },
181 | ]
182 |
183 | function setMenu() {
184 | if (process.platform === 'darwin') {
185 | template.unshift({
186 | label: app.name,
187 | submenu: [
188 | { role: 'about' },
189 | { type: 'separator' },
190 | { role: 'services' },
191 | { type: 'separator' },
192 | { role: 'hide' },
193 | { role: 'hideothers' },
194 | { role: 'unhide' },
195 | { type: 'separator' },
196 | { role: 'quit' },
197 | ],
198 | })
199 |
200 | template.push({
201 | role: 'window',
202 | })
203 |
204 | template.push({
205 | role: 'help',
206 | })
207 |
208 | template.push({ role: 'services' })
209 | }
210 |
211 | const menu = Menu.buildFromTemplate(template)
212 | Menu.setApplicationMenu(menu)
213 | }
214 |
--------------------------------------------------------------------------------
/_icons/logotype1black.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/logotype2black.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/logotype1blue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/logotype1white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/logotype2blue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_icons/logotype2white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------