├── .gitignore ├── README.md ├── generators └── app │ ├── index.js │ └── templates │ └── electron-react │ ├── README.md │ ├── electron-builder.yml │ ├── gitignore │ ├── package.json │ ├── public │ ├── electron.js │ ├── favicon.ico │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── App.test.js │ ├── index.js │ └── utilities │ └── registerServiceWorker.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | .env.local 16 | .env.development.local 17 | .env.test.local 18 | .env.production.local 19 | 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | 24 | # yarn 25 | package-lock.json 26 | yarn.lock 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > lightweight yeoman generator to get you started with the beautiful react-electron combo. 2 | 3 | ## Getting started 4 | The usage is very simple: 5 | - installign yeoman, if you haven't done that yet 6 | ```bash 7 | npm install -g yo 8 | ``` 9 | - installing the generator 10 | ```bash 11 | npm install generator-react-electron -g 12 | ``` 13 | - call this from inside the folder you want to bootstrap your application 14 | ```bash 15 | yo react-electron 16 | ``` 17 | 18 | And you are now good to go! 19 | 20 | ### Development and deployment 21 | - to start the development environment with hot reloading 22 | ```bash 23 | npm run electron-dev 24 | ``` 25 | - to create an optimized version of you app (output in the dist folder) 26 | ```bash 27 | npm run electron-pack 28 | ``` 29 | ### Autoupdates 30 | If you chose to have autoupdates, change the package version, run the following line, then go to the repository's releases and publish the new release. 31 | ```bash 32 | npm run ship 33 | ``` 34 | 35 | ### Linting 36 | If you opted-in prettier, your files will automatically be linted on commit, or when you run 37 | ```bash 38 | npm run pretty 39 | ``` 40 | 41 | ### Sass 42 | If you chose to use sass, it will be converted into css automatically when building and is also hot-reloaded during development 43 | -------------------------------------------------------------------------------- /generators/app/index.js: -------------------------------------------------------------------------------- 1 | var Generator = require("yeoman-generator") 2 | 3 | module.exports = class extends Generator { 4 | // The name `constructor` is important here 5 | constructor(args, opts) { 6 | // Calling the super constructor is important so our generator is correctly set up 7 | super(args, opts) 8 | this.answers={} 9 | // Next, add your custom code 10 | } 11 | prompting() { 12 | function createApp(answers) { 13 | answers.name = answers.name 14 | .split(" ") 15 | .join("") 16 | .toLowerCase() // remove whitespace and lowercase 17 | if (answers.sass){ 18 | answers.electrondev = /^win/.test(process.platform) 19 | ? `concurrently \\"yarn watch-css\\" \\"SET BROWSER=none&&yarn start\\" \\"wait-on http://localhost:3000 && electron .\\"` 20 | : `concurrently \\"yarn watch-css\\" \\"export BROWSER=none && yarn start\\" \\"wait-on http://localhost:3000 && electron .\\"` 21 | } 22 | else{ 23 | answers.electrondev = /^win/.test(process.platform) 24 | ? `concurrently \\"SET BROWSER=none&&yarn start\\" \\"wait-on http://localhost:3000 && electron .\\"` 25 | : `concurrently \\"export BROWSER=none && yarn start\\" \\"wait-on http://localhost:3000 && electron .\\"` 26 | } 27 | 28 | this.fs.copyTpl( 29 | this.templatePath("electron-react/README.md"), 30 | this.destinationPath("README.md"), 31 | answers 32 | ) 33 | this.fs.copyTpl( 34 | this.templatePath("electron-react/package.json"), 35 | this.destinationPath("package.json"), 36 | answers 37 | ) 38 | this.fs.copyTpl( 39 | this.templatePath("electron-react/gitignore"), 40 | this.destinationPath(".gitignore"), 41 | answers 42 | ) 43 | this.fs.copyTpl( 44 | this.templatePath("electron-react/src/App.js"), 45 | this.destinationPath("src/App.js"), 46 | answers 47 | ) 48 | this.fs.copy( 49 | this.templatePath("electron-react/src/App.test.js"), 50 | this.destinationPath("src/App.test.js") 51 | ) 52 | this.fs.copy( 53 | this.templatePath("electron-react/src/index.js"), 54 | this.destinationPath("src/index.js") 55 | ) 56 | this.fs.copy( 57 | this.templatePath( 58 | "electron-react/src/utilities/registerServiceWorker.js" 59 | ), 60 | this.destinationPath("src/utilities/registerServiceWorker.js") 61 | ) 62 | this.fs.copyTpl( 63 | this.templatePath("electron-react/public/electron.js"), 64 | this.destinationPath("public/electron.js"), 65 | answers 66 | ) 67 | this.fs.copy( 68 | this.templatePath("electron-react/public/favicon.ico"), 69 | this.destinationPath("public/favicon.ico") 70 | ) 71 | this.fs.copy( 72 | this.templatePath("electron-react/public/index.html"), 73 | this.destinationPath("public/index.html") 74 | ) 75 | this.fs.copyTpl( 76 | this.templatePath("electron-react/public/manifest.json"), 77 | this.destinationPath("public/manifest.json"), 78 | answers 79 | ) 80 | if (answers.autoupdate) { 81 | this.fs.copyTpl( 82 | this.templatePath("electron-react/electron-builder.yml"), 83 | this.destinationPath("electron-builder.yml"), 84 | answers 85 | ) 86 | } 87 | this.answers=answers 88 | this.npmInstall() 89 | } 90 | 91 | this.prompt([ 92 | { 93 | type: "input", 94 | name: "name", 95 | message: "Your project name", 96 | default: this.appname 97 | .split(" ") 98 | .join("") 99 | .toLowerCase(), // Default to current folder name 100 | }, 101 | { 102 | type: "input", 103 | name: "description", 104 | message: "Your project description", 105 | }, 106 | { 107 | type: "input", 108 | name: "author", 109 | message: "Who are you?", 110 | default: this.user.git.name, 111 | store: true, 112 | }, 113 | { 114 | type: "confirm", 115 | name: "sass", 116 | message: "Do you want to use sass?" 117 | }, 118 | { 119 | type: "confirm", 120 | name: "prettier", 121 | message: "Do you want to use Prettier linter?" 122 | }, 123 | { 124 | type: "confirm", 125 | name: "autoupdate", 126 | message: "Do you want to enable automatic update delivery?", 127 | }, 128 | ]).then(answers => { 129 | createApp = createApp.bind(this) 130 | if (!answers.autoupdate) { 131 | createApp(answers) 132 | } else { 133 | this.prompt([ 134 | { 135 | type: "input", 136 | name: "repository", 137 | message: "Github repository link", 138 | default: 139 | "https://github.com/" + 140 | this.user.git.name() + 141 | "/" + 142 | this.appname 143 | .split(" ") 144 | .join("") 145 | .toLowerCase(), 146 | }, 147 | { 148 | type: "input", 149 | name: "token", 150 | message: "Enter your github access token", 151 | store: true, 152 | }, 153 | ]).then(answers2 => { 154 | createApp({...answers, ...answers2}) 155 | }) 156 | } 157 | }) 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /generators/app/templates/electron-react/README.md: -------------------------------------------------------------------------------- 1 | # <%= name %> 2 | <%= description %> 3 | -------------------------------------------------------------------------------- /generators/app/templates/electron-react/electron-builder.yml: -------------------------------------------------------------------------------- 1 | publish: 2 | provider: github 3 | token: <%= token %> 4 | appId: com.<%= name %> 5 | files: 6 | - build/**/* 7 | - node_modules/**/*" 8 | directories: 9 | buildResources: assets 10 | productName: <%= name %> 11 | -------------------------------------------------------------------------------- /generators/app/templates/electron-react/gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | .env.local 16 | .env.development.local 17 | .env.test.local 18 | .env.production.local 19 | 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | 24 | # yarn 25 | package-lock.json 26 | yarn.lock 27 | 28 | <% if (autoupdate) { %> 29 | electron-builder.yml 30 | <% } %> 31 | -------------------------------------------------------------------------------- /generators/app/templates/electron-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= name %>", 3 | "version": "0.1.0", 4 | "author": "<%= author %>", 5 | "homepage": "./", 6 | "description": "<%= description %>", 7 | "main": "public/electron.js",<% if (autoupdate) { %> 8 | "repository": "<%= repository %>",<% } %> 9 | "build": { 10 | "appId": "com.<%= name %>", 11 | "files": ["build/**/*", "node_modules/**/*"], 12 | "directories": { 13 | "buildResources": "assets" 14 | } 15 | }, 16 | "dependencies": { 17 | <% if (sass) { %>"node-sass-chokidar": "0.0.3", 18 | <% } %><% if (autoupdate) { %>"electron-updater": "^2.10.1",<% } %> 19 | "react": "^15.6.1", 20 | "react-dom": "^15.6.1", 21 | "react-scripts": "1.0.10", 22 | "electron-is-dev": "^0.3.0" 23 | 24 | },<% if (prettier) { %> 25 | "lint-staged": { 26 | "{{public,src}/**/*.{scss,js,json},package.json}": [ 27 | "prettier --write \"{{public,src}/**/*.{scss,js,json},package.json}\"", 28 | "git add" 29 | ] 30 | },<% } %> 31 | "scripts": {<% if (autoupdate) { %> 32 | <% if (sass) { %>"preship":"yarn build && yarn build-css",<% } %><% if (!sass) { %>"preship":"yarn build",<% } %> 33 | "ship": 34 | "build --em.main=build/electron.js --win --ia32 -p always -c electron-builder.yml",<% } %> 35 | <% if (sass) { %>"build-css": "node-sass-chokidar src/ -o src/", 36 | "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",<% } %> 37 | "start": "react-scripts start", 38 | "build": "react-scripts build", 39 | "test": "react-scripts test --env=jsdom", 40 | "eject": "react-scripts eject",<% if (prettier) { %> 41 | "pretty": 42 | "prettier --write \"{{public,src}/**/*.{css,scss,js,json},package.json}\"", 43 | "precommit": "lint-staged",<% } %> 44 | "electron-dev": "<%- electrondev %>", 45 | "electron-pack": "build --em.main=build/electron.js --win --ia32 -c electron-builder.yml", 46 | <% if (sass) { %>"preelectron-pack": "yarn build && yarn build-css"<% } %><% if (!sass) { %>"preelectron-pack": "yarn build"<% } %> 47 | }, 48 | "devDependencies": {<% if (prettier) { %> 49 | "prettier": "^1.7.4", 50 | "husky": "^0.14.3", 51 | "lint-staged": "^4.2.3",<% } %> 52 | "concurrently": "^3.5.0", 53 | "electron": "^1.7.5", 54 | "electron-builder": "^19.20.1", 55 | "wait-on": "^2.0.2" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /generators/app/templates/electron-react/public/electron.js: -------------------------------------------------------------------------------- 1 | const {app, BrowserWindow, ipcMain} = require('electron'); 2 | const path = require('path'); 3 | const isDev = require('electron-is-dev'); 4 | <% if (autoupdate) { %> 5 | const {autoUpdater} = require("electron-updater"); 6 | <% } %> 7 | 8 | let mainWindow; 9 | 10 | function createWindow() { 11 | mainWindow = new BrowserWindow({width: 900, height: 680}); 12 | mainWindow.loadURL(isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, '../build/index.html')}`); // load the react app 13 | mainWindow.on('closed', () => mainWindow = null); 14 | } 15 | <% if (autoupdate) { %> 16 | // when the app is loaded create a BrowserWindow and check for updates 17 | app.on('ready', function() { 18 | createWindow() 19 | if (!isDev) autoUpdater.checkForUpdates(); 20 | }); 21 | <% } %> 22 | <% if (!autoupdate) { %> 23 | app.on('ready', createWindow); 24 | <% } %> 25 | 26 | // on MacOS leave process running also with no windows 27 | app.on('window-all-closed', () => { 28 | if (process.platform !== 'darwin') { 29 | app.quit(); 30 | } 31 | }); 32 | 33 | // if there are no windows create one 34 | app.on('activate', () => { 35 | if (mainWindow === null) { 36 | createWindow(); 37 | } 38 | }); 39 | 40 | <% if (autoupdate) { %> 41 | // when the update has been downloaded and is ready to be installed, notify the BrowserWindow 42 | autoUpdater.on('update-downloaded', (info) => { 43 | mainWindow.webContents.send('updateReady') 44 | }); 45 | 46 | // when receiving a quitAndInstall signal, quit and install the new version ;) 47 | ipcMain.on("quitAndInstall", (event, arg) => { 48 | autoUpdater.quitAndInstall(); 49 | }) 50 | <% } %> 51 | -------------------------------------------------------------------------------- /generators/app/templates/electron-react/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZaninAndrea/generator-react-electron/3d6cd704d1d8ce7fc4930305317ffd33e4b2f355/generators/app/templates/electron-react/public/favicon.ico -------------------------------------------------------------------------------- /generators/app/templates/electron-react/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 |