├── .gitignore ├── .prettierignore ├── .prettierrc ├── .travis.yml ├── .vscode ├── launch.json └── settings.json ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── README.zh-CN.md ├── build ├── webpack.base.config.js ├── webpack.main.config.js └── webpack.main.prod.config.js ├── index.html ├── package.json ├── src ├── main │ ├── global.d.ts │ ├── main.ts │ └── utils │ │ └── menu.ts └── renderer │ ├── assets │ └── yay.jpg │ ├── config │ └── config.js │ ├── global.ts │ ├── models │ └── global.ts │ ├── pages │ └── index.tsx │ ├── tsconfig.json │ └── utils │ └── electron.ts ├── test ├── main.test.js └── renderer.test.js ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | src/renderer/pages/.umi 4 | release -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | release/ 3 | .DS_Store 4 | .idea/ 5 | yarn-error.log 6 | npm-debug.log 7 | src/renderer/pages/.umi/ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true 6 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "8" 5 | - "10" 6 | 7 | script: 8 | - npm run test 9 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "program": "${workspaceFolder}/dist/main/main.js", 12 | "preLaunchTask": "tsc: build - tsconfig.json", 13 | "outFiles": [ 14 | "${workspaceFolder}/dist/**/*.js" 15 | ] 16 | }, 17 | { 18 | "type": "node", 19 | "request": "launch", 20 | "name": "Launch and Debug", 21 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-webpack", 22 | "runtimeArgs": [ 23 | "dev" 24 | ], 25 | "autoAttachChildProcesses": true, 26 | "internalConsoleOptions": "openOnFirstSessionStart", 27 | "console": "integratedTerminal" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangtianlun/umi-electron-typescript/a3118529e5f65cd7a9d74558d6769d3b86bb96f0/CHANGELOG.md -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019-present WangTianLun (chongxinkaishi8188@gmail.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all 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 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # umi-electron-typescript 2 | 3 | ### An example based on umijs + electron + typescript 4 | 5 | [![Umi](https://img.souche.com/f2e/a92fc3dfdb4918578861c42bbfcfaf7f.png)](https://umijs.org/) 6 | [![Webpack](https://img.souche.com/f2e/cdc96229f3f9b7068a9b13f7658a9b0e.png)](https://webpack.js.org/) 7 | [![TypeScript](https://img.souche.com/f2e/abaffc28828246dcca08eae82a0b34c3.png)](https://www.typescriptlang.org/) 8 | [![Electron](https://img.souche.com/f2e/4f18b23a82d106ce023cdaf17c6dfd51.png)](https://electronjs.org/) 9 | 10 | [访问中文版](https://github.com/wangtianlun/umi-electron-typescript/blob/master/README.zh-CN.md) 11 | 12 | ## Features 13 | - Support hot reload for main process and renderer process 14 | - Support typescript 15 | 16 | ## Install 17 | 18 | First, clone the repo via git: 19 | 20 | ```javascript 21 | git clone git@github.com:wangtianlun/umi-electron-typescript.git 22 | ``` 23 | 24 | And then install the dependencies with yarn 25 | 26 | ```javascript 27 | $ yarn 28 | ``` 29 | 30 | ## Starting Development 31 | 32 | ```javascript 33 | $ yarn start 34 | ``` 35 | 36 | ## Packaging 37 | 38 | ```javascript 39 | $ npm run pack 40 | ``` 41 | 42 | If you want to package into dmg(on mac) or zip, you can follow below 43 | 44 | ```javascript 45 | $ npm run dist 46 | ``` 47 | 48 | If you want to package all platforms(eg: mac, windows, linux), you can follow below 49 | 50 | ```javascript 51 | $ npm run dist-all 52 | ``` 53 | 54 | ## screenshot 55 | 56 | ![umi-electron-typescript-image](https://img.souche.com/f2e/f26a29f3232f33dfa1ade9b48df64b6b.png) 57 | 58 | -------------------------------------------------------------------------------- /README.zh-CN.md: -------------------------------------------------------------------------------- 1 | # umi-electron-typescript 2 | 3 | ### 一个基于umijs + electron + typescript的模板 4 | 5 | [![Umi](https://img.souche.com/f2e/a92fc3dfdb4918578861c42bbfcfaf7f.png)](https://umijs.org/) 6 | [![Webpack](https://img.souche.com/f2e/cdc96229f3f9b7068a9b13f7658a9b0e.png)](https://webpack.js.org/) 7 | [![TypeScript](https://img.souche.com/f2e/abaffc28828246dcca08eae82a0b34c3.png)](https://www.typescriptlang.org/) 8 | [![Electron](https://img.souche.com/f2e/4f18b23a82d106ce023cdaf17c6dfd51.png)](https://electronjs.org/) 9 | 10 | ## 主要特性 11 | - 支持整个应用的热重载 12 | - 支持typescript语法 13 | 14 | ## 安装 15 | 16 | 首先通过git下载这个仓库到本地 17 | 18 | ```javascript 19 | git clone git@github.com:wangtianlun/umi-electron-typescript.git 20 | ``` 21 | 22 | 然后通过yarn下载依赖 23 | 24 | ```javascript 25 | $ yarn 26 | ``` 27 | 28 | ## 开发 29 | 30 | ```javascript 31 | $ yarn start 32 | ``` 33 | 34 | ## 打包 35 | 36 | ```javascript 37 | $ npm run pack 38 | ``` 39 | 40 | 如果想把代码打包成一个dmg文件或者zip文件,可以执行以下命令 41 | 42 | ```javascript 43 | $ npm run dist 44 | ``` 45 | 46 | ## 应用截图 47 | 48 | ![umi-electron-typescript-image](https://img.souche.com/f2e/f26a29f3232f33dfa1ade9b48df64b6b.png) 49 | 50 | -------------------------------------------------------------------------------- /build/webpack.base.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = { 6 | output: { 7 | path: path.resolve(__dirname, '../dist/main'), 8 | filename: '[name].js', 9 | }, 10 | node: { 11 | __dirname: false, 12 | __filename: false, 13 | }, 14 | resolve: { 15 | extensions: ['.tsx', '.ts', '.js', '.json'], 16 | }, 17 | devtool: 'source-map', 18 | }; 19 | -------------------------------------------------------------------------------- /build/webpack.main.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const merge = require('webpack-merge'); 4 | const baseConfig = require('./webpack.base.config'); 5 | 6 | module.exports = merge.smart(baseConfig, { 7 | target: 'electron-main', 8 | entry: { 9 | main: './src/main/main.ts', 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.tsx?$/, 15 | loader: 'awesome-typescript-loader', 16 | exclude: /node_modules/, 17 | }, 18 | ], 19 | }, 20 | plugins: [ 21 | new webpack.DefinePlugin({ 22 | 'process.env.NODE_ENV': JSON.stringify( 23 | process.env.NODE_ENV || 'development' 24 | ), 25 | }), 26 | ], 27 | mode: 'development', 28 | }); 29 | -------------------------------------------------------------------------------- /build/webpack.main.prod.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const merge = require('webpack-merge'); 4 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 5 | 6 | const baseConfig = require('./webpack.main.config'); 7 | 8 | module.exports = merge.smart(baseConfig, { 9 | // plugins: [ 10 | // new UglifyJsPlugin() 11 | // ], 12 | mode: 'production', 13 | }); 14 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello World! 6 | 7 | 8 |

Hello World!

9 | 10 | We are using Node.js , 11 | Chromium , 12 | and Electron 13 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "umi-electron-typescript", 3 | "version": "1.0.0", 4 | "description": "an example based on umijs + electron + typescript", 5 | "main": "./dist/main/main.js", 6 | "private": true, 7 | "build": { 8 | "files": [ 9 | "dist/", 10 | "node_modules/", 11 | "package.json" 12 | ], 13 | "mac": { 14 | "category": "your.app.category.type" 15 | }, 16 | "directories": { 17 | "output": "release" 18 | }, 19 | "appId": "com.wangtianlun.umi-electron-typescript", 20 | "asar": false 21 | }, 22 | "scripts": { 23 | "start": "concurrently \"yarn start:main\" \"yarn start:renderer\"", 24 | "start:main": "electron-webpack dev", 25 | "start:renderer": "BROWSER=none APP_ROOT=src/renderer umi dev", 26 | "build-main-prod": "NODE_ENV=production webpack --config ./build/webpack.main.prod.config.js", 27 | "build-main-dev": "NODE_ENV=development webpack --config ./build/webpack.main.config.js", 28 | "build:renderer": "APP_ROOT=src/renderer umi build", 29 | "watch": "tsc -w", 30 | "test": "jest", 31 | "lint": "tslint -c tslint.json -p tsconfig.json", 32 | "debug:main": "electron --inspect=5858 -w ./dist/main/main.js", 33 | "pack": "npm run build:renderer && npm run build-main-prod && electron-builder --dir", 34 | "dist": "electron-builder", 35 | "dist-mac": "electron-builder -m", 36 | "dist-win": "electron-builder -w", 37 | "dist-linux": "electron-builder -l", 38 | "dist-all": "electron-builder -mwl", 39 | "prettier": "prettier --list-different \"./**/*.{ts,tsx,js,jsx,less}\"", 40 | "postinstall": "electron-builder install-app-deps" 41 | }, 42 | "repository": "https://github.com/wangtianlun/umi-electron-typescript", 43 | "keywords": [ 44 | "Electron", 45 | "umi", 46 | "quick", 47 | "start", 48 | "tutorial", 49 | "demo", 50 | "typescript" 51 | ], 52 | "author": { 53 | "name": "wangtianlun", 54 | "email": "chongxinkaishi8188@gmail.com" 55 | }, 56 | "devDependencies": { 57 | "awesome-typescript-loader": "^5.2.1", 58 | "concurrently": "^5.1.0", 59 | "electron": "^4.0.5", 60 | "electron-builder": "^20.38.5", 61 | "electron-debug": "^2.0.0", 62 | "electron-webpack": "^2.6.2", 63 | "electron-webpack-ts": "^3.1.1", 64 | "jest": "^24.9.0", 65 | "prettier": "1.16.4", 66 | "ts-loader": "^5.3.3", 67 | "tslint": "^5.10.0", 68 | "typescript": "^3.2.4", 69 | "uglifyjs-webpack-plugin": "^2.1.1", 70 | "umi": "^2.8.17", 71 | "umi-plugin-react": "^1.9.15", 72 | "webpack": "4.28.0", 73 | "webpack-cli": "^3.2.1", 74 | "webpack-merge": "^4.2.1" 75 | }, 76 | "electronWebpack": { 77 | "main": { 78 | "sourceDirectory": "src/main" 79 | }, 80 | "renderer": { 81 | "sourceDirectory": null 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module NodeJS { 2 | interface Global { 3 | title: string; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/main/main.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as url from 'url'; 3 | import { app, BrowserWindow } from 'electron'; 4 | import setApplicationMenu from './utils/menu'; 5 | 6 | let mainWindow: Electron.BrowserWindow | null; 7 | 8 | function createWindow() { 9 | mainWindow = new BrowserWindow({ 10 | height: 600, 11 | width: 800, 12 | }); 13 | 14 | setApplicationMenu(); 15 | 16 | global.title = 'Yay! Welcome to umi-electron-typescript!'; 17 | 18 | if (process.env.NODE_ENV === 'development') { 19 | mainWindow.loadURL('http://localhost:8000/#/'); 20 | mainWindow.webContents.openDevTools(); 21 | } else { 22 | mainWindow.loadURL( 23 | url.format({ 24 | pathname: path.join(__dirname, './dist/renderer/index.html'), 25 | protocol: 'file:', 26 | slashes: true, 27 | }), 28 | ); 29 | } 30 | 31 | mainWindow.on('closed', () => { 32 | mainWindow = null; 33 | }); 34 | } 35 | 36 | app.on('ready', createWindow); 37 | 38 | app.on('window-all-closed', () => { 39 | if (process.platform !== 'darwin') { 40 | app.quit(); 41 | } 42 | }); 43 | 44 | app.on('activate', () => { 45 | if (mainWindow === null) { 46 | createWindow(); 47 | } 48 | }); 49 | -------------------------------------------------------------------------------- /src/main/utils/menu.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Top menu bar 3 | */ 4 | import { Menu, MenuItemConstructorOptions, app } from 'electron'; 5 | 6 | const template: MenuItemConstructorOptions[] = [ 7 | { 8 | label: 'Edit', 9 | submenu: [ 10 | { role: 'undo' }, 11 | { role: 'redo' }, 12 | { type: 'separator' }, 13 | { role: 'cut' }, 14 | { role: 'copy' }, 15 | { role: 'paste' }, 16 | { role: 'pasteandmatchstyle' }, 17 | { role: 'delete' }, 18 | { role: 'selectall' }, 19 | ], 20 | }, 21 | { 22 | label: 'View', 23 | submenu: [ 24 | { role: 'reload' }, 25 | { role: 'forcereload' }, 26 | { role: 'toggledevtools' }, 27 | { type: 'separator' }, 28 | { role: 'resetzoom' }, 29 | { role: 'zoomin' }, 30 | { role: 'zoomout' }, 31 | { type: 'separator' }, 32 | { role: 'togglefullscreen' }, 33 | ], 34 | }, 35 | { 36 | label: 'Window', 37 | role: 'window', 38 | submenu: [{ role: 'minimize' }, { role: 'close' }], 39 | }, 40 | { 41 | label: 'Help', 42 | submenu: [ 43 | { 44 | label: 'doc', 45 | submenu: [ 46 | { 47 | label: 'doc', 48 | }, 49 | ], 50 | }, 51 | ], 52 | }, 53 | ]; 54 | 55 | if (process.platform === 'darwin') { 56 | template.unshift({ 57 | label: app.getName(), 58 | submenu: [ 59 | { 60 | role: 'about', 61 | label: 'about', 62 | }, 63 | { 64 | type: 'separator', 65 | }, 66 | { 67 | label: 'preferences', 68 | }, 69 | { 70 | type: 'separator', 71 | }, 72 | { 73 | role: 'quit', 74 | label: 'quit', 75 | }, 76 | ], 77 | }); 78 | } 79 | 80 | export default function() { 81 | const menu = Menu.buildFromTemplate(template); 82 | Menu.setApplicationMenu(menu); 83 | } 84 | 85 | -------------------------------------------------------------------------------- /src/renderer/assets/yay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangtianlun/umi-electron-typescript/a3118529e5f65cd7a9d74558d6769d3b86bb96f0/src/renderer/assets/yay.jpg -------------------------------------------------------------------------------- /src/renderer/config/config.js: -------------------------------------------------------------------------------- 1 | const cwd = process.cwd(); 2 | 3 | export default { 4 | history: 'hash', 5 | outputPath: `../../dist/renderer`, 6 | publicPath: './', 7 | plugins: [ 8 | [ 9 | 'umi-plugin-react', 10 | { 11 | antd: true, 12 | dva: true, 13 | dynamicImport: true, 14 | title: 'umi-electron-typescript', 15 | dll: true, 16 | routes: { 17 | exclude: [], 18 | }, 19 | hardSource: false, 20 | routes: { 21 | exclude: [/components/], 22 | }, 23 | }, 24 | ], 25 | ], 26 | routes: [ 27 | { 28 | path: '/', 29 | component: './index', 30 | }, 31 | ], 32 | }; 33 | -------------------------------------------------------------------------------- /src/renderer/global.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangtianlun/umi-electron-typescript/a3118529e5f65cd7a9d74558d6769d3b86bb96f0/src/renderer/global.ts -------------------------------------------------------------------------------- /src/renderer/models/global.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | state: { 3 | name: 'global', 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /src/renderer/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { getGlobal } from '../utils/electron'; 2 | 3 | function Index() { 4 | return ( 5 |
6 |

{ getGlobal('title') }

7 |
8 |
9 | 10 |
11 | ); 12 | } 13 | 14 | export default Index; 15 | -------------------------------------------------------------------------------- /src/renderer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "importHelpers": true, 7 | "jsx": "preserve", 8 | "esModuleInterop": true, 9 | "sourceMap": true, 10 | "baseUrl": ".", 11 | "paths": { 12 | "@/*": ["./*"] 13 | }, 14 | "allowSyntheticDefaultImports": true 15 | } 16 | } -------------------------------------------------------------------------------- /src/renderer/utils/electron.ts: -------------------------------------------------------------------------------- 1 | const electron = (window as any).require('electron'); 2 | const { ipcRenderer, remote } = electron; 3 | const { getGlobal, shell } = remote; 4 | 5 | export { 6 | shell, 7 | remote, 8 | electron, 9 | getGlobal, 10 | ipcRenderer, 11 | }; 12 | -------------------------------------------------------------------------------- /test/main.test.js: -------------------------------------------------------------------------------- 1 | test('test main', () => { 2 | expect(1).toBe(1); 3 | }); -------------------------------------------------------------------------------- /test/renderer.test.js: -------------------------------------------------------------------------------- 1 | test('test renderer', () => { 2 | expect(1).toBe(1); 3 | }); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES5", 4 | "moduleResolution": "node", 5 | "module": "commonjs", 6 | "lib": [ 7 | "dom", 8 | "es2015", 9 | "es2016", 10 | "es2017" 11 | ], 12 | "noImplicitAny": false, 13 | "sourceMap": true, 14 | "outDir": "dist", 15 | "baseUrl": "./", 16 | "jsx": "preserve", 17 | "allowJs": true, 18 | "emitDecoratorMetadata": true, 19 | "experimentalDecorators": true, 20 | "strictPropertyInitialization": false, 21 | "noEmit": false, 22 | "paths": { 23 | "*": ["node_modules/*"] 24 | }, 25 | }, 26 | "include": [ 27 | "src/**/*" 28 | ], 29 | "extends": "./node_modules/electron-webpack/tsconfig-base.json" 30 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "max-line-length": { 5 | "options": [ 6 | 120 7 | ] 8 | }, 9 | "new-parens": true, 10 | "no-arg": true, 11 | "no-bitwise": true, 12 | "no-conditional-assignment": true, 13 | "no-consecutive-blank-lines": false, 14 | "ordered-imports": false, 15 | "quotemark": [true, "single"] 16 | }, 17 | "jsRules": { 18 | "max-line-length": { 19 | "options": [ 20 | 120 21 | ] 22 | } 23 | } 24 | } --------------------------------------------------------------------------------