1
0
mirror of https://github.com/TheGreyDiamond/Enlight.git synced 2025-07-17 20:33:48 +02:00
This commit is contained in:
TheGreyDiamond
2020-11-29 17:43:34 +01:00
parent 05ad177917
commit 015e0779a3
112 changed files with 18004 additions and 0 deletions

48
enlightApp/.dockerignore Normal file
View File

@ -0,0 +1,48 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
.eslintcache
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
# OSX
.DS_Store
# App packaged
release
app/main.prod.js
app/main.prod.js.map
app/renderer.prod.js
app/renderer.prod.js.map
app/style.css
app/style.css.map
dist
dll
main.js
main.js.map
.idea
npm-debug.log.*
.*.dockerfile

12
enlightApp/.editorconfig Normal file
View File

@ -0,0 +1,12 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

56
enlightApp/.eslintignore Normal file
View File

@ -0,0 +1,56 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
.eslintcache
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
# OSX
.DS_Store
# App packaged
release
app/*.main.prod.js
app/main.prod.js
app/main.prod.js.map
app/renderer.prod.js
app/renderer.prod.js.map
app/style.css
app/style.css.map
dist
dll
main.js
main.js.map
.idea
npm-debug.log.*
__snapshots__
# Package.json
package.json
.travis.yml
*.css.d.ts
*.sass.d.ts
*.scss.d.ts

26
enlightApp/.eslintrc.js Normal file
View File

@ -0,0 +1,26 @@
module.exports = {
extends: 'erb',
rules: {
// A temporary hack related to IDE not resolving correct package.json
'import/no-extraneous-dependencies': 'off',
},
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
project: './tsconfig.json',
tsconfigRootDir: __dirname,
createDefaultProgram: true,
},
settings: {
'import/resolver': {
// See https://github.com/benmosher/eslint-plugin-import/issues/1396#issuecomment-575727774 for line below
node: {},
webpack: {
config: require.resolve('./configs/webpack.config.eslint.js'),
},
},
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx'],
},
},
};

7
enlightApp/.gitattributes vendored Normal file
View File

@ -0,0 +1,7 @@
* text eol=lf
*.exe binary
*.png binary
*.jpg binary
*.jpeg binary
*.ico binary
*.icns binary

5
enlightApp/.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,5 @@
# These are supported funding model platforms
github: [electron-react-boilerplate, amilajack]
patreon: amilajack
open_collective: electron-react-boilerplate-594

View File

@ -0,0 +1,67 @@
---
name: Bug report
about: You're having technical issues. 🐞
labels: 'bug'
---
<!-- Please use the following issue template or your issue will be closed -->
## Prerequisites
<!-- If the following boxes are not ALL checked, your issue is likely to be closed -->
- [ ] Using yarn
- [ ] Using an up-to-date [`master` branch](https://github.com/electron-react-boilerplate/electron-react-boilerplate/tree/master)
- [ ] Using latest version of devtools. [Check the docs for how to update](https://electron-react-boilerplate.js.org/docs/dev-tools/)
- [ ] Tried solutions mentioned in [#400](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/400)
- [ ] For issue in production release, add devtools output of `DEBUG_PROD=true yarn build && yarn start`
## Expected Behavior
<!--- What should have happened? -->
## Current Behavior
<!--- What went wrong? -->
## Steps to Reproduce
<!-- Add relevant code and/or a live example -->
<!-- Add stack traces -->
1.
2.
3.
4.
## Possible Solution (Not obligatory)
<!--- Suggest a reason for the bug or how to fix it. -->
## Context
<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Did you make any changes to the boilerplate after cloning it? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
- Node version :
- electron-react-boilerplate version or branch :
- Operating System and version :
- Link to your project :
<!---
❗️❗️ Also, please consider donating (https://opencollective.com/electron-react-boilerplate-594) ❗️❗️
Donations will ensure the following:
🔨 Long term maintenance of the project
🛣 Progress on the roadmap
🐛 Quick responses to bug reports and help requests
-->

View File

@ -0,0 +1,19 @@
---
name: Question
about: Ask a question.❓
labels: 'question'
---
## Summary
<!-- What do you need help with? -->
<!---
❗️❗️ Also, please consider donating (https://opencollective.com/electron-react-boilerplate-594) ❗️❗️
Donations will ensure the following:
🔨 Long term maintenance of the project
🛣 Progress on the roadmap
🐛 Quick responses to bug reports and help requests
-->

View File

@ -0,0 +1,15 @@
---
name: Feature request
about: You want something added to the boilerplate. 🎉
labels: 'enhancement'
---
<!---
❗️❗️ Also, please consider donating (https://opencollective.com/electron-react-boilerplate-594) ❗️❗️
Donations will ensure the following:
🔨 Long term maintenance of the project
🛣 Progress on the roadmap
🐛 Quick responses to bug reports and help requests
-->

6
enlightApp/.github/config.yml vendored Normal file
View File

@ -0,0 +1,6 @@
requiredHeaders:
- Prerequisites
- Expected Behavior
- Current Behavior
- Possible Solution
- Your Environment

17
enlightApp/.github/stale.yml vendored Normal file
View File

@ -0,0 +1,17 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pr
- discussion
- e2e
- enhancement
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@ -0,0 +1,33 @@
name: Publish
on:
push:
branches:
- master
jobs:
publish:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest]
steps:
- name: Check out Git repository
uses: actions/checkout@v1
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v1
with:
node-version: 14
- name: yarn install
run: |
yarn install
- name: Publish Releases
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
yarn package-ci

46
enlightApp/.github/workflows/test.yml vendored Normal file
View File

@ -0,0 +1,46 @@
name: Test
on: [push, pull_request]
jobs:
release:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Check out Git repository
uses: actions/checkout@v1
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v1
with:
node-version: 14
- name: yarn install
run: |
yarn install --frozen-lockfile --network-timeout 300000
- name: yarn test
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
yarn package
yarn lint
yarn tsc
yarn test
yarn build-e2e
- if: matrix.os == 'ubuntu-latest'
run: |
Xvfb :99 &
disown -ar
echo "::set-env name=DISPLAY:::99"
# TODO: Testcafe e2e are broken because of:
# https://github.com/DevExpress/testcafe/issues/4512
# Tests are currently broken on linux and macos
# - if: matrix.os == 'windows-latest'
# run: |
# yarn test-e2e

50
enlightApp/.gitignore vendored Normal file
View File

@ -0,0 +1,50 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
.eslintcache
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
# OSX
.DS_Store
# App packaged
release
app/main.prod.js
app/main.prod.js.map
app/renderer.prod.js
app/renderer.prod.js.map
app/style.css
app/style.css.map
dist
dll
main.js
main.js.map
.idea
npm-debug.log.*
*.css.d.ts
*.sass.d.ts
*.scss.d.ts

7
enlightApp/.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
"msjsdiag.debugger-for-chrome"
]
}

28
enlightApp/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,28 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Electron: Main",
"protocol": "inspector",
"runtimeExecutable": "yarn",
"runtimeArgs": ["start-main-debug"],
"preLaunchTask": "Start Webpack Dev"
},
{
"name": "Electron: Renderer",
"type": "chrome",
"request": "attach",
"port": 9223,
"webRoot": "${workspaceFolder}",
"timeout": 15000
}
],
"compounds": [
{
"name": "Electron: All",
"configurations": ["Electron: Main", "Electron: Renderer"]
}
]
}

30
enlightApp/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,30 @@
{
"files.associations": {
".babelrc": "jsonc",
".eslintrc": "jsonc",
".prettierrc": "jsonc",
".stylelintrc": "json",
".dockerignore": "ignore",
".eslintignore": "ignore"
},
"javascript.validate.enable": false,
"javascript.format.enable": false,
"typescript.format.enable": false,
"search.exclude": {
".git": true,
".eslintcache": true,
"app/dist": true,
"app/main.prod.js": true,
"app/main.prod.js.map": true,
"bower_components": true,
"dll": true,
"release": true,
"node_modules": true,
"npm-debug.log.*": true,
"test/**/__snapshots__": true,
"yarn.lock": true,
"*.{css,sass,scss}.d.ts": true
}
}

