├── .gitignore
├── LICENSE
├── README.md
├── app
├── index.html
├── index.js
├── scripts
│ ├── app.jsx
│ └── components
│ │ └── main.jsx
└── styles
│ └── main.scss
├── gulpfile.js
├── images
└── term.png
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### OSX template
3 | .DS_Store
4 | .AppleDouble
5 | .LSOverride
6 |
7 | # Icon must end with two \r
8 | Icon
9 |
10 | # Thumbnails
11 | ._*
12 |
13 | # Files that might appear in the root of a volume
14 | .DocumentRevisions-V100
15 | .fseventsd
16 | .Spotlight-V100
17 | .TemporaryItems
18 | .Trashes
19 | .VolumeIcon.icns
20 |
21 | # Directories potentially created on remote AFP share
22 | .AppleDB
23 | .AppleDesktop
24 | Network Trash Folder
25 | Temporary Items
26 | .apdisk
27 |
28 |
29 | ### Vim template
30 | [._]*.s[a-w][a-z]
31 | [._]s[a-w][a-z]
32 | *.un~
33 | Session.vim
34 | .netrwhist
35 | *~
36 |
37 |
38 | ### Windows template
39 | # Windows image file caches
40 | Thumbs.db
41 | ehthumbs.db
42 |
43 | # Folder config file
44 | Desktop.ini
45 |
46 | # Recycle Bin used on file shares
47 | $RECYCLE.BIN/
48 |
49 | # Windows Installer files
50 | *.cab
51 | *.msi
52 | *.msm
53 | *.msp
54 |
55 | # Windows shortcuts
56 | *.lnk
57 |
58 |
59 | ### JetBrains template
60 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
61 |
62 | *.iml
63 |
64 | ## Directory-based project format:
65 | .idea/
66 | # if you remove the above rule, at least ignore the following:
67 |
68 | # User-specific stuff:
69 | # .idea/workspace.xml
70 | # .idea/tasks.xml
71 | # .idea/dictionaries
72 |
73 | # Sensitive or high-churn files:
74 | # .idea/dataSources.ids
75 | # .idea/dataSources.xml
76 | # .idea/sqlDataSources.xml
77 | # .idea/dynamic.xml
78 | # .idea/uiDesigner.xml
79 |
80 | # Gradle:
81 | # .idea/gradle.xml
82 | # .idea/libraries
83 |
84 | # Mongo Explorer plugin:
85 | # .idea/mongoSettings.xml
86 |
87 | ## File-based project format:
88 | *.ipr
89 | *.iws
90 |
91 | ## Plugin-specific files:
92 |
93 | # IntelliJ
94 | /out/
95 |
96 | # mpeltonen/sbt-idea plugin
97 | .idea_modules/
98 |
99 | # JIRA plugin
100 | atlassian-ide-plugin.xml
101 |
102 | # Crashlytics plugin (for Android Studio and IntelliJ)
103 | com_crashlytics_export_strings.xml
104 | crashlytics.properties
105 | crashlytics-build.properties
106 |
107 |
108 |
109 | ### Yeoman template
110 | node_modules/
111 | bower_components/
112 | *.log
113 |
114 | build/
115 | dist/
116 |
117 |
118 | ### Node template
119 | # Logs
120 | logs
121 | *.log
122 |
123 | # Runtime data
124 | pids
125 | *.pid
126 | *.seed
127 |
128 | # Directory for instrumented libs generated by jscoverage/JSCover
129 | lib-cov
130 |
131 | # Coverage directory used by tools like istanbul
132 | coverage
133 |
134 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
135 | .grunt
136 |
137 | # node-waf configuration
138 | .lock-wscript
139 |
140 | # Compiled binary addons (http://nodejs.org/api/addons.html)
141 | build/Release
142 |
143 | # Dependency directory
144 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
145 | node_modules
146 |
147 |
148 | ### electron-starterify
149 | release/
150 | cache/
151 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015, Jaewe Heo
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ANOTHER *[EPP][epp](Electron aPPlication)*
2 |
3 |
4 | # electron-starterify
5 |
6 | :electric_plug: [Electron][electron] application skeleton based on [React][react]
7 |
8 |
9 | ## Usage
10 |
11 | Install dependencies.
12 |
13 | ```sh
14 | $ npm install
15 | ```
16 |
17 | ### Development
18 |
19 | ```sh
20 | $ gulp watch
21 | ```
22 |
23 | ### Release (Deploy)
24 |
25 | 1. Set `release` [task option][opt] in `gulpfile.js` if you want.
26 | - Check [latest version of electron][latest]
27 |
28 | 2. Run
29 | ```sh
30 | $ gulp build
31 | ```
32 |
33 | 3. See `./release` directory
34 |
35 |
36 | ## Troubleshooting
37 |
38 | - [Error: spawn zip ENOENT][issue1] on Windows
39 |
40 |
41 | [electron]: http://electron.atom.io/
42 | [react]: http://facebook.github.io/react/
43 | [latest]: https://github.com/atom/electron/releases/latest
44 | [opt]: https://github.com/mainyaa/gulp-electron#options
45 | [issue1]: https://github.com/importre/electron-starterify/issues/1#issuecomment-101391136
46 | [epp]: https://github.com/importre/epp/
47 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | electron-starterify
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const app = require('app');
4 | const BrowserWindow = require('browser-window');
5 | const Menu = require('menu');
6 | const MenuItem = require('menu-item');
7 |
8 | // report crashes to the Electron project
9 | require('crash-reporter').start();
10 |
11 | // prevent window being GC'd
12 | let mainWindow = null;
13 | var menu = null;
14 |
15 | app.on('window-all-closed', function () {
16 | app.quit();
17 | });
18 |
19 | app.on('ready', function () {
20 | mainWindow = new BrowserWindow({
21 | width: 1280,
22 | height: 768,
23 | resizable: true
24 | });
25 |
26 | mainWindow.loadUrl(`file://${__dirname}/index.html`);
27 |
28 | try {
29 | var bs = require("browser-sync").create();
30 | bs.watch(`${__dirname}/**/*`, function (event, file) {
31 | if (event == "change" && file.match(/(.css|.html|.js)$/g)) {
32 | mainWindow.reloadIgnoringCache();
33 | }
34 | });
35 | } catch (e) {
36 | }
37 |
38 | if (process.platform == 'darwin') {
39 | var darwinTmpl = [
40 | {
41 | label: 'Electron',
42 | submenu: [
43 | {
44 | label: 'About Electron',
45 | selector: 'orderFrontStandardAboutPanel:'
46 | },
47 | {
48 | type: 'separator'
49 | },
50 | {
51 | label: 'Services',
52 | submenu: []
53 | },
54 | {
55 | type: 'separator'
56 | },
57 | {
58 | label: 'Hide Electron',
59 | accelerator: 'Command+H',
60 | selector: 'hide:'
61 | },
62 | {
63 | label: 'Hide Others',
64 | accelerator: 'Command+Shift+H',
65 | selector: 'hideOtherApplications:'
66 | },
67 | {
68 | label: 'Show All',
69 | selector: 'unhideAllApplications:'
70 | },
71 | {
72 | type: 'separator'
73 | },
74 | {
75 | label: 'Quit',
76 | accelerator: 'Command+Q',
77 | click: function () {
78 | app.quit();
79 | }
80 | }
81 | ]
82 | },
83 | {
84 | label: 'Edit',
85 | submenu: [
86 | {
87 | label: 'Undo',
88 | accelerator: 'Command+Z',
89 | selector: 'undo:'
90 | },
91 | {
92 | label: 'Redo',
93 | accelerator: 'Shift+Command+Z',
94 | selector: 'redo:'
95 | },
96 | {
97 | type: 'separator'
98 | },
99 | {
100 | label: 'Cut',
101 | accelerator: 'Command+X',
102 | selector: 'cut:'
103 | },
104 | {
105 | label: 'Copy',
106 | accelerator: 'Command+C',
107 | selector: 'copy:'
108 | },
109 | {
110 | label: 'Paste',
111 | accelerator: 'Command+V',
112 | selector: 'paste:'
113 | },
114 | {
115 | label: 'Select All',
116 | accelerator: 'Command+A',
117 | selector: 'selectAll:'
118 | }
119 | ]
120 | },
121 | {
122 | label: 'View',
123 | submenu: [
124 | {
125 | label: 'Reload',
126 | accelerator: 'Command+R',
127 | click: function () {
128 | mainWindow.restart();
129 | }
130 | },
131 | {
132 | label: 'Toggle Full Screen',
133 | accelerator: 'Ctrl+Command+F',
134 | click: function () {
135 | mainWindow.setFullScreen(!mainWindow.isFullScreen());
136 | }
137 | },
138 | {
139 | label: 'Toggle Developer Tools',
140 | accelerator: 'Alt+Command+I',
141 | click: function () {
142 | mainWindow.toggleDevTools();
143 | }
144 | }
145 | ]
146 | },
147 | {
148 | label: 'Window',
149 | submenu: [
150 | {
151 | label: 'Minimize',
152 | accelerator: 'Command+M',
153 | selector: 'performMiniaturize:'
154 | },
155 | {
156 | label: 'Close',
157 | accelerator: 'Command+W',
158 | selector: 'performClose:'
159 | },
160 | {
161 | type: 'separator'
162 | },
163 | {
164 | label: 'Bring All to Front',
165 | selector: 'arrangeInFront:'
166 | }
167 | ]
168 | },
169 | {
170 | label: 'Help',
171 | submenu: [
172 | {
173 | label: 'Learn More',
174 | click: function () {
175 | require('shell').openExternal('http://electron.atom.io')
176 | }
177 | },
178 | {
179 | label: 'Documentation',
180 | click: function () {
181 | require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme')
182 | }
183 | },
184 | {
185 | label: 'Community Discussions',
186 | click: function () {
187 | require('shell').openExternal('https://discuss.atom.io/c/electron')
188 | }
189 | },
190 | {
191 | label: 'Search Issues',
192 | click: function () {
193 | require('shell').openExternal('https://github.com/atom/electron/issues')
194 | }
195 | }
196 | ]
197 | }
198 | ];
199 |
200 | menu = Menu.buildFromTemplate(darwinTmpl);
201 | Menu.setApplicationMenu(menu);
202 | } else {
203 | var template = [
204 | {
205 | label: '&File',
206 | submenu: [
207 | {
208 | label: '&Open',
209 | accelerator: 'Ctrl+O'
210 | },
211 | {
212 | label: '&Close',
213 | accelerator: 'Ctrl+W',
214 | click: function () {
215 | mainWindow.close();
216 | }
217 | }
218 | ]
219 | },
220 | {
221 | label: '&View',
222 | submenu: [
223 | {
224 | label: '&Reload',
225 | accelerator: 'Ctrl+R',
226 | click: function () {
227 | mainWindow.restart();
228 | }
229 | },
230 | {
231 | label: 'Toggle &Full Screen',
232 | accelerator: 'F11',
233 | click: function () {
234 | mainWindow.setFullScreen(!mainWindow.isFullScreen());
235 | }
236 | },
237 | {
238 | label: 'Toggle &Developer Tools',
239 | accelerator: 'Alt+Ctrl+I',
240 | click: function () {
241 | mainWindow.toggleDevTools();
242 | }
243 | }
244 | ]
245 | },
246 | {
247 | label: 'Help',
248 | submenu: [
249 | {
250 | label: 'Learn More',
251 | click: function () {
252 | require('shell').openExternal('http://electron.atom.io')
253 | }
254 | },
255 | {
256 | label: 'Documentation',
257 | click: function () {
258 | require('shell').openExternal('https://github.com/atom/electron/tree/master/docs#readme')
259 | }
260 | },
261 | {
262 | label: 'Community Discussions',
263 | click: function () {
264 | require('shell').openExternal('https://discuss.atom.io/c/electron')
265 | }
266 | },
267 | {
268 | label: 'Search Issues',
269 | click: function () {
270 | require('shell').openExternal('https://github.com/atom/electron/issues')
271 | }
272 | }
273 | ]
274 | }
275 | ];
276 |
277 | menu = Menu.buildFromTemplate(template);
278 | mainWindow.setMenu(menu);
279 | }
280 |
281 |
282 | mainWindow.on('closed', function () {
283 | // deref the window
284 | // for multiple windows store them in an array
285 | mainWindow = null;
286 | });
287 | });
288 |
--------------------------------------------------------------------------------
/app/scripts/app.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Main from './components/main.jsx'
3 |
4 | window.React = React;
5 |
6 | React.render(, document.body);
7 |
--------------------------------------------------------------------------------
/app/scripts/components/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | let Main = React.createClass({
4 | render: function () {
5 | return (
6 |
7 |
electron-starterify
8 |

Hello,
Electron!!!
9 |
10 | )
11 | }
12 | });
13 |
14 | export default Main;
15 |
--------------------------------------------------------------------------------
/app/styles/main.scss:
--------------------------------------------------------------------------------
1 | *, *:before, *:after {
2 | box-sizing: border-box;
3 | }
4 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | var babelify = require('babelify');
4 | var browserSync = require('browser-sync');
5 | var browserify = require('browserify');
6 | var buffer = require('vinyl-buffer');
7 | var changed = require('gulp-changed');
8 | var copy = require('gulp-copy');
9 | var csso = require('gulp-csso');
10 | var del = require('del');
11 | var electron = require('gulp-electron');
12 | var gulp = require('gulp');
13 | var notify = require('gulp-notify');
14 | var packageJson = require('./package.json');
15 | var sass = require('gulp-sass');
16 | var shell = require('gulp-shell');
17 | var source = require('vinyl-source-stream');
18 | var uglify = require('gulp-uglify');
19 |
20 | var o = {
21 | jsx: 'app/scripts/app.jsx',
22 | scss: 'app/styles/main.scss',
23 | bundle: 'app.js',
24 | distJs: 'dist/app/js',
25 | distCss: 'dist/app/css'
26 | };
27 |
28 | gulp.task('clean', function (cb) {
29 | del(['dist', 'release'], cb);
30 | });
31 |
32 | gulp.task('images', function () {
33 | return gulp.src('images/**/*')
34 | .pipe(gulp.dest('dist/app/images'));
35 | });
36 |
37 | gulp.task('etc', function () {
38 | return gulp.src(['app/index.html', 'app/index.js', 'package.json'])
39 | .pipe(gulp.dest('dist/app'));
40 | });
41 |
42 | gulp.task('copy', function () {
43 | gulp.start(['images', 'etc']);
44 | });
45 |
46 | gulp.task('browserify', function () {
47 | return browserify(o.jsx)
48 | .transform(babelify)
49 | .bundle()
50 | .pipe(source(o.bundle))
51 | .pipe(buffer())
52 | .pipe(uglify())
53 | .pipe(gulp.dest(o.distJs));
54 | });
55 |
56 | gulp.task('browserifyDev', function () {
57 | return browserify(o.jsx)
58 | .transform(babelify)
59 | .bundle()
60 | .pipe(source(o.bundle))
61 | .pipe(gulp.dest(o.distJs));
62 | });
63 |
64 | gulp.task('styles', function () {
65 | return gulp.src(o.scss)
66 | .pipe(changed(o.distCss))
67 | .pipe(sass({errLogToConsole: true}))
68 | .on('error', notify.onError())
69 | .pipe(csso())
70 | .pipe(gulp.dest(o.distCss));
71 | });
72 |
73 | gulp.task('browserSync', function () {
74 | var bs = browserSync.create();
75 | bs.watch('app/**/*').on('change', function () {
76 | gulp.start(['browserifyDev', 'copy', 'styles']);
77 | });
78 | });
79 |
80 | gulp.task('electron', ['browserifyDev'], function () {
81 | var cmd = '';
82 | switch (process.platform) {
83 | case 'darwin':
84 | cmd = './node_modules/electron-prebuilt/dist/Electron.app/Contents/MacOS/Electron dist/app';
85 | break;
86 | case 'win32':
87 | cmd = 'node_modules\\electron-prebuilt\\dist\\electron.exe dist\\app';
88 | break;
89 | case 'linux':
90 | cmd = './node_modules/electron-prebuilt/dist/electron dist/app';
91 | break;
92 | default:
93 | console.log(process.platform + ' is not supported.');
94 | return;
95 | }
96 |
97 | return gulp.src('', {read: false})
98 | .pipe(shell(cmd));
99 | });
100 |
101 | gulp.task('release', ['browserify'], function () {
102 | gulp.src('')
103 | .pipe(electron({
104 | src: './dist/app',
105 | packageJson: packageJson,
106 | release: './release',
107 | cache: './cache',
108 | version: 'v0.26.0',
109 | rebuild: false,
110 | platforms: ['win32-ia32', 'darwin-x64']
111 | }))
112 | .pipe(gulp.dest(''));
113 | });
114 |
115 | gulp.task('watch', ['clean'], function () {
116 | gulp.start(['browserifyDev', 'copy', 'styles', 'browserSync', 'electron']);
117 | });
118 |
119 | gulp.task('build', ['clean'], function () {
120 | process.env.NODE_ENV = 'production';
121 | gulp.start(['browserify', 'copy', 'styles', 'release']);
122 | });
123 |
124 | gulp.task('default', function () {
125 | console.log('Run `gulp watch` or `gulp build`');
126 | });
127 |
128 |
--------------------------------------------------------------------------------
/images/term.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/importre/electron-starterify/4edbc88f517b4ffae6738ea51e75c45ab487a698/images/term.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "electron-starterify",
3 | "version": "0.0.1",
4 | "description": "Electron application skeleton based on React",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/importre/electron-starterify.git"
12 | },
13 | "keywords": [
14 | "electron",
15 | "react"
16 | ],
17 | "author": "Jaewe Heo",
18 | "license": "BSD",
19 | "bugs": {
20 | "url": "https://github.com/importre/electron-starterify/issues"
21 | },
22 | "homepage": "https://github.com/importre/electron-starterify#readme",
23 | "dependencies": {
24 | "react": "^0.13.3",
25 | "superagent": "^1.2.0"
26 | },
27 | "devDependencies": {
28 | "asar": "^0.6.1",
29 | "babelify": "^6.1.0",
30 | "browser-sync": "^2.7.1",
31 | "browserify": "^10.1.3",
32 | "del": "^1.1.1",
33 | "electron-prebuilt": "^0.25.3-2",
34 | "gulp": "^3.8.11",
35 | "gulp-changed": "^1.2.1",
36 | "gulp-copy": "0.0.2",
37 | "gulp-csso": "^1.0.0",
38 | "gulp-electron": "0.0.3",
39 | "gulp-notify": "^2.2.0",
40 | "gulp-sass": "^2.0.0",
41 | "gulp-shell": "^0.4.1",
42 | "gulp-uglify": "^1.2.0",
43 | "vinyl-buffer": "^1.0.0",
44 | "vinyl-source-stream": "^1.1.0"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------