25
enlightApp/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,25 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"label": "Start Webpack Dev",
"script": "start-renderer-dev",
"options": {
"cwd": "${workspaceFolder}"
},
"isBackground": true,
"problemMatcher": {
"owner": "custom",
"pattern": {
"regexp": "____________"
},
"background": {
"activeOnStart": true,
"beginsPattern": "Compiling\\.\\.\\.$",
"endsPattern": "(Compiled successfully|Failed to compile)\\.$"
}
}
}
]
}

21
enlightApp/LICENSE Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-present Electron React Boilerplate
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

171
enlightApp/README.md Normal file
View File

@ -0,0 +1,171 @@
<img src="internals/img/erb-banner.png" width="100%" />
<br>
<p>
Electron React Boilerplate uses <a href="https://electron.atom.io/">Electron</a>, <a href="https://facebook.github.io/react/">React</a>, <a href="https://github.com/reactjs/redux">Redux</a>, <a href="https://github.com/reactjs/react-router">React Router</a>, <a href="https://webpack.github.io/docs/">Webpack</a> and <a href="https://github.com/gaearon/react-hot-loader">React Hot Loader</a> for rapid application development (HMR).
</p>
<br>
<div align="center">
<a href="https://facebook.github.io/react/"><img src="./internals/img/react-padded-90.png" /></a>
<a href="https://webpack.github.io/"><img src="./internals/img/webpack-padded-90.png" /></a>
<a href="https://redux.js.org/"><img src="./internals/img/redux-padded-90.png" /></a>
<a href="https://github.com/ReactTraining/react-router"><img src="./internals/img/react-router-padded-90.png" /></a>
<a href="https://eslint.org/"><img src="./internals/img/eslint-padded-90.png" /></a>
<a href="https://facebook.github.io/jest/"><img src="./internals/img/jest-padded-90.png" /></a>
<a href="https://yarnpkg.com/"><img src="./internals/img/yarn-padded-90.png" /></a>
</div>
<hr />
<br />
<div align="center">
[![Build Status][github-actions-status]][github-actions-url]
[![Dependency Status][david-image]][david-url]
[![DevDependency Status][david-dev-image]][david-dev-url]
[![Github Tag][github-tag-image]][github-tag-url]
[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/electron-react-blpt)
[![OpenCollective](https://opencollective.com/electron-react-boilerplate/backers/badge.svg)](#backers)
[![OpenCollective](https://opencollective.com/electron-react-boilerplate/sponsors/badge.svg)](#sponsors)
[![Good first issues open][good-first-issue-image]][good-first-issue-url]
[![StackOverflow][stackoverflow-img]][stackoverflow-url]
</div>
## Install
- **If you have installation or compilation issues with this project, please see [our debugging guide](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/400)**
First, clone the repo via git and install dependencies:
```bash
git clone --depth 1 --single-branch https://github.com/electron-react-boilerplate/electron-react-boilerplate.git your-project-name
cd your-project-name
yarn
```
## Starting Development
Start the app in the `dev` environment. This starts the renderer process in [**hot-module-replacement**](https://webpack.js.org/guides/hmr-react/) mode and starts a webpack dev server that sends hot updates to the renderer process:
```bash
yarn start
```
## Packaging for Production
To package apps for the local platform:
```bash
yarn package
```
## Docs
See our [docs and guides here](https://electron-react-boilerplate.js.org/docs/installation)
## Donations
**Donations will ensure the following:**
- 🔨 Long term maintenance of the project
- 🛣 Progress on the [roadmap](https://electron-react-boilerplate.js.org/docs/roadmap)
- 🐛 Quick responses to bug reports and help requests
## Backers
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/electron-react-boilerplate#backer)]
<a href="https://opencollective.com/electron-react-boilerplate/backer/0/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/1/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/2/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/3/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/4/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/5/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/6/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/7/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/8/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/9/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/10/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/11/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/12/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/13/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/14/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/15/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/16/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/17/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/18/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/19/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/20/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/21/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/22/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/23/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/24/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/25/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/26/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/27/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/28/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/backer/29/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/backer/29/avatar.svg"></a>
## Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/electron-react-boilerplate-594#sponsor)]
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/0/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/1/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/2/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/3/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/4/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/5/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/6/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/7/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/8/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/9/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/10/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/10/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/11/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/11/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/12/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/12/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/13/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/13/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/14/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/14/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/15/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/15/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/16/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/16/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/17/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/17/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/18/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/18/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/19/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/19/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/20/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/20/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/21/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/21/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/22/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/22/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/23/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/23/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/24/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/24/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/25/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/25/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/26/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/26/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/27/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/27/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/28/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/28/avatar.svg"></a>
<a href="https://opencollective.com/electron-react-boilerplate/sponsor/29/website" target="_blank"><img src="https://opencollective.com/electron-react-boilerplate/sponsor/29/avatar.svg"></a>
## Maintainers
- [Amila Welihinda](https://github.com/amilajack)
- [John Tran](https://github.com/jooohhn)
- [C. T. Lin](https://github.com/chentsulin)
- [Jhen-Jie Hong](https://github.com/jhen0409)
## License
MIT © [Electron React Boilerplate](https://github.com/electron-react-boilerplate)
[github-actions-status]: https://github.com/electron-react-boilerplate/electron-react-boilerplate/workflows/Test/badge.svg
[github-actions-url]: https://github.com/electron-react-boilerplate/electron-react-boilerplate/actions
[github-tag-image]: https://img.shields.io/github/tag/electron-react-boilerplate/electron-react-boilerplate.svg?label=version
[github-tag-url]: https://github.com/electron-react-boilerplate/electron-react-boilerplate/releases/latest
[stackoverflow-img]: https://img.shields.io/badge/stackoverflow-electron_react_boilerplate-blue.svg
[stackoverflow-url]: https://stackoverflow.com/questions/tagged/electron-react-boilerplate
[david-image]: https://img.shields.io/david/electron-react-boilerplate/electron-react-boilerplate.svg
[david-url]: https://david-dm.org/electron-react-boilerplate/electron-react-boilerplate
[david-dev-image]: https://img.shields.io/david/dev/electron-react-boilerplate/electron-react-boilerplate.svg?label=devDependencies
[david-dev-url]: https://david-dm.org/electron-react-boilerplate/electron-react-boilerplate?type=dev
[good-first-issue-image]: https://img.shields.io/github/issues/electron-react-boilerplate/electron-react-boilerplate/good%20first%20issue.svg?label=good%20first%20issues
[good-first-issue-url]: https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues?q=is%3Aopen+is%3Aissue+label%3A"good+first+issue"

View File

@ -0,0 +1,4 @@
{
"mainWindowUrl": "./app.html",
"appPath": "."
}

28
enlightApp/app/Routes.tsx Normal file
View File

@ -0,0 +1,28 @@
/* eslint react/jsx-props-no-spreading: off */
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import routes from './constants/routes.json';
import App from './containers/App';
import HomePage from './containers/HomePage';
// Lazily load routes and code split with webpack
const LazyCounterPage = React.lazy(() =>
import(/* webpackChunkName: "CounterPage" */ './containers/CounterPage')
);
const CounterPage = (props: Record<string, any>) => (
<React.Suspense fallback={<h1>Loading...</h1>}>
<LazyCounterPage {...props} />
</React.Suspense>
);
export default function Routes() {
return (
<App>
<Switch>
<Route path={routes.COUNTER} component={CounterPage} />
<Route path={routes.HOME} component={HomePage} />
</Switch>
</App>
);
}

View File

@ -0,0 +1,47 @@
/*
* @NOTE: Prepend a `~` to css file paths that are in your node_modules
* See https://github.com/webpack-contrib/sass-loader#imports
*/
@import '~@fortawesome/fontawesome-free/css/all.css';
body {
position: relative;
color: white;
height: 100vh;
background-color: #232c39;
background-image: linear-gradient(
45deg,
rgba(0, 216, 255, 0.5) 10%,
rgba(0, 1, 127, 0.7)
);
font-family: Arial, Helvetica, Helvetica Neue, serif;
overflow-y: hidden;
}
h2 {
margin: 0;
font-size: 2.25rem;
font-weight: bold;
letter-spacing: -0.025em;
color: #fff;
}
p {
font-size: 24px;
}
li {
list-style: none;
}
a {
color: white;
opacity: 0.75;
text-decoration: none;
}
a:hover {
opacity: 1;
text-decoration: none;
cursor: pointer;
}

50
enlightApp/app/app.html Normal file
View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello Electron React!</title>
<script>
(() => {
if (
typeof process !== 'object' ||
(typeof process === 'object' && !process.env.START_HOT)
) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = './dist/style.css';
// HACK: Writing the script path should be done with webpack
document.getElementsByTagName('head')[0].appendChild(link);
}
})();
</script>
</head>
<body>
<div id="root"></div>
<script>
if (typeof process === 'object') {
const scripts = [];
if (process.env.NODE_ENV === 'development') {
// Dynamically insert the DLL script in development env in the
// renderer process
scripts.push('../dll/renderer.dev.dll.js');
}
if (process.env.START_HOT) {
// Dynamically insert the bundled app script in the renderer process
const port = process.env.PORT || 1212;
scripts.push(`http://localhost:${port}/dist/renderer.dev.js`);
} else {
scripts.push('./dist/renderer.prod.js');
}
if (scripts.length) {
document.write(
scripts
.map(script => `<script defer src="${script}"><\/script>`)
.join('')
);
}
}
</script>
</body>
</html>

BIN
enlightApp/app/app.icns Normal file

Binary file not shown.

View File

@ -0,0 +1,14 @@
.container {
position: absolute;
top: 30%;
left: 10px;
text-align: center;
}
.container h2 {
font-size: 5rem;
}
.container a {
font-size: 1.4rem;
}

View File

@ -0,0 +1,13 @@
import React from 'react';
import { Link } from 'react-router-dom';
import routes from '../constants/routes.json';
import styles from './Home.css';
export default function Home(): JSX.Element {
return (
<div className={styles.container} data-tid="container">
<h2>Home</h2>
<Link to={routes.COUNTER}>to Counter</Link>
</div>
);
}

9
enlightApp/app/components/css.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
declare module '*.scss' {
const content: { [className: string]: string };
export default content;
}
declare module '*.css' {
const content: { [className: string]: string };
export default content;
}

View File

@ -0,0 +1,4 @@
{
"HOME": "/",
"COUNTER": "/counter"
}

View File

@ -0,0 +1,10 @@
import React, { ReactNode } from 'react';
type Props = {
children: ReactNode;
};
export default function App(props: Props) {
const { children } = props;
return <>{children}</>;
}

View File

@ -0,0 +1,6 @@
import React from 'react';
import Counter from '../features/counter/Counter';
export default function CounterPage() {
return <Counter />;
}

View File

@ -0,0 +1,6 @@
import React from 'react';
import Home from '../components/Home';
export default function HomePage() {
return <Home />;
}

View File

@ -0,0 +1,22 @@
import React from 'react';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router';
import { hot } from 'react-hot-loader/root';
import { History } from 'history';
import { Store } from '../store';
import Routes from '../Routes';
type Props = {
store: Store;
history: History;
};
const Root = ({ store, history }: Props) => (
<Provider store={store}>
<ConnectedRouter history={history}>
<Routes />
</ConnectedRouter>
</Provider>
);
export default hot(Root);

View File

@ -0,0 +1,37 @@
.backButton {
position: absolute;
}
.counter {
position: absolute;
top: 30%;
left: 45%;
font-size: 10rem;
font-weight: bold;
letter-spacing: -0.025em;
}
.btnGroup {
position: relative;
top: 500px;
width: 480px;
margin: 0 auto;
}
.btn {
font-size: 1.6rem;
font-weight: bold;
background-color: #fff;
border-radius: 50%;
margin: 10px;
width: 100px;
height: 100px;
opacity: 0.7;
cursor: pointer;
font-family: Arial, Helvetica, Helvetica Neue, sans-serif;
}
.btn:hover {
color: white;
background-color: rgba(0, 0, 0, 0.5);
}

View File

@ -0,0 +1,71 @@
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Link } from 'react-router-dom';
import styles from './Counter.css';
import routes from '../../constants/routes.json';
import {
increment,
decrement,
incrementIfOdd,
incrementAsync,
selectCount,
} from './counterSlice';
export default function Counter() {
const dispatch = useDispatch();
const value = useSelector(selectCount);
return (
<div>
<div className={styles.backButton} data-tid="backButton">
<Link to={routes.HOME}>
<i className="fa fa-arrow-left fa-3x" />
</Link>
</div>
<div className={`counter ${styles.counter}`} data-tid="counter">
{value}
</div>
<div className={styles.btnGroup}>
<button
className={styles.btn}
onClick={() => {
dispatch(increment());
}}
data-tclass="btn"
type="button"
>
<i className="fa fa-plus" />
</button>
<button
className={styles.btn}
onClick={() => {
dispatch(decrement());
}}
data-tclass="btn"
type="button"
>
<i className="fa fa-minus" />
</button>
<button
className={styles.btn}
onClick={() => {
dispatch(incrementIfOdd());
}}
data-tclass="btn"
type="button"
>
odd
</button>
<button
className={styles.btn}
onClick={() => {
dispatch(incrementAsync());
}}
data-tclass="btn"
type="button"
>
async
</button>
</div>
</div>
);
}

View File

@ -0,0 +1,38 @@
import { createSlice } from '@reduxjs/toolkit';
// eslint-disable-next-line import/no-cycle
import { AppThunk, RootState } from '../../store';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
},
});
export const { increment, decrement } = counterSlice.actions;
export const incrementIfOdd = (): AppThunk => {
return (dispatch, getState) => {
const state = getState();
if (state.counter.value % 2 === 0) {
return;
}
dispatch(increment());
};
};
export const incrementAsync = (delay = 1000): AppThunk => (dispatch) => {
setTimeout(() => {
dispatch(increment());
}, delay);
};
export default counterSlice.reducer;
export const selectCount = (state: RootState) => state.counter.value;

20
enlightApp/app/index.tsx Normal file
View File

@ -0,0 +1,20 @@
import React, { Fragment } from 'react';
import { render } from 'react-dom';
import { AppContainer as ReactHotAppContainer } from 'react-hot-loader';
import { history, configuredStore } from './store';
import './app.global.css';
const store = configuredStore();
const AppContainer = process.env.PLAIN_HMR ? Fragment : ReactHotAppContainer;
document.addEventListener('DOMContentLoaded', () => {
// eslint-disable-next-line global-require
const Root = require('./containers/Root').default;
render(
<AppContainer>
<Root store={store} history={history} />
</AppContainer>,
document.getElementById('root')
);
});

138
enlightApp/app/main.dev.ts Normal file
View File

@ -0,0 +1,138 @@
/* eslint global-require: off, no-console: off */
/**
* This module executes inside of electron's main process. You can start
* electron renderer process from here and communicate with the other processes
* through IPC.
*
* When running `yarn build` or `yarn build-main`, this file is compiled to
* `./app/main.prod.js` using webpack. This gives us some performance wins.
*/
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import path from 'path';
import { app, BrowserWindow } from 'electron';
import { autoUpdater } from 'electron-updater';
import log from 'electron-log';
import MenuBuilder from './menu';
export default class AppUpdater {
constructor() {
log.transports.file.level = 'info';
autoUpdater.logger = log;
autoUpdater.checkForUpdatesAndNotify();
}
}
let mainWindow: BrowserWindow | null = null;
if (process.env.NODE_ENV === 'production') {
const sourceMapSupport = require('source-map-support');
sourceMapSupport.install();
}
if (
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
) {
require('electron-debug')();
}
const installExtensions = async () => {
const installer = require('electron-devtools-installer');
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
return installer
.default(
extensions.map((name) => installer[name]),
forceDownload
)
.catch(console.log);
};
const createWindow = async () => {
if (
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
) {
await installExtensions();
}
const RESOURCES_PATH = app.isPackaged
? path.join(process.resourcesPath, 'resources')
: path.join(__dirname, '../resources');
const getAssetPath = (...paths: string[]): string => {
return path.join(RESOURCES_PATH, ...paths);
};
mainWindow = new BrowserWindow({
show: false,
width: 1024,
height: 728,
icon: getAssetPath('icon.png'),
webPreferences:
(process.env.NODE_ENV === 'development' ||
process.env.E2E_BUILD === 'true') &&
process.env.ERB_SECURE !== 'true'
? {
nodeIntegration: true,
}
: {
preload: path.join(__dirname, 'dist/renderer.prod.js'),
},
});
mainWindow.setMenuBarVisibility(false);
mainWindow.loadURL(`file://${__dirname}/app.html`);
// @TODO: Use 'ready-to-show' event
// https://github.com/electron/electron/blob/master/docs/api/browser-window.md#using-ready-to-show-event
mainWindow.webContents.on('did-finish-load', () => {
if (!mainWindow) {
throw new Error('"mainWindow" is not defined');
}
if (process.env.START_MINIMIZED) {
mainWindow.minimize();
} else {
mainWindow.show();
mainWindow.focus();
}
});
mainWindow.on('closed', () => {
mainWindow = null;
});
const menuBuilder = new MenuBuilder(mainWindow);
menuBuilder.buildMenu();
// Remove this if your app does not use auto updates
// eslint-disable-next-line
new AppUpdater();
};
/**
* Add event listeners...
*/
app.on('window-all-closed', () => {
// Respect the OSX convention of having the application in memory even
// after all windows have been closed
if (process.platform !== 'darwin') {
app.quit();
}
});
if (process.env.E2E_BUILD === 'true') {
// eslint-disable-next-line promise/catch-or-return
app.whenReady().then(createWindow);
} else {
app.on('ready', createWindow);
}
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) createWindow();
});

View File

@ -0,0 +1 @@
/*! http://mths.be/fromcodepoint v0.1.0 by @mathias */

View File

@ -0,0 +1 @@
/*! http://mths.be/fromcodepoint v0.1.0 by @mathias */

290
enlightApp/app/menu.ts Normal file
View File

@ -0,0 +1,290 @@
import {
app,
Menu,
shell,
BrowserWindow,
MenuItemConstructorOptions,
} from 'electron';
interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions {
selector?: string;
submenu?: DarwinMenuItemConstructorOptions[] | Menu;
}
export default class MenuBuilder {
mainWindow: BrowserWindow;
constructor(mainWindow: BrowserWindow) {
this.mainWindow = mainWindow;
}
buildMenu(): Menu {
if (
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
) {
this.setupDevelopmentEnvironment();
}
const template =
process.platform === 'darwin'
? this.buildDarwinTemplate()
: this.buildDefaultTemplate();
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
return menu;
}
setupDevelopmentEnvironment(): void {
this.mainWindow.webContents.on('context-menu', (_, props) => {
const { x, y } = props;
Menu.buildFromTemplate([
{
label: 'Inspect element',
click: () => {
this.mainWindow.webContents.inspectElement(x, y);
},
},
]).popup({ window: this.mainWindow });
});
}
buildDarwinTemplate(): MenuItemConstructorOptions[] {
const subMenuAbout: DarwinMenuItemConstructorOptions = {
label: 'Electron',
submenu: [
{
label: 'About ElectronReact',
selector: 'orderFrontStandardAboutPanel:',
},
{ type: 'separator' },
{ label: 'Services', submenu: [] },
{ type: 'separator' },
{
label: 'Hide ElectronReact',
accelerator: 'Command+H',
selector: 'hide:',
},
{
label: 'Hide Others',
accelerator: 'Command+Shift+H',
selector: 'hideOtherApplications:',
},
{ label: 'Show All', selector: 'unhideAllApplications:' },
{ type: 'separator' },
{
label: 'Quit',
accelerator: 'Command+Q',
click: () => {
app.quit();
},
},
],
};
const subMenuEdit: DarwinMenuItemConstructorOptions = {
label: 'Edit',
submenu: [
{ label: 'Undo', accelerator: 'Command+Z', selector: 'undo:' },
{ label: 'Redo', accelerator: 'Shift+Command+Z', selector: 'redo:' },
{ type: 'separator' },
{ label: 'Cut', accelerator: 'Command+X', selector: 'cut:' },
{ label: 'Copy', accelerator: 'Command+C', selector: 'copy:' },
{ label: 'Paste', accelerator: 'Command+V', selector: 'paste:' },
{
label: 'Select All',
accelerator: 'Command+A',
selector: 'selectAll:',
},
],
};
const subMenuViewDev: MenuItemConstructorOptions = {
label: 'View',
submenu: [
{
label: 'Reload',
accelerator: 'Command+R',
click: () => {
this.mainWindow.webContents.reload();
},
},
{
label: 'Toggle Full Screen',
accelerator: 'Ctrl+Command+F',
click: () => {
this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
},
},
{
label: 'Toggle Developer Tools',
accelerator: 'Alt+Command+I',
click: () => {
this.mainWindow.webContents.toggleDevTools();
},
},
],
};
const subMenuViewProd: MenuItemConstructorOptions = {
label: 'View',
submenu: [
{
label: 'Toggle Full Screen',
accelerator: 'Ctrl+Command+F',
click: () => {
this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
},
},
],
};
const subMenuWindow: DarwinMenuItemConstructorOptions = {
label: 'Window',
submenu: [
{
label: 'Minimize',
accelerator: 'Command+M',
selector: 'performMiniaturize:',
},
{ label: 'Close', accelerator: 'Command+W', selector: 'performClose:' },
{ type: 'separator' },
{ label: 'Bring All to Front', selector: 'arrangeInFront:' },
],
};
const subMenuHelp: MenuItemConstructorOptions = {
label: 'Help',
submenu: [
{
label: 'Learn More',
click() {
shell.openExternal('https://electronjs.org');
},
},
{
label: 'Documentation',
click() {
shell.openExternal(
'https://github.com/electron/electron/tree/master/docs#readme'
);
},
},
{
label: 'Community Discussions',
click() {
shell.openExternal('https://www.electronjs.org/community');
},
},
{
label: 'Search Issues',
click() {
shell.openExternal('https://github.com/electron/electron/issues');
},
},
],
};
const subMenuView =
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
? subMenuViewDev
: subMenuViewProd;
return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp];
}
buildDefaultTemplate() {
const templateDefault = [
{
label: '&File',
submenu: [
{
label: '&Open',
accelerator: 'Ctrl+O',
},
{
label: '&Close',
accelerator: 'Ctrl+W',
click: () => {
this.mainWindow.close();
},
},
],
},
{
label: '&View',
submenu:
process.env.NODE_ENV === 'development' ||
process.env.DEBUG_PROD === 'true'
? [
{
label: '&Reload',
accelerator: 'Ctrl+R',
click: () => {
this.mainWindow.webContents.reload();
},
},
{
label: 'Toggle &Full Screen',
accelerator: 'F11',
click: () => {
this.mainWindow.setFullScreen(
!this.mainWindow.isFullScreen()
);
},
},
{
label: 'Toggle &Developer Tools',
accelerator: 'Alt+Ctrl+I',
click: () => {
this.mainWindow.webContents.toggleDevTools();
},
},
]
: [
{
label: 'Toggle &Full Screen',
accelerator: 'F11',
click: () => {
this.mainWindow.setFullScreen(
!this.mainWindow.isFullScreen()
);
},
},
],
},
{
label: 'Help',
submenu: [
{
label: 'Learn More',
click() {
shell.openExternal('https://electronjs.org');
},
},
{
label: 'Documentation',
click() {
shell.openExternal(
'https://github.com/electron/electron/tree/master/docs#readme'
);
},
},
{
label: 'Community Discussions',
click() {
shell.openExternal('https://www.electronjs.org/community');
},
},
{
label: 'Search Issues',
click() {
shell.openExternal('https://github.com/electron/electron/issues');
},
},
],
},
];
return templateDefault;
}
}

View File

@ -0,0 +1,18 @@
{
"name": "electron-react-boilerplate",
"productName": "electron-react-boilerplate",
"version": "1.4.0",
"description": "Electron application boilerplate based on React, React Router, Webpack, React Hot Loader for rapid application development",
"main": "./main.prod.js",
"author": {
"name": "Electron React Boilerplate Maintainers",
"email": "electronreactboilerplate@gmail.com",
"url": "https://github.com/electron-react-boilerplate"
},
"scripts": {
"electron-rebuild": "node -r ../internals/scripts/BabelRegister.js ../internals/scripts/ElectronRebuild.js",
"postinstall": "yarn electron-rebuild"
},
"license": "MIT",
"dependencies": {}
}

View File

@ -0,0 +1,12 @@
import { combineReducers } from 'redux';
import { connectRouter } from 'connected-react-router';
import { History } from 'history';
// eslint-disable-next-line import/no-cycle
import counterReducer from './features/counter/counterSlice';
export default function createRootReducer(history: History) {
return combineReducers({
router: connectRouter(history),
counter: counterReducer,
});
}

47
enlightApp/app/store.ts Normal file
View File

@ -0,0 +1,47 @@
import { configureStore, getDefaultMiddleware, Action } from '@reduxjs/toolkit';
import { createHashHistory } from 'history';
import { routerMiddleware } from 'connected-react-router';
import { createLogger } from 'redux-logger';
import { ThunkAction } from 'redux-thunk';
// eslint-disable-next-line import/no-cycle
import createRootReducer from './rootReducer';
export const history = createHashHistory();
const rootReducer = createRootReducer(history);
export type RootState = ReturnType<typeof rootReducer>;
const router = routerMiddleware(history);
const middleware = [...getDefaultMiddleware(), router];
const excludeLoggerEnvs = ['test', 'production'];
const shouldIncludeLogger = !excludeLoggerEnvs.includes(
process.env.NODE_ENV || ''
);
if (shouldIncludeLogger) {
const logger = createLogger({
level: 'info',
collapsed: true,
});
middleware.push(logger);
}
export const configuredStore = (initialState?: RootState) => {
// Create Store
const store = configureStore({
reducer: rootReducer,
middleware,
preloadedState: initialState,
});
if (process.env.NODE_ENV === 'development' && module.hot) {
module.hot.accept(
'./rootReducer',
// eslint-disable-next-line global-require
() => store.replaceReducer(require('./rootReducer').default)
);
}
return store;
};
export type Store = ReturnType<typeof configuredStore>;
export type AppThunk = ThunkAction<void, RootState, unknown, Action<string>>;

View File

4
enlightApp/app/yarn.lock Normal file
View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

View File

@ -0,0 +1,65 @@
/* eslint global-require: off, import/no-extraneous-dependencies: off */
const developmentEnvironments = ['development', 'test'];
const developmentPlugins = [
require('react-hot-loader/babel'),
require('@babel/plugin-transform-runtime'),
];
const productionPlugins = [
require('babel-plugin-dev-expression'),
// babel-preset-react-optimize
require('@babel/plugin-transform-react-constant-elements'),
require('@babel/plugin-transform-react-inline-elements'),
require('babel-plugin-transform-react-remove-prop-types'),
];
module.exports = (api) => {
// See docs about api at https://babeljs.io/docs/en/config-files#apicache
const development = api.env(developmentEnvironments);
return {
presets: [
// @babel/preset-env will automatically target our browserslist targets
require('@babel/preset-env'),
require('@babel/preset-typescript'),
[require('@babel/preset-react'), { development }],
],
plugins: [
// Stage 0
require('@babel/plugin-proposal-function-bind'),
// Stage 1
require('@babel/plugin-proposal-export-default-from'),
require('@babel/plugin-proposal-logical-assignment-operators'),
[require('@babel/plugin-proposal-optional-chaining'), { loose: false }],
[
require('@babel/plugin-proposal-pipeline-operator'),
{ proposal: 'minimal' },
],
[
require('@babel/plugin-proposal-nullish-coalescing-operator'),
{ loose: false },
],
require('@babel/plugin-proposal-do-expressions'),
// Stage 2
[require('@babel/plugin-proposal-decorators'), { legacy: true }],
require('@babel/plugin-proposal-function-sent'),
require('@babel/plugin-proposal-export-namespace-from'),
require('@babel/plugin-proposal-numeric-separator'),
require('@babel/plugin-proposal-throw-expressions'),
// Stage 3
require('@babel/plugin-syntax-dynamic-import'),
require('@babel/plugin-syntax-import-meta'),
[require('@babel/plugin-proposal-class-properties'), { loose: true }],
require('@babel/plugin-proposal-json-strings'),
...(development ? developmentPlugins : productionPlugins),
],
};
};

View File

@ -0,0 +1,7 @@
{
"rules": {
"no-console": "off",
"global-require": "off",
"import/no-dynamic-require": "off"
}
}

View File

@ -0,0 +1,50 @@
/**
* Base webpack config used across other specific configs
*/
import path from 'path';
import webpack from 'webpack';
import { dependencies as externals } from '../app/package.json';
export default {
externals: [...Object.keys(externals || {})],
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
},
},
},
],
},
output: {
path: path.join(__dirname, '..', 'app'),
// https://github.com/webpack/webpack/issues/1114
libraryTarget: 'commonjs2',
},
/**
* Determine the array of extensions that should be used to resolve modules.
*/
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
modules: [path.join(__dirname, '..', 'app'), 'node_modules'],
},
optimization: {
namedModules: true,
},
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: 'production',
}),
],
};

View File

@ -0,0 +1,4 @@
/* eslint import/no-unresolved: off, import/no-self-import: off */
require('@babel/register');
module.exports = require('./webpack.config.renderer.dev.babel').default;

View File

@ -0,0 +1,76 @@
/**
* Webpack config for production electron main process
*/
import path from 'path';
import webpack from 'webpack';
import { merge } from 'webpack-merge';
import TerserPlugin from 'terser-webpack-plugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import baseConfig from './webpack.config.base';
import CheckNodeEnv from '../internals/scripts/CheckNodeEnv';
import DeleteSourceMaps from '../internals/scripts/DeleteSourceMaps';
CheckNodeEnv('production');
DeleteSourceMaps();
export default merge(baseConfig, {
devtool: process.env.DEBUG_PROD === 'true' ? 'source-map' : 'none',
mode: 'production',
target: 'electron-main',
entry: './app/main.dev.ts',
output: {
path: path.join(__dirname, '..'),
filename: './app/main.prod.js',
},
optimization: {
minimizer: process.env.E2E_BUILD
? []
: [
new TerserPlugin({
parallel: true,
sourceMap: true,
cache: true,
}),
],
},
plugins: [
new BundleAnalyzerPlugin({
analyzerMode:
process.env.OPEN_ANALYZER === 'true' ? 'server' : 'disabled',
openAnalyzer: process.env.OPEN_ANALYZER === 'true',
}),
/**
* Create global constants which can be configured at compile time.
*
* Useful for allowing different behaviour between development builds and
* release builds
*
* NODE_ENV should be production so that modules do not perform certain
* development checks
*/
new webpack.EnvironmentPlugin({
NODE_ENV: 'production',
DEBUG_PROD: false,
START_MINIMIZED: false,
E2E_BUILD: false,
}),
],
/**
* Disables webpack processing of __dirname and __filename.
* If you run the bundle in node.js it falls back to these values of node.js.
* https://github.com/webpack/webpack/issues/2010
*/
node: {
__dirname: false,
__filename: false,
},
});

View File

@ -0,0 +1,276 @@
/**
* Build config for development electron renderer process that uses
* Hot-Module-Replacement
*
* https://webpack.js.org/concepts/hot-module-replacement/
*/
import path from 'path';
import fs from 'fs';
import webpack from 'webpack';
import chalk from 'chalk';
import { merge } from 'webpack-merge';
import { spawn, execSync } from 'child_process';
import baseConfig from './webpack.config.base';
import CheckNodeEnv from '../internals/scripts/CheckNodeEnv';
// When an ESLint server is running, we can't set the NODE_ENV so we'll check if it's
// at the dev webpack config is not accidentally run in a production environment
if (process.env.NODE_ENV === 'production') {
CheckNodeEnv('development');
}
const port = process.env.PORT || 1212;
const publicPath = `http://localhost:${port}/dist`;
const dll = path.join(__dirname, '..', 'dll');
const manifest = path.resolve(dll, 'renderer.json');
const requiredByDLLConfig = module.parent.filename.includes(
'webpack.config.renderer.dev.dll'
);
/**
* Warn if the DLL is not built
*/
if (!requiredByDLLConfig && !(fs.existsSync(dll) && fs.existsSync(manifest))) {
console.log(
chalk.black.bgYellow.bold(
'The DLL files are missing. Sit back while we build them for you with "yarn build-dll"'
)
);
execSync('yarn build-dll');
}
export default merge(baseConfig, {
devtool: 'inline-source-map',
mode: 'development',
target: 'electron-renderer',
entry: [
'core-js',
'regenerator-runtime/runtime',
...(process.env.PLAIN_HMR ? [] : ['react-hot-loader/patch']),
`webpack-dev-server/client?http://localhost:${port}/`,
'webpack/hot/only-dev-server',
require.resolve('../app/index.tsx'),
],
output: {
publicPath: `http://localhost:${port}/dist/`,
filename: 'renderer.dev.js',
},
module: {
rules: [
{
test: /\.global\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: /^((?!\.global).)*\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]',
},
sourceMap: true,
importLoaders: 1,
},
},
],
},
// SASS support - compile all .global.scss files and pipe it to style.css
{
test: /\.global\.(scss|sass)$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
},
],
},
// SASS support - compile all other .scss files and pipe it to style.css
{
test: /^((?!\.global).)*\.(scss|sass)$/,
use: [
{
loader: 'style-loader',
},
{
loader: '@teamsupercell/typings-for-css-modules-loader',
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]',
},
sourceMap: true,
importLoaders: 1,
},
},
{
loader: 'sass-loader',
},
],
},
// WOFF Font
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
},
},
},
// WOFF2 Font
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
},
},
},
// TTF Font
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream',
},
},
},
// EOT Font
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader',
},
// SVG Font
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'image/svg+xml',
},
},
},
// Common Image Formats
{
test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
use: 'url-loader',
},
],
},
resolve: {
alias: {
'react-dom': '@hot-loader/react-dom',
},
},
plugins: [
requiredByDLLConfig
? null
: new webpack.DllReferencePlugin({
context: path.join(__dirname, '..', 'dll'),
manifest: require(manifest),
sourceType: 'var',
}),
new webpack.HotModuleReplacementPlugin({
multiStep: true,
}),
new webpack.NoEmitOnErrorsPlugin(),
/**
* Create global constants which can be configured at compile time.
*
* Useful for allowing different behaviour between development builds and
* release builds
*
* NODE_ENV should be production so that modules do not perform certain
* development checks
*
* By default, use 'development' as NODE_ENV. This can be overriden with
* 'staging', for example, by changing the ENV variables in the npm scripts
*/
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
}),
new webpack.LoaderOptionsPlugin({
debug: true,
}),
],
node: {
__dirname: false,
__filename: false,
},
devServer: {
port,
publicPath,
compress: true,
noInfo: false,
stats: 'errors-only',
inline: true,
lazy: false,
hot: true,
headers: { 'Access-Control-Allow-Origin': '*' },
contentBase: path.join(__dirname, 'dist'),
watchOptions: {
aggregateTimeout: 300,
ignored: /node_modules/,
poll: 100,
},
historyApiFallback: {
verbose: true,
disableDotRule: false,
},
before() {
if (process.env.START_HOT) {
console.log('Starting Main Process...');
spawn('npm', ['run', 'start-main-dev'], {
shell: true,
env: process.env,
stdio: 'inherit',
})
.on('close', (code) => process.exit(code))
.on('error', (spawnError) => console.error(spawnError));
}
},
},
});

View File

@ -0,0 +1,72 @@
/**
* Builds the DLL for development electron renderer process
*/
import webpack from 'webpack';
import path from 'path';
import { merge } from 'webpack-merge';
import baseConfig from './webpack.config.base';
import { dependencies } from '../package.json';
import CheckNodeEnv from '../internals/scripts/CheckNodeEnv';
CheckNodeEnv('development');
const dist = path.join(__dirname, '..', 'dll');
export default merge(baseConfig, {
context: path.join(__dirname, '..'),
devtool: 'eval',
mode: 'development',
target: 'electron-renderer',
externals: ['fsevents', 'crypto-browserify'],
/**
* Use `module` from `webpack.config.renderer.dev.js`
*/
module: require('./webpack.config.renderer.dev.babel').default.module,
entry: {
renderer: Object.keys(dependencies || {}),
},
output: {
library: 'renderer',
path: dist,
filename: '[name].dev.dll.js',
libraryTarget: 'var',
},
plugins: [
new webpack.DllPlugin({
path: path.join(dist, '[name].json'),
name: '[name]',
}),
/**
* Create global constants which can be configured at compile time.
*
* Useful for allowing different behaviour between development builds and
* release builds
*
* NODE_ENV should be production so that modules do not perform certain
* development checks
*/
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
}),
new webpack.LoaderOptionsPlugin({
debug: true,
options: {
context: path.join(__dirname, '..', 'app'),
output: {
path: path.join(__dirname, '..', 'dll'),
},
},
}),
],
});

View File

@ -0,0 +1,229 @@
/**
* Build config for electron renderer process
*/
import path from 'path';
import webpack from 'webpack';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import OptimizeCSSAssetsPlugin from 'optimize-css-assets-webpack-plugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import { merge } from 'webpack-merge';
import TerserPlugin from 'terser-webpack-plugin';
import baseConfig from './webpack.config.base';
import CheckNodeEnv from '../internals/scripts/CheckNodeEnv';
import DeleteSourceMaps from '../internals/scripts/DeleteSourceMaps';
CheckNodeEnv('production');
DeleteSourceMaps();
export default merge(baseConfig, {
devtool: process.env.DEBUG_PROD === 'true' ? 'source-map' : 'none',
mode: 'production',
target:
process.env.E2E_BUILD || process.env.ERB_SECURE !== 'true'
? 'electron-renderer'
: 'electron-preload',
entry: [
'core-js',
'regenerator-runtime/runtime',
path.join(__dirname, '..', 'app/index.tsx'),
],
output: {
path: path.join(__dirname, '..', 'app/dist'),
publicPath: './dist/',
filename: 'renderer.prod.js',
},
module: {
rules: [
// Extract all .global.css to style.css as is
{
test: /\.global\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: './',
},
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
],
},
// Pipe other styles through css modules and append to style.css
{
test: /^((?!\.global).)*\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]',
},
sourceMap: true,
},
},
],
},
// Add SASS support - compile all .global.scss files and pipe it to style.css
{
test: /\.global\.(scss|sass)$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 1,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
// Add SASS support - compile all other .scss files and pipe it to style.css
{
test: /^((?!\.global).)*\.(scss|sass)$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]',
},
importLoaders: 1,
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
// WOFF Font
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
},
},
},
// WOFF2 Font
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
},
},
},
// TTF Font
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream',
},
},
},
// EOT Font
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader',
},
// SVG Font
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'image/svg+xml',
},
},
},
// Common Image Formats
{
test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
use: 'url-loader',
},
],
},
optimization: {
minimizer: process.env.E2E_BUILD
? []
: [
new TerserPlugin({
parallel: true,
sourceMap: true,
cache: true,
}),
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
map: {
inline: false,
annotation: true,
},
},
}),
],
},
plugins: [
/**
* Create global constants which can be configured at compile time.
*
* Useful for allowing different behaviour between development builds and
* release builds
*
* NODE_ENV should be production so that modules do not perform certain
* development checks
*/
new webpack.EnvironmentPlugin({
NODE_ENV: 'production',
DEBUG_PROD: false,
E2E_BUILD: false,
}),
new MiniCssExtractPlugin({
filename: 'style.css',
}),
new BundleAnalyzerPlugin({
analyzerMode:
process.env.OPEN_ANALYZER === 'true' ? 'server' : 'disabled',
openAnalyzer: process.env.OPEN_ANALYZER === 'true',
}),
],
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1 @@
export default 'test-file-stub';

View File

@ -0,0 +1,8 @@
{
"rules": {
"no-console": "off",
"global-require": "off",
"import/no-dynamic-require": "off",
"import/no-extraneous-dependencies": "off"
}
}

View File

@ -0,0 +1,6 @@
const path = require('path');
require('@babel/register')({
extensions: ['.es6', '.es', '.jsx', '.js', '.mjs', '.ts', '.tsx'],
cwd: path.join(__dirname, '..', '..'),
});

View File

@ -0,0 +1,30 @@
// Check if the renderer and main bundles are built
import path from 'path';
import chalk from 'chalk';
import fs from 'fs';
const mainPath = path.join(__dirname, '..', '..', 'app', 'main.prod.js');
const rendererPath = path.join(
__dirname,
'..',
'..',
'app',
'dist',
'renderer.prod.js'
);
if (!fs.existsSync(mainPath)) {
throw new Error(
chalk.whiteBright.bgRed.bold(
'The main process is not built yet. Build it by running "yarn build-main"'
)
);
}
if (!fs.existsSync(rendererPath)) {
throw new Error(
chalk.whiteBright.bgRed.bold(
'The renderer process is not built yet. Build it by running "yarn build-renderer"'
)
);
}

View File

@ -0,0 +1,49 @@
import fs from 'fs';
import chalk from 'chalk';
import { execSync } from 'child_process';
import { dependencies } from '../../package.json';
if (dependencies) {
const dependenciesKeys = Object.keys(dependencies);
const nativeDeps = fs
.readdirSync('node_modules')
.filter((folder) => fs.existsSync(`node_modules/${folder}/binding.gyp`));
try {
// Find the reason for why the dependency is installed. If it is installed
// because of a devDependency then that is okay. Warn when it is installed
// because of a dependency
const { dependencies: dependenciesObject } = JSON.parse(
execSync(`npm ls ${nativeDeps.join(' ')} --json`).toString()
);
const rootDependencies = Object.keys(dependenciesObject);
const filteredRootDependencies = rootDependencies.filter((rootDependency) =>
dependenciesKeys.includes(rootDependency)
);
if (filteredRootDependencies.length > 0) {
const plural = filteredRootDependencies.length > 1;
console.log(`
${chalk.whiteBright.bgYellow.bold(
'Webpack does not work with native dependencies.'
)}
${chalk.bold(filteredRootDependencies.join(', '))} ${
plural ? 'are native dependencies' : 'is a native dependency'
} and should be installed inside of the "./app" folder.
First, uninstall the packages from "./package.json":
${chalk.whiteBright.bgGreen.bold('yarn remove your-package')}
${chalk.bold(
'Then, instead of installing the package to the root "./package.json":'
)}
${chalk.whiteBright.bgRed.bold('yarn add your-package')}
${chalk.bold('Install the package to "./app/package.json"')}
${chalk.whiteBright.bgGreen.bold('cd ./app && yarn add your-package')}
Read more about native dependencies at:
${chalk.bold(
'https://electron-react-boilerplate.js.org/docs/adding-dependencies/#module-structure'
)}
`);
process.exit(1);
}
} catch (e) {
console.log('Native dependencies could not be checked');
}
}

View File

@ -0,0 +1,16 @@
import chalk from 'chalk';
export default function CheckNodeEnv(expectedEnv) {
if (!expectedEnv) {
throw new Error('"expectedEnv" not set');
}
if (process.env.NODE_ENV !== expectedEnv) {
console.log(
chalk.whiteBright.bgRed.bold(
`"process.env.NODE_ENV" must be "${expectedEnv}" to use this webpack config`
)
);
process.exit(2);
}
}

View File

@ -0,0 +1,16 @@
import chalk from 'chalk';
import detectPort from 'detect-port';
const port = process.env.PORT || '1212';
detectPort(port, (err, availablePort) => {
if (port !== String(availablePort)) {
throw new Error(
chalk.whiteBright.bgRed.bold(
`Port "${port}" on "localhost" is already in use. Please use another port. ex: PORT=4343 yarn start`
)
);
} else {
process.exit(0);
}
});

View File

@ -0,0 +1,5 @@
if (!/yarn\.js$/.test(process.env.npm_execpath || '')) {
console.warn(
"\u001b[33mYou don't seem to be using yarn. This could produce unexpected results.\u001b[39m"
);
}

View File

@ -0,0 +1,7 @@
import path from 'path';
import rimraf from 'rimraf';
export default function deleteSourceMaps() {
rimraf.sync(path.join(__dirname, '../../app/dist/*.js.map'));
rimraf.sync(path.join(__dirname, '../../app/*.js.map'));
}

View File

@ -0,0 +1,22 @@
import path from 'path';
import { execSync } from 'child_process';
import fs from 'fs';
import { dependencies } from '../../app/package.json';
const nodeModulesPath = path.join(__dirname, '..', '..', 'app', 'node_modules');
if (
Object.keys(dependencies || {}).length > 0 &&
fs.existsSync(nodeModulesPath)
) {
const electronRebuildCmd =
'../node_modules/.bin/electron-rebuild --parallel --force --types prod,dev,optional --module-dir .';
const cmd =
process.platform === 'win32'
? electronRebuildCmd.replace(/\//g, '\\')
: electronRebuildCmd;
execSync(cmd, {
cwd: path.join(__dirname, '..', '..', 'app'),
stdio: 'inherit',
});
}

340
enlightApp/package.json Normal file
View File

@ -0,0 +1,340 @@
{
"name": "electron-react-boilerplate",
"productName": "ElectronReact",
"description": "Electron application boilerplate based on React, React Router, Webpack, React Hot Loader for rapid application development",
"scripts": {
"build": "concurrently \"yarn build-main\" \"yarn build-renderer\"",
"build-dll": "cross-env NODE_ENV=development webpack --config ./configs/webpack.config.renderer.dev.dll.babel.js --colors",
"build-e2e": "cross-env E2E_BUILD=true yarn build",
"build-main": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.main.prod.babel.js --colors",
"build-renderer": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.renderer.prod.babel.js --colors",
"electron-rebuild": "electron-rebuild --parallel --force --types prod,dev,optional --module-dir app",
"lint": "cross-env NODE_ENV=development eslint . --cache --ext .js,.jsx,.ts,.tsx",
"lint-fix": "yarn --silent lint --fix; exit 0",
"lint-styles": "stylelint --ignore-path .eslintignore '**/*.*(css|scss)' --syntax scss",
"lint-styles-fix": "yarn --silent lint-styles --fix; exit 0",
"package": "yarn build && electron-builder build --publish never",
"package-all": "yarn build && electron-builder build -mwl",
"package-ci": "yarn postinstall && yarn build && electron-builder --publish always",
"package-mac": "yarn build && electron-builder build --mac",
"package-linux": "yarn build && electron-builder build --linux",
"package-win": "yarn build && electron-builder build --win --x64",
"postinstall": "node -r @babel/register internals/scripts/CheckNativeDep.js && electron-builder install-app-deps && yarn build-dll && opencollective-postinstall",
"postlint-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{js,jsx,json,html,css,less,scss,yml}'",
"postlint-styles-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{css,scss}'",
"preinstall": "node ./internals/scripts/CheckYarn.js",
"prestart": "yarn build",
"start": "cross-env START_HOT=1 node -r @babel/register ./internals/scripts/CheckPortInUse.js && cross-env START_HOT=1 yarn start-renderer-dev",
"start:prod": "cross-env NODE_ENV=production electron ./app/main.prod.js",
"start-main-debug": "yarn start-main-dev --inspect=5858 --remote-debugging-port=9223",
"start-main-dev": "cross-env START_HOT=1 NODE_ENV=development electron -r ./internals/scripts/BabelRegister ./app/main.dev.ts",
"start-renderer-dev": "cross-env NODE_ENV=development webpack-dev-server --config configs/webpack.config.renderer.dev.babel.js",
"test": "cross-env BABEL_DISABLE_CACHE=1 jest",
"test-all": "yarn lint && yarn tsc && yarn build && yarn test",
"test-e2e": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test testcafe electron:./app ./test/e2e/HomePage.e2e.ts",
"test-e2e-live": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test testcafe --live electron:./app ./test/e2e/HomePage.e2e.ts",
"test-watch": "yarn test --watch"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"cross-env NODE_ENV=development eslint --cache"
],
"{*.json,.{babelrc,eslintrc,prettierrc,stylelintrc}}": [
"prettier --ignore-path .eslintignore --parser json --write"
],
"*.{css,scss}": [
"stylelint --ignore-path .eslintignore --syntax scss --fix",
"prettier --ignore-path .eslintignore --single-quote --write"
],
"*.{html,md,yml}": [
"prettier --ignore-path .eslintignore --single-quote --write"
]
},
"build": {
"productName": "ElectronReact",
"appId": "org.develar.ElectronReact",
"files": [
"dist/",
"node_modules/",
"app.html",
"main.prod.js",
"main.prod.js.map",
"package.json"
],
"dmg": {
"contents": [
{
"x": 130,
"y": 220
},
{
"x": 410,
"y": 220,
"type": "link",
"path": "/Applications"
}
]
},
"win": {
"target": [
"nsis",
"msi"
]
},
"linux": {
"target": [
"deb",
"rpm",
"AppImage"
],
"category": "Development"
},
"directories": {
"buildResources": "resources",
"output": "release"
},
"extraResources": [
"./resources/**"
],
"publish": {
"provider": "github",
"owner": "electron-react-boilerplate",
"repo": "electron-react-boilerplate",
"private": false
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/electron-react-boilerplate/electron-react-boilerplate.git"
},
"author": {
"name": "Electron React Boilerplate Maintainers",
"email": "electronreactboilerplate@gmail.com",
"url": "https://electron-react-boilerplate.js.org"
},
"contributors": [
{
"name": "Vikram Rangaraj",
"email": "vikr01@icloud.com",
"url": "https://github.com/vikr01"
},
{
"name": "Amila Welihinda",
"email": "amilajack@gmail.com",
"url": "https://github.com/amilajack"
},
{
"name": "John Tran",
"email": "jptran318@gmail.com",
"url": "https://github.com/jooohhn"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues"
},
"keywords": [
"electron",
"boilerplate",
"react",
"redux",
"typescript",
"ts",
"sass",
"webpack",
"hot",
"reload"
],
"homepage": "https://github.com/electron-react-boilerplate/electron-react-boilerplate#readme",
"jest": {
"testURL": "http://localhost/",
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/internals/mocks/fileMock.js",
"\\.(css|less|sass|scss)$": "identity-obj-proxy"
},
"moduleFileExtensions": [
"js",
"jsx",
"ts",
"tsx",
"json"
],
"moduleDirectories": [
"node_modules",
"app/node_modules"
],
"setupFiles": [
"./internals/scripts/CheckBuildsExist.js"
]
},
"devDependencies": {
"@amilajack/testcafe-browser-provider-electron": "^0.0.15-alpha.1",
"@babel/core": "^7.12.3",
"@babel/plugin-proposal-class-properties": "^7.12.1",
"@babel/plugin-proposal-decorators": "^7.12.1",
"@babel/plugin-proposal-do-expressions": "^7.12.1",
"@babel/plugin-proposal-export-default-from": "^7.12.1",
"@babel/plugin-proposal-export-namespace-from": "^7.12.1",
"@babel/plugin-proposal-function-bind": "^7.12.1",
"@babel/plugin-proposal-function-sent": "^7.12.1",
"@babel/plugin-proposal-json-strings": "^7.12.1",
"@babel/plugin-proposal-logical-assignment-operators": "^7.12.1",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
"@babel/plugin-proposal-numeric-separator": "^7.12.1",
"@babel/plugin-proposal-optional-chaining": "^7.12.1",
"@babel/plugin-proposal-pipeline-operator": "^7.12.1",
"@babel/plugin-proposal-throw-expressions": "^7.12.1",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/plugin-transform-react-constant-elements": "^7.12.1",
"@babel/plugin-transform-react-inline-elements": "^7.12.1",
"@babel/plugin-transform-runtime": "^7.12.1",
"@babel/preset-env": "^7.12.1",
"@babel/preset-react": "^7.12.1",
"@babel/preset-typescript": "^7.12.1",
"@babel/register": "^7.12.1",
"@teamsupercell/typings-for-css-modules-loader": "^2.4.0",
"@types/enzyme": "^3.10.5",
"@types/enzyme-adapter-react-16": "^1.0.6",
"@types/history": "^4.7.7",
"@types/jest": "^26.0.15",
"@types/node": "12",
"@types/react": "^16.9.44",
"@types/react-dom": "^16.9.9",
"@types/react-redux": "^7.1.9",
"@types/react-router": "^5.1.8",
"@types/react-router-dom": "^5.1.5",
"@types/react-test-renderer": "^16.9.3",
"@types/redux-logger": "^3.0.8",
"@types/webpack": "^4.41.21",
"@types/webpack-env": "^1.15.2",
"@typescript-eslint/eslint-plugin": "^3.6.1",
"@typescript-eslint/parser": "^3.6.1",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.1.0",
"babel-loader": "^8.1.0",
"babel-plugin-dev-expression": "^0.2.2",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"browserslist-config-erb": "^0.0.1",
"chalk": "^4.1.0",
"concurrently": "^5.3.0",
"core-js": "^3.6.5",
"cross-env": "^7.0.2",
"css-loader": "^3.6.0",
"detect-port": "^1.3.0",
"electron": "^8",
"electron-builder": "^22.3.6",
"electron-devtools-installer": "^2.2.4",
"electron-rebuild": "^1.10.0",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.3",
"enzyme-to-json": "^3.5.0",
"eslint": "^7.5.0",
"eslint-config-airbnb": "^18.2.0",
"eslint-config-airbnb-typescript": "^9.0.0",
"eslint-config-erb": "^2.0.0",
"eslint-config-prettier": "^6.11.0",
"eslint-import-resolver-webpack": "^0.12.2",
"eslint-plugin-compat": "^3.8.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-jest": "^23.18.0",
"eslint-plugin-jsx-a11y": "6.3.1",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.20.6",
"eslint-plugin-react-hooks": "^4.0.8",
"eslint-plugin-testcafe": "^0.2.1",
"file-loader": "^6.0.0",
"husky": "^4.2.5",
"identity-obj-proxy": "^3.0.0",
"jest": "^26.1.0",
"lint-staged": "^10.2.11",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.14.1",
"opencollective-postinstall": "^2.0.3",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"prettier": "^2.0.5",
"react-test-renderer": "^16.12.0",
"redux-logger": "^3.0.6",
"rimraf": "^3.0.0",
"sass-loader": "^9.0.3",
"style-loader": "^1.2.1",
"stylelint": "^13.6.1",
"stylelint-config-prettier": "^8.0.2",
"stylelint-config-standard": "^20.0.0",
"terser-webpack-plugin": "^3.0.7",
"testcafe": "^1.8.8",
"testcafe-browser-provider-electron": "^0.0.15",
"testcafe-react-selectors": "^4.0.0",
"typescript": "^3.9.7",
"url-loader": "^4.1.0",
"webpack": "^4.43.0",
"webpack-bundle-analyzer": "^3.8.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^5.0.9"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^5.15.0",
"@hot-loader/react-dom": "^16.13.0",
"@reduxjs/toolkit": "^1.4.0",
"connected-react-router": "^6.6.1",
"electron-debug": "^3.1.0",
"electron-log": "^4.2.4",
"electron-updater": "^4.3.4",
"history": "^4.7.2",
"react": "^16.13.1",
"react-dom": "^16.12.0",
"react-hot-loader": "^4.12.21",
"react-redux": "^7.2.1",
"react-router-dom": "^5.2.0",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"regenerator-runtime": "^0.13.5",
"source-map-support": "^0.5.19"
},
"devEngines": {
"node": ">=7.x",
"npm": ">=4.x",
"yarn": ">=0.21.3"
},
"collective": {
"url": "https://opencollective.com/electron-react-boilerplate-594"
},
"browserslist": [],
"prettier": {
"overrides": [
{
"files": [
".prettierrc",
".babelrc",
".eslintrc",
".stylelintrc"
],
"options": {
"parser": "json"
}
}
],
"singleQuote": true
},
"stylelint": {
"extends": [
"stylelint-config-standard",
"stylelint-config-prettier"
]
},
"renovate": {
"extends": [
"bliss"
],
"baseBranches": [
"next"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Some files were not shown because too many files have changed in this diff Show More