├── .erb
├── mocks
│ └── fileMock.js
├── img
│ ├── erb-logo.png
│ └── erb-banner.png
├── configs
│ ├── .eslintrc
│ ├── webpack.config.eslint.ts
│ ├── postcss.config.js
│ ├── webpack.config.base.ts
│ ├── webpack.paths.ts
│ ├── webpack.config.renderer.dev.dll.ts
│ ├── webpack.config.main.prod.ts
│ ├── webpack.config.renderer.prod.ts
│ └── webpack.config.renderer.dev.ts
└── scripts
│ ├── .eslintrc
│ ├── link-modules.js
│ ├── delete-source-maps.js
│ ├── check-node-env.js
│ ├── clean.js
│ ├── check-port-in-use.js
│ ├── electron-rebuild.js
│ ├── check-build-exists.ts
│ ├── notarize.js
│ └── check-native-dep.js
├── assets
├── icon.icns
├── icon.ico
├── icon.png
├── icons
│ ├── 16x16.png
│ ├── 24x24.png
│ ├── 32x32.png
│ ├── 48x48.png
│ ├── 64x64.png
│ ├── 96x96.png
│ ├── 1024x1024.png
│ ├── 128x128.png
│ ├── 256x256.png
│ └── 512x512.png
├── assets.d.ts
├── entitlements.mac.plist
└── icon.svg
├── .vscode
├── extensions.json
├── settings.json
├── tasks.json
└── launch.json
├── src
├── renderer
│ ├── index.tsx
│ ├── index.ejs
│ ├── App.css
│ └── App.tsx
├── __tests__
│ └── App.test.tsx
└── main
│ ├── util.ts
│ ├── preload.js
│ ├── main.ts
│ └── menu.ts
├── .github
├── config.yml
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── 3-Feature_request.md
│ ├── 2-Question.md
│ └── 1-Bug_report.md
├── stale.yml
└── workflows
│ ├── test.yml
│ └── publish.yml
├── .editorconfig
├── .gitattributes
├── README.md
├── release
└── app
│ ├── package-lock.json
│ └── package.json
├── tailwind.config.js
├── .gitignore
├── .eslintignore
├── tsconfig.json
├── .eslintrc.js
├── LICENSE
├── CODE_OF_CONDUCT.md
├── package.json
└── CHANGELOG.md
/.erb/mocks/fileMock.js:
--------------------------------------------------------------------------------
1 | export default 'test-file-stub';
2 |
--------------------------------------------------------------------------------
/assets/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icon.icns
--------------------------------------------------------------------------------
/assets/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icon.ico
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icon.png
--------------------------------------------------------------------------------
/.erb/img/erb-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/.erb/img/erb-logo.png
--------------------------------------------------------------------------------
/.erb/img/erb-banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/.erb/img/erb-banner.png
--------------------------------------------------------------------------------
/assets/icons/16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icons/16x16.png
--------------------------------------------------------------------------------
/assets/icons/24x24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icons/24x24.png
--------------------------------------------------------------------------------
/assets/icons/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icons/32x32.png
--------------------------------------------------------------------------------
/assets/icons/48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icons/48x48.png
--------------------------------------------------------------------------------
/assets/icons/64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icons/64x64.png
--------------------------------------------------------------------------------
/assets/icons/96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icons/96x96.png
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["dbaeumer.vscode-eslint", "EditorConfig.EditorConfig"]
3 | }
4 |
--------------------------------------------------------------------------------
/assets/icons/1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icons/1024x1024.png
--------------------------------------------------------------------------------
/assets/icons/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icons/128x128.png
--------------------------------------------------------------------------------
/assets/icons/256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icons/256x256.png
--------------------------------------------------------------------------------
/assets/icons/512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amilajack/erb-tailwind-example/HEAD/assets/icons/512x512.png
--------------------------------------------------------------------------------
/src/renderer/index.tsx:
--------------------------------------------------------------------------------
1 | import { render } from 'react-dom';
2 | import App from './App';
3 |
4 | render(, document.getElementById('root'));
5 |
--------------------------------------------------------------------------------
/.github/config.yml:
--------------------------------------------------------------------------------
1 | requiredHeaders:
2 | - Prerequisites
3 | - Expected Behavior
4 | - Current Behavior
5 | - Possible Solution
6 | - Your Environment
7 |
--------------------------------------------------------------------------------
/.erb/configs/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-console": "off",
4 | "global-require": "off",
5 | "import/no-dynamic-require": "off"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.eslint.ts:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved: off, import/no-self-import: off */
2 |
3 | module.exports = require('./webpack.config.renderer.dev').default;
4 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [electron-react-boilerplate, amilajack]
4 | patreon: amilajack
5 | open_collective: electron-react-boilerplate-594
6 |
--------------------------------------------------------------------------------
/.erb/configs/postcss.config.js:
--------------------------------------------------------------------------------
1 | const tailwindcss = require('tailwindcss');
2 | const autoprefixer = require('autoprefixer');
3 |
4 | module.exports = {
5 | plugins: [tailwindcss, autoprefixer],
6 | };
7 |
--------------------------------------------------------------------------------
/.erb/scripts/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-console": "off",
4 | "global-require": "off",
5 | "import/no-dynamic-require": "off",
6 | "import/no-extraneous-dependencies": "off"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 | *.exe binary
3 | *.png binary
4 | *.jpg binary
5 | *.jpeg binary
6 | *.ico binary
7 | *.icns binary
8 | *.eot binary
9 | *.otf binary
10 | *.ttf binary
11 | *.woff binary
12 | *.woff2 binary
13 |
--------------------------------------------------------------------------------
/src/__tests__/App.test.tsx:
--------------------------------------------------------------------------------
1 | import '@testing-library/jest-dom';
2 | import { render } from '@testing-library/react';
3 | import App from '../renderer/App';
4 |
5 | describe('App', () => {
6 | it('should render', () => {
7 | expect(render()).toBeTruthy();
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # erb-tailwind-example
2 |
3 | **See the last commit for the required changes for tailwind integration**
4 |
5 | ## Install
6 |
7 | ```bash
8 | git clone --depth 1 --branch main https://github.com/amilajack/erb-tailwind-example.git your-project-name
9 | cd your-project-name
10 | npm install
11 | ```
12 |
--------------------------------------------------------------------------------
/.erb/scripts/link-modules.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import {
3 | appNodeModulesPath,
4 | srcNodeModulesPath,
5 | } from '../configs/webpack.paths';
6 |
7 | if (!fs.existsSync(srcNodeModulesPath) && fs.existsSync(appNodeModulesPath)) {
8 | fs.symlinkSync(appNodeModulesPath, srcNodeModulesPath, 'junction');
9 | }
10 |
--------------------------------------------------------------------------------
/.erb/scripts/delete-source-maps.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import rimraf from 'rimraf';
3 | import webpackPaths from '../configs/webpack.paths';
4 |
5 | export default function deleteSourceMaps() {
6 | rimraf.sync(path.join(webpackPaths.distMainPath, '*.js.map'));
7 | rimraf.sync(path.join(webpackPaths.distRendererPath, '*.js.map'));
8 | }
9 |
--------------------------------------------------------------------------------
/release/app/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "electron-react-boilerplate",
3 | "version": "4.3.1",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "electron-react-boilerplate",
9 | "version": "4.3.1",
10 | "hasInstallScript": true,
11 | "license": "MIT"
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/assets/assets.d.ts:
--------------------------------------------------------------------------------
1 | /* eslint @typescript-eslint/no-explicit-any: off */
2 |
3 | declare module '*.svg' {
4 | const content: string;
5 | export default content;
6 | }
7 |
8 | declare module '*.png' {
9 | const content: string;
10 | export default content;
11 | }
12 |
13 | declare module '*.jpg' {
14 | const content: string;
15 | export default content;
16 | }
17 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | import colors from 'tailwindcss/colors';
2 |
3 | module.exports = {
4 | purge: [],
5 | darkMode: false, // or 'media' or 'class'
6 | theme: {
7 | extend: {
8 | colors: {
9 | sky: colors.sky,
10 | cyan: colors.cyan,
11 | },
12 | },
13 | },
14 | variants: {
15 | extend: {},
16 | },
17 | plugins: [],
18 | };
19 |
--------------------------------------------------------------------------------
/assets/entitlements.mac.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.cs.allow-unsigned-executable-memory
6 |
7 | com.apple.security.cs.allow-jit
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/renderer/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello Electron React!
6 |
7 |
8 |
9 |
10 |
18 |
19 |
--------------------------------------------------------------------------------
/.erb/scripts/check-node-env.js:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk';
2 |
3 | export default function checkNodeEnv(expectedEnv) {
4 | if (!expectedEnv) {
5 | throw new Error('"expectedEnv" not set');
6 | }
7 |
8 | if (process.env.NODE_ENV !== expectedEnv) {
9 | console.log(
10 | chalk.whiteBright.bgRed.bold(
11 | `"process.env.NODE_ENV" must be "${expectedEnv}" to use this webpack config`
12 | )
13 | );
14 | process.exit(2);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/3-Feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: You want something added to the boilerplate. 🎉
4 | labels: 'enhancement'
5 | ---
6 |
7 |
16 |
--------------------------------------------------------------------------------
/.erb/scripts/clean.js:
--------------------------------------------------------------------------------
1 | import rimraf from 'rimraf';
2 | import webpackPaths from '../configs/webpack.paths.ts';
3 | import process from 'process';
4 |
5 | const args = process.argv.slice(2);
6 | const commandMap = {
7 | dist: webpackPaths.distPath,
8 | release: webpackPaths.releasePath,
9 | dll: webpackPaths.dllPath,
10 | };
11 |
12 | args.forEach((x) => {
13 | const pathToRemove = commandMap[x];
14 | if (pathToRemove !== undefined) {
15 | rimraf.sync(pathToRemove);
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/2-Question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Question
3 | about: Ask a question.❓
4 | labels: 'question'
5 | ---
6 |
7 | ## Summary
8 |
9 |
10 |
11 |
20 |
--------------------------------------------------------------------------------
/.erb/scripts/check-port-in-use.js:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk';
2 | import detectPort from 'detect-port';
3 |
4 | const port = process.env.PORT || '1212';
5 |
6 | detectPort(port, (err, availablePort) => {
7 | if (port !== String(availablePort)) {
8 | throw new Error(
9 | chalk.whiteBright.bgRed.bold(
10 | `Port "${port}" on "localhost" is already in use. Please use another port. ex: PORT=4343 npm start`
11 | )
12 | );
13 | } else {
14 | process.exit(0);
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Coverage directory used by tools like istanbul
11 | coverage
12 | .eslintcache
13 |
14 | # Dependency directory
15 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
16 | node_modules
17 |
18 | # OSX
19 | .DS_Store
20 |
21 | release/app/dist
22 | release/build
23 | .erb/dll
24 |
25 | .idea
26 | npm-debug.log.*
27 | *.css.d.ts
28 | *.sass.d.ts
29 | *.scss.d.ts
30 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Coverage directory used by tools like istanbul
11 | coverage
12 | .eslintcache
13 |
14 | # Dependency directory
15 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
16 | node_modules
17 |
18 | # OSX
19 | .DS_Store
20 |
21 | release/app/dist
22 | release/build
23 | .erb/dll
24 |
25 | .idea
26 | npm-debug.log.*
27 | *.css.d.ts
28 | *.sass.d.ts
29 | *.scss.d.ts
30 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | ".eslintrc": "jsonc",
4 | ".prettierrc": "jsonc",
5 | ".eslintignore": "ignore"
6 | },
7 |
8 | "javascript.validate.enable": false,
9 | "javascript.format.enable": false,
10 | "typescript.format.enable": false,
11 |
12 | "search.exclude": {
13 | ".git": true,
14 | ".eslintcache": true,
15 | ".erb/dll": true,
16 | "release/{build,app/dist}": true,
17 | "node_modules": true,
18 | "npm-debug.log.*": true,
19 | "test/**/__snapshots__": true,
20 | "yarn.lock": true,
21 | "*.{css,sass,scss}.d.ts": true
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/util.ts:
--------------------------------------------------------------------------------
1 | /* eslint import/prefer-default-export: off, import/no-mutable-exports: off */
2 | import { URL } from 'url';
3 | import path from 'path';
4 |
5 | export let resolveHtmlPath: (htmlFileName: string) => string;
6 |
7 | if (process.env.NODE_ENV === 'development') {
8 | const port = process.env.PORT || 1212;
9 | resolveHtmlPath = (htmlFileName: string) => {
10 | const url = new URL(`http://localhost:${port}`);
11 | url.pathname = htmlFileName;
12 | return url.href;
13 | };
14 | } else {
15 | resolveHtmlPath = (htmlFileName: string) => {
16 | return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`;
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "type": "npm",
6 | "label": "Start Webpack Dev",
7 | "script": "start:renderer",
8 | "options": {
9 | "cwd": "${workspaceFolder}"
10 | },
11 | "isBackground": true,
12 | "problemMatcher": {
13 | "owner": "custom",
14 | "pattern": {
15 | "regexp": "____________"
16 | },
17 | "background": {
18 | "activeOnStart": true,
19 | "beginsPattern": "Compiling\\.\\.\\.$",
20 | "endsPattern": "(Compiled successfully|Failed to compile)\\.$"
21 | }
22 | }
23 | }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 30
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 7
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - pr
8 | - discussion
9 | - e2e
10 | - enhancement
11 | # Comment to post when marking an issue as stale. Set to `false` to disable
12 | markComment: >
13 | This issue has been automatically marked as stale because it has not had
14 | recent activity. It will be closed if no further activity occurs. Thank you
15 | for your contributions.
16 | # Comment to post when closing a stale issue. Set to `false` to disable
17 | closeComment: false
18 |
--------------------------------------------------------------------------------
/.erb/scripts/electron-rebuild.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import { execSync } from 'child_process';
3 | import fs from 'fs';
4 | import { dependencies } from '../../release/app/package.json';
5 | import webpackPaths from '../configs/webpack.paths';
6 |
7 | if (
8 | Object.keys(dependencies || {}).length > 0 &&
9 | fs.existsSync(webpackPaths.appNodeModulesPath)
10 | ) {
11 | const electronRebuildCmd =
12 | '../../node_modules/.bin/electron-rebuild --parallel --force --types prod,dev,optional --module-dir .';
13 | const cmd =
14 | process.platform === 'win32'
15 | ? electronRebuildCmd.replace(/\//g, '\\')
16 | : electronRebuildCmd;
17 | execSync(cmd, {
18 | cwd: webpackPaths.appPath,
19 | stdio: 'inherit',
20 | });
21 | }
22 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | release:
7 | runs-on: ${{ matrix.os }}
8 |
9 | strategy:
10 | matrix:
11 | os: [macos-latest, windows-latest, ubuntu-latest]
12 |
13 | steps:
14 | - name: Check out Git repository
15 | uses: actions/checkout@v1
16 |
17 | - name: Install Node.js, NPM and Yarn
18 | uses: actions/setup-node@v1
19 | with:
20 | node-version: 15
21 |
22 | - name: npm install
23 | run: |
24 | npm install
25 |
26 | - name: npm test
27 | env:
28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29 | run: |
30 | npm run package
31 | npm run lint
32 | npm exec tsc
33 | npm test
34 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Electron: Main",
6 | "type": "node",
7 | "request": "launch",
8 | "protocol": "inspector",
9 | "runtimeExecutable": "npm",
10 | "runtimeArgs": [
11 | "run start:main --inspect=5858 --remote-debugging-port=9223"
12 | ],
13 | "preLaunchTask": "Start Webpack Dev"
14 | },
15 | {
16 | "name": "Electron: Renderer",
17 | "type": "chrome",
18 | "request": "attach",
19 | "port": 9223,
20 | "webRoot": "${workspaceFolder}",
21 | "timeout": 15000
22 | }
23 | ],
24 | "compounds": [
25 | {
26 | "name": "Electron: All",
27 | "configurations": ["Electron: Main", "Electron: Renderer"]
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/.erb/scripts/check-build-exists.ts:
--------------------------------------------------------------------------------
1 | // Check if the renderer and main bundles are built
2 | import path from 'path';
3 | import chalk from 'chalk';
4 | import fs from 'fs';
5 | import webpackPaths from '../configs/webpack.paths';
6 |
7 | const mainPath = path.join(webpackPaths.distMainPath, 'main.js');
8 | const rendererPath = path.join(webpackPaths.distRendererPath, 'renderer.js');
9 |
10 | if (!fs.existsSync(mainPath)) {
11 | throw new Error(
12 | chalk.whiteBright.bgRed.bold(
13 | 'The main process is not built yet. Build it by running "npm run build:main"'
14 | )
15 | );
16 | }
17 |
18 | if (!fs.existsSync(rendererPath)) {
19 | throw new Error(
20 | chalk.whiteBright.bgRed.bold(
21 | 'The renderer process is not built yet. Build it by running "npm run build:renderer"'
22 | )
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/preload.js:
--------------------------------------------------------------------------------
1 | const { contextBridge, ipcRenderer } = require('electron');
2 |
3 | contextBridge.exposeInMainWorld('electron', {
4 | ipcRenderer: {
5 | myPing() {
6 | ipcRenderer.send('ipc-example', 'ping');
7 | },
8 | on(channel, func) {
9 | const validChannels = ['ipc-example'];
10 | if (validChannels.includes(channel)) {
11 | // Deliberately strip event as it includes `sender`
12 | ipcRenderer.on(channel, (event, ...args) => func(...args));
13 | }
14 | },
15 | once(channel, func) {
16 | const validChannels = ['ipc-example'];
17 | if (validChannels.includes(channel)) {
18 | // Deliberately strip event as it includes `sender`
19 | ipcRenderer.once(channel, (event, ...args) => func(...args));
20 | }
21 | },
22 | },
23 | });
24 |
--------------------------------------------------------------------------------
/release/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "electron-react-boilerplate",
3 | "productName": "electron-react-boilerplate",
4 | "version": "4.3.1",
5 | "description": "Electron application boilerplate based on React, React Router, Webpack, React Hot Loader for rapid application development",
6 | "main": "./dist/main/main.js",
7 | "author": {
8 | "name": "Electron React Boilerplate Maintainers",
9 | "email": "electronreactboilerplate@gmail.com",
10 | "url": "https://github.com/electron-react-boilerplate"
11 | },
12 | "scripts": {
13 | "electron-rebuild": "node -r ts-node/register ../../.erb/scripts/electron-rebuild.js",
14 | "link-modules": "node -r ts-node/register ../../.erb/scripts/link-modules.js",
15 | "postinstall": "npm run electron-rebuild && npm run link-modules"
16 | },
17 | "license": "MIT"
18 | }
19 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2021",
4 | "module": "commonjs",
5 | "lib": ["dom", "esnext"],
6 | "declaration": true,
7 | "declarationMap": true,
8 | "jsx": "react-jsx",
9 | "strict": true,
10 | "pretty": true,
11 | "sourceMap": true,
12 | "baseUrl": "./src",
13 | /* Additional Checks */
14 | "noUnusedLocals": true,
15 | "noUnusedParameters": true,
16 | "noImplicitReturns": true,
17 | "noFallthroughCasesInSwitch": true,
18 | /* Module Resolution Options */
19 | "moduleResolution": "node",
20 | "esModuleInterop": true,
21 | "allowSyntheticDefaultImports": true,
22 | "resolveJsonModule": true,
23 | "allowJs": true,
24 | "outDir": "release/app/dist"
25 | },
26 | "exclude": ["test", "release/build", "release/app/dist", ".erb/dll"]
27 | }
28 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: 'erb',
3 | rules: {
4 | // A temporary hack related to IDE not resolving correct package.json
5 | 'import/no-extraneous-dependencies': 'off',
6 | // Since React 17 and typescript 4.1 you can safely disable the rule
7 | 'react/react-in-jsx-scope': 'off',
8 | },
9 | parserOptions: {
10 | ecmaVersion: 2020,
11 | sourceType: 'module',
12 | project: './tsconfig.json',
13 | tsconfigRootDir: __dirname,
14 | createDefaultProgram: true,
15 | },
16 | settings: {
17 | 'import/resolver': {
18 | // See https://github.com/benmosher/eslint-plugin-import/issues/1396#issuecomment-575727774 for line below
19 | node: {},
20 | webpack: {
21 | config: require.resolve('./.erb/configs/webpack.config.eslint.ts'),
22 | },
23 | },
24 | 'import/parsers': {
25 | '@typescript-eslint/parser': ['.ts', '.tsx'],
26 | },
27 | },
28 | };
29 |
--------------------------------------------------------------------------------
/.erb/scripts/notarize.js:
--------------------------------------------------------------------------------
1 | const { notarize } = require('electron-notarize');
2 | const { build } = require('../../package.json');
3 |
4 | exports.default = async function notarizeMacos(context) {
5 | const { electronPlatformName, appOutDir } = context;
6 | if (electronPlatformName !== 'darwin') {
7 | return;
8 | }
9 |
10 | if (!process.env.CI) {
11 | console.warn('Skipping notarizing step. Packaging is not running in CI');
12 | return;
13 | }
14 |
15 | if (!('APPLE_ID' in process.env && 'APPLE_ID_PASS' in process.env)) {
16 | console.warn('Skipping notarizing step. APPLE_ID and APPLE_ID_PASS env variables must be set');
17 | return;
18 | }
19 |
20 | const appName = context.packager.appInfo.productFilename;
21 |
22 | await notarize({
23 | appBundleId: build.appId,
24 | appPath: `${appOutDir}/${appName}.app`,
25 | appleId: process.env.APPLE_ID,
26 | appleIdPassword: process.env.APPLE_ID_PASS,
27 | });
28 | };
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-present Electron React Boilerplate
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.base.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Base webpack config used across other specific configs
3 | */
4 |
5 | import webpack from 'webpack';
6 | import webpackPaths from './webpack.paths';
7 | import { dependencies as externals } from '../../release/app/package.json';
8 |
9 | export default {
10 | externals: [...Object.keys(externals || {})],
11 |
12 | stats: 'errors-only',
13 |
14 | module: {
15 | rules: [
16 | {
17 | test: /\.[jt]sx?$/,
18 | exclude: /node_modules/,
19 | use: {
20 | loader: 'ts-loader',
21 | },
22 | },
23 | ],
24 | },
25 |
26 | output: {
27 | path: webpackPaths.srcPath,
28 | // https://github.com/webpack/webpack/issues/1114
29 | library: {
30 | type: 'commonjs2',
31 | },
32 | },
33 |
34 | /**
35 | * Determine the array of extensions that should be used to resolve modules.
36 | */
37 | resolve: {
38 | extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
39 | modules: [webpackPaths.srcPath, 'node_modules'],
40 | },
41 |
42 | plugins: [
43 | new webpack.EnvironmentPlugin({
44 | NODE_ENV: 'production',
45 | }),
46 | ],
47 | };
48 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.paths.ts:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const rootPath = path.join(__dirname, '../..');
4 |
5 | const dllPath = path.join(__dirname, '../dll');
6 |
7 | const srcPath = path.join(rootPath, 'src');
8 | const srcMainPath = path.join(srcPath, 'main');
9 | const srcRendererPath = path.join(srcPath, 'renderer');
10 |
11 | const releasePath = path.join(rootPath, 'release');
12 | const appPath = path.join(releasePath, 'app');
13 | const appPackagePath = path.join(appPath, 'package.json');
14 | const appNodeModulesPath = path.join(appPath, 'node_modules');
15 | const srcNodeModulesPath = path.join(srcPath, 'node_modules');
16 |
17 | const distPath = path.join(appPath, 'dist');
18 | const distMainPath = path.join(distPath, 'main');
19 | const distRendererPath = path.join(distPath, 'renderer');
20 |
21 | const buildPath = path.join(releasePath, 'build');
22 |
23 | export default {
24 | rootPath,
25 | dllPath,
26 | srcPath,
27 | srcMainPath,
28 | srcRendererPath,
29 | releasePath,
30 | appPath,
31 | appPackagePath,
32 | appNodeModulesPath,
33 | srcNodeModulesPath,
34 | distPath,
35 | distMainPath,
36 | distRendererPath,
37 | buildPath,
38 | };
39 |
--------------------------------------------------------------------------------
/src/renderer/App.css:
--------------------------------------------------------------------------------
1 | /*
2 | * @NOTE: Prepend a `~` to css file paths that are in your node_modules
3 | * See https://github.com/webpack-contrib/sass-loader#imports
4 | */
5 | body {
6 | position: relative;
7 | color: white;
8 | height: 100vh;
9 | background: linear-gradient(
10 | 200.96deg,
11 | #fedc2a -29.09%,
12 | #dd5789 51.77%,
13 | #7a2c9e 129.35%
14 | );
15 | font-family: sans-serif;
16 | overflow-y: hidden;
17 | display: flex;
18 | justify-content: center;
19 | align-items: center;
20 | }
21 |
22 | button {
23 | background-color: white;
24 | color: black;
25 | padding: 10px 20px;
26 | border-radius: 10px;
27 | border: none;
28 | appearance: none;
29 | font-size: 1.3rem;
30 | box-shadow: 0px 8px 28px -6px rgba(24, 39, 75, 0.12),
31 | 0px 18px 88px -4px rgba(24, 39, 75, 0.14);
32 | transition: all ease-in 0.1s;
33 | cursor: pointer;
34 | opacity: 0.9;
35 | }
36 |
37 | button:hover {
38 | transform: scale(1.05);
39 | opacity: 1;
40 | }
41 |
42 | li {
43 | list-style: none;
44 | }
45 |
46 | a {
47 | text-decoration: none;
48 | height: fit-content;
49 | width: fit-content;
50 | margin: 10px;
51 | }
52 |
53 | a:hover {
54 | opacity: 1;
55 | text-decoration: none;
56 | }
57 |
58 | .Hello {
59 | display: flex;
60 | justify-content: center;
61 | align-items: center;
62 | margin: 20px 0;
63 | }
64 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | publish:
10 | # To enable auto publishing to github, update your electron publisher
11 | # config in package.json > "build" and remove the conditional below
12 | if: ${{ github.repository_owner == 'electron-react-boilerplate' }}
13 |
14 | runs-on: ${{ matrix.os }}
15 |
16 | strategy:
17 | matrix:
18 | os: [macos-latest]
19 |
20 | steps:
21 | - name: Checkout git repo
22 | uses: actions/checkout@v1
23 |
24 | - name: Install Node, NPM and Yarn
25 | uses: actions/setup-node@v1
26 | with:
27 | node-version: 15
28 |
29 | - name: Install dependencies
30 | run: |
31 | npm install
32 |
33 | - name: Publish releases
34 | env:
35 | # These values are used for auto updates signing
36 | APPLE_ID: ${{ secrets.APPLE_ID }}
37 | APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }}
38 | CSC_LINK: ${{ secrets.CSC_LINK }}
39 | CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
40 | # This is used for uploading release assets to github
41 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42 | run: |
43 | npm run postinstall
44 | npm run build
45 | npm exec electron-builder -- --publish always --win --mac --linux
46 |
--------------------------------------------------------------------------------
/src/renderer/App.tsx:
--------------------------------------------------------------------------------
1 | import { MemoryRouter as Router, Switch, Route } from 'react-router-dom';
2 | import 'tailwindcss/tailwind.css';
3 | import icon from '../../assets/icon.svg';
4 | import './App.css';
5 |
6 | const Tailwind = () => {
7 | return (
8 |
9 | ERB + TAILWIND = ❤
10 |
11 | );
12 | };
13 |
14 | const Hello = () => {
15 | return (
16 |
17 |
18 |

19 |
20 |
electron-react-boilerplate
21 |
22 |
48 |
49 | );
50 | };
51 |
52 | export default function App() {
53 | return (
54 |
55 |
56 |
57 |
58 |
59 | );
60 | }
61 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.renderer.dev.dll.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Builds the DLL for development electron renderer process
3 | */
4 |
5 | import webpack from 'webpack';
6 | import path from 'path';
7 | import { merge } from 'webpack-merge';
8 | import baseConfig from './webpack.config.base';
9 | import webpackPaths from './webpack.paths';
10 | import { dependencies } from '../../package.json';
11 | import checkNodeEnv from '../scripts/check-node-env';
12 |
13 | checkNodeEnv('development');
14 |
15 | const dist = webpackPaths.dllPath;
16 |
17 | export default merge(baseConfig, {
18 | context: webpackPaths.rootPath,
19 |
20 | devtool: 'eval',
21 |
22 | mode: 'development',
23 |
24 | target: 'electron-renderer',
25 |
26 | externals: ['fsevents', 'crypto-browserify'],
27 |
28 | /**
29 | * Use `module` from `webpack.config.renderer.dev.js`
30 | */
31 | module: require('./webpack.config.renderer.dev').default.module,
32 |
33 | entry: {
34 | renderer: Object.keys(dependencies || {}),
35 | },
36 |
37 | output: {
38 | path: dist,
39 | filename: '[name].dev.dll.js',
40 | library: {
41 | name: 'renderer',
42 | type: 'var',
43 | },
44 | },
45 |
46 | plugins: [
47 | new webpack.DllPlugin({
48 | path: path.join(dist, '[name].json'),
49 | name: '[name]',
50 | }),
51 |
52 | /**
53 | * Create global constants which can be configured at compile time.
54 | *
55 | * Useful for allowing different behaviour between development builds and
56 | * release builds
57 | *
58 | * NODE_ENV should be production so that modules do not perform certain
59 | * development checks
60 | */
61 | new webpack.EnvironmentPlugin({
62 | NODE_ENV: 'development',
63 | }),
64 |
65 | new webpack.LoaderOptionsPlugin({
66 | debug: true,
67 | options: {
68 | context: webpackPaths.srcPath,
69 | output: {
70 | path: webpackPaths.dllPath,
71 | },
72 | },
73 | }),
74 | ],
75 | });
76 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/1-Bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: You're having technical issues. 🐞
4 | labels: 'bug'
5 | ---
6 |
7 |
8 |
9 | ## Prerequisites
10 |
11 |
12 |
13 | - [ ] Using npm
14 | - [ ] Using an up-to-date [`main` branch](https://github.com/electron-react-boilerplate/electron-react-boilerplate/tree/main)
15 | - [ ] Using latest version of devtools. [Check the docs for how to update](https://electron-react-boilerplate.js.org/docs/dev-tools/)
16 | - [ ] Tried solutions mentioned in [#400](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/400)
17 | - [ ] For issue in production release, add devtools output of `DEBUG_PROD=true npm run build && npm start`
18 |
19 | ## Expected Behavior
20 |
21 |
22 |
23 | ## Current Behavior
24 |
25 |
26 |
27 | ## Steps to Reproduce
28 |
29 |
30 |
31 |
32 | 1.
33 |
34 | 2.
35 |
36 | 3.
37 |
38 | 4.
39 |
40 | ## Possible Solution (Not obligatory)
41 |
42 |
43 |
44 | ## Context
45 |
46 |
47 |
48 |
49 |
50 | ## Your Environment
51 |
52 |
53 |
54 | - Node version :
55 | - electron-react-boilerplate version or branch :
56 | - Operating System and version :
57 | - Link to your project :
58 |
59 |
68 |
--------------------------------------------------------------------------------
/.erb/scripts/check-native-dep.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import chalk from 'chalk';
3 | import { execSync } from 'child_process';
4 | import { dependencies } from '../../package.json';
5 |
6 | if (dependencies) {
7 | const dependenciesKeys = Object.keys(dependencies);
8 | const nativeDeps = fs
9 | .readdirSync('node_modules')
10 | .filter((folder) => fs.existsSync(`node_modules/${folder}/binding.gyp`));
11 | if (nativeDeps.length === 0) {
12 | process.exit(0);
13 | }
14 | try {
15 | // Find the reason for why the dependency is installed. If it is installed
16 | // because of a devDependency then that is okay. Warn when it is installed
17 | // because of a dependency
18 | const { dependencies: dependenciesObject } = JSON.parse(
19 | execSync(`npm ls ${nativeDeps.join(' ')} --json`).toString()
20 | );
21 | const rootDependencies = Object.keys(dependenciesObject);
22 | const filteredRootDependencies = rootDependencies.filter((rootDependency) =>
23 | dependenciesKeys.includes(rootDependency)
24 | );
25 | if (filteredRootDependencies.length > 0) {
26 | const plural = filteredRootDependencies.length > 1;
27 | console.log(`
28 | ${chalk.whiteBright.bgYellow.bold(
29 | 'Webpack does not work with native dependencies.'
30 | )}
31 | ${chalk.bold(filteredRootDependencies.join(', '))} ${
32 | plural ? 'are native dependencies' : 'is a native dependency'
33 | } and should be installed inside of the "./release/app" folder.
34 | First, uninstall the packages from "./package.json":
35 | ${chalk.whiteBright.bgGreen.bold('npm uninstall your-package')}
36 | ${chalk.bold(
37 | 'Then, instead of installing the package to the root "./package.json":'
38 | )}
39 | ${chalk.whiteBright.bgRed.bold('npm install your-package')}
40 | ${chalk.bold('Install the package to "./release/app/package.json"')}
41 | ${chalk.whiteBright.bgGreen.bold('cd ./release/app && npm install your-package')}
42 | Read more about native dependencies at:
43 | ${chalk.bold(
44 | 'https://electron-react-boilerplate.js.org/docs/adding-dependencies/#module-structure'
45 | )}
46 | `);
47 | process.exit(1);
48 | }
49 | } catch (e) {
50 | console.log('Native dependencies could not be checked');
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.main.prod.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Webpack config for production electron main process
3 | */
4 |
5 | import path from 'path';
6 | import webpack from 'webpack';
7 | import { merge } from 'webpack-merge';
8 | import TerserPlugin from 'terser-webpack-plugin';
9 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
10 | import baseConfig from './webpack.config.base';
11 | import webpackPaths from './webpack.paths';
12 | import checkNodeEnv from '../scripts/check-node-env';
13 | import deleteSourceMaps from '../scripts/delete-source-maps';
14 |
15 | checkNodeEnv('production');
16 | deleteSourceMaps();
17 |
18 | const devtoolsConfig =
19 | process.env.DEBUG_PROD === 'true'
20 | ? {
21 | devtool: 'source-map',
22 | }
23 | : {};
24 |
25 | export default merge(baseConfig, {
26 | ...devtoolsConfig,
27 |
28 | mode: 'production',
29 |
30 | target: 'electron-main',
31 |
32 | entry: {
33 | main: path.join(webpackPaths.srcMainPath, 'main.ts'),
34 | preload: path.join(webpackPaths.srcMainPath, 'preload.js'),
35 | },
36 |
37 | output: {
38 | path: webpackPaths.distMainPath,
39 | filename: '[name].js',
40 | },
41 |
42 | optimization: {
43 | minimizer: [
44 | new TerserPlugin({
45 | parallel: true,
46 | }),
47 | ],
48 | },
49 |
50 | plugins: [
51 | new BundleAnalyzerPlugin({
52 | analyzerMode:
53 | process.env.OPEN_ANALYZER === 'true' ? 'server' : 'disabled',
54 | openAnalyzer: process.env.OPEN_ANALYZER === 'true',
55 | }),
56 |
57 | /**
58 | * Create global constants which can be configured at compile time.
59 | *
60 | * Useful for allowing different behaviour between development builds and
61 | * release builds
62 | *
63 | * NODE_ENV should be production so that modules do not perform certain
64 | * development checks
65 | */
66 | new webpack.EnvironmentPlugin({
67 | NODE_ENV: 'production',
68 | DEBUG_PROD: false,
69 | START_MINIMIZED: false,
70 | }),
71 | ],
72 |
73 | /**
74 | * Disables webpack processing of __dirname and __filename.
75 | * If you run the bundle in node.js it falls back to these values of node.js.
76 | * https://github.com/webpack/webpack/issues/2010
77 | */
78 | node: {
79 | __dirname: false,
80 | __filename: false,
81 | },
82 | });
83 |
--------------------------------------------------------------------------------
/assets/icon.svg:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at electronreactboilerplate@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/src/main/main.ts:
--------------------------------------------------------------------------------
1 | /* eslint global-require: off, no-console: off, promise/always-return: off */
2 |
3 | /**
4 | * This module executes inside of electron's main process. You can start
5 | * electron renderer process from here and communicate with the other processes
6 | * through IPC.
7 | *
8 | * When running `npm run build` or `npm run build:main`, this file is compiled to
9 | * `./src/main.js` using webpack. This gives us some performance wins.
10 | */
11 | import 'core-js/stable';
12 | import 'regenerator-runtime/runtime';
13 | import path from 'path';
14 | import { app, BrowserWindow, shell, ipcMain } from 'electron';
15 | import { autoUpdater } from 'electron-updater';
16 | import log from 'electron-log';
17 | import MenuBuilder from './menu';
18 | import { resolveHtmlPath } from './util';
19 |
20 | export default class AppUpdater {
21 | constructor() {
22 | log.transports.file.level = 'info';
23 | autoUpdater.logger = log;
24 | autoUpdater.checkForUpdatesAndNotify();
25 | }
26 | }
27 |
28 | let mainWindow: BrowserWindow | null = null;
29 |
30 | ipcMain.on('ipc-example', async (event, arg) => {
31 | const msgTemplate = (pingPong: string) => `IPC test: ${pingPong}`;
32 | console.log(msgTemplate(arg));
33 | event.reply('ipc-example', msgTemplate('pong'));
34 | });
35 |
36 | if (process.env.NODE_ENV === 'production') {
37 | const sourceMapSupport = require('source-map-support');
38 | sourceMapSupport.install();
39 | }
40 |
41 | const isDevelopment =
42 | process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true';
43 |
44 | if (isDevelopment) {
45 | require('electron-debug')();
46 | }
47 |
48 | const installExtensions = async () => {
49 | const installer = require('electron-devtools-installer');
50 | const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
51 | const extensions = ['REACT_DEVELOPER_TOOLS'];
52 |
53 | return installer
54 | .default(
55 | extensions.map((name) => installer[name]),
56 | forceDownload
57 | )
58 | .catch(console.log);
59 | };
60 |
61 | const createWindow = async () => {
62 | if (isDevelopment) {
63 | await installExtensions();
64 | }
65 |
66 | const RESOURCES_PATH = app.isPackaged
67 | ? path.join(process.resourcesPath, 'assets')
68 | : path.join(__dirname, '../../assets');
69 |
70 | const getAssetPath = (...paths: string[]): string => {
71 | return path.join(RESOURCES_PATH, ...paths);
72 | };
73 |
74 | mainWindow = new BrowserWindow({
75 | show: false,
76 | width: 1024,
77 | height: 728,
78 | icon: getAssetPath('icon.png'),
79 | webPreferences: {
80 | preload: path.join(__dirname, 'preload.js'),
81 | },
82 | });
83 |
84 | mainWindow.loadURL(resolveHtmlPath('index.html'));
85 |
86 | mainWindow.on('ready-to-show', () => {
87 | if (!mainWindow) {
88 | throw new Error('"mainWindow" is not defined');
89 | }
90 | if (process.env.START_MINIMIZED) {
91 | mainWindow.minimize();
92 | } else {
93 | mainWindow.show();
94 | }
95 | });
96 |
97 | mainWindow.on('closed', () => {
98 | mainWindow = null;
99 | });
100 |
101 | const menuBuilder = new MenuBuilder(mainWindow);
102 | menuBuilder.buildMenu();
103 |
104 | // Open urls in the user's browser
105 | mainWindow.webContents.on('new-window', (event, url) => {
106 | event.preventDefault();
107 | shell.openExternal(url);
108 | });
109 |
110 | // Remove this if your app does not use auto updates
111 | // eslint-disable-next-line
112 | new AppUpdater();
113 | };
114 |
115 | /**
116 | * Add event listeners...
117 | */
118 |
119 | app.on('window-all-closed', () => {
120 | // Respect the OSX convention of having the application in memory even
121 | // after all windows have been closed
122 | if (process.platform !== 'darwin') {
123 | app.quit();
124 | }
125 | });
126 |
127 | app
128 | .whenReady()
129 | .then(() => {
130 | createWindow();
131 | app.on('activate', () => {
132 | // On macOS it's common to re-create a window in the app when the
133 | // dock icon is clicked and there are no other windows open.
134 | if (mainWindow === null) createWindow();
135 | });
136 | })
137 | .catch(console.log);
138 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.renderer.prod.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Build config for electron renderer process
3 | */
4 |
5 | import path from 'path';
6 | import webpack from 'webpack';
7 | import HtmlWebpackPlugin from 'html-webpack-plugin';
8 | import MiniCssExtractPlugin from 'mini-css-extract-plugin';
9 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
10 | import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
11 | import { merge } from 'webpack-merge';
12 | import TerserPlugin from 'terser-webpack-plugin';
13 | import baseConfig from './webpack.config.base';
14 | import webpackPaths from './webpack.paths';
15 | import checkNodeEnv from '../scripts/check-node-env';
16 | import deleteSourceMaps from '../scripts/delete-source-maps';
17 |
18 | checkNodeEnv('production');
19 | deleteSourceMaps();
20 |
21 | const devtoolsConfig =
22 | process.env.DEBUG_PROD === 'true'
23 | ? {
24 | devtool: 'source-map',
25 | }
26 | : {};
27 |
28 | export default merge(baseConfig, {
29 | ...devtoolsConfig,
30 |
31 | mode: 'production',
32 |
33 | target: ['web', 'electron-renderer'],
34 |
35 | entry: [
36 | 'core-js',
37 | 'regenerator-runtime/runtime',
38 | path.join(webpackPaths.srcRendererPath, 'index.tsx'),
39 | ],
40 |
41 | output: {
42 | path: webpackPaths.distRendererPath,
43 | publicPath: './',
44 | filename: 'renderer.js',
45 | library: {
46 | type: 'umd',
47 | },
48 | },
49 |
50 | module: {
51 | rules: [
52 | {
53 | test: /\.s?(a|c)ss$/,
54 | use: [
55 | MiniCssExtractPlugin.loader,
56 | {
57 | loader: 'css-loader',
58 | options: {
59 | modules: true,
60 | sourceMap: true,
61 | importLoaders: 1,
62 | },
63 | },
64 | 'sass-loader',
65 | {
66 | loader: 'postcss-loader',
67 | options: {
68 | postcssOptions: {
69 | plugins: [require('tailwindcss'), require('autoprefixer')],
70 | },
71 | },
72 | },
73 | ],
74 | include: /\.module\.s?(c|a)ss$/,
75 | },
76 | {
77 | test: /\.s?(a|c)ss$/,
78 | use: [
79 | MiniCssExtractPlugin.loader,
80 | 'css-loader',
81 | 'sass-loader',
82 | {
83 | loader: 'postcss-loader',
84 | options: {
85 | postcssOptions: {
86 | plugins: [require('tailwindcss'), require('autoprefixer')],
87 | },
88 | },
89 | },
90 | ],
91 | exclude: /\.module\.s?(c|a)ss$/,
92 | },
93 | //Font Loader
94 | {
95 | test: /\.(woff|woff2|eot|ttf|otf)$/i,
96 | type: 'asset/resource',
97 | },
98 | // SVG Font
99 | {
100 | test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
101 | use: {
102 | loader: 'url-loader',
103 | options: {
104 | limit: 10000,
105 | mimetype: 'image/svg+xml',
106 | },
107 | },
108 | },
109 | // Common Image Formats
110 | {
111 | test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
112 | use: 'url-loader',
113 | },
114 | ],
115 | },
116 |
117 | optimization: {
118 | minimize: true,
119 | minimizer: [
120 | new TerserPlugin({
121 | parallel: true,
122 | }),
123 | new CssMinimizerPlugin(),
124 | ],
125 | },
126 |
127 | plugins: [
128 | /**
129 | * Create global constants which can be configured at compile time.
130 | *
131 | * Useful for allowing different behaviour between development builds and
132 | * release builds
133 | *
134 | * NODE_ENV should be production so that modules do not perform certain
135 | * development checks
136 | */
137 | new webpack.EnvironmentPlugin({
138 | NODE_ENV: 'production',
139 | DEBUG_PROD: false,
140 | }),
141 |
142 | new MiniCssExtractPlugin({
143 | filename: 'style.css',
144 | }),
145 |
146 | new BundleAnalyzerPlugin({
147 | analyzerMode:
148 | process.env.OPEN_ANALYZER === 'true' ? 'server' : 'disabled',
149 | openAnalyzer: process.env.OPEN_ANALYZER === 'true',
150 | }),
151 |
152 | new HtmlWebpackPlugin({
153 | filename: 'index.html',
154 | template: path.join(webpackPaths.srcRendererPath, 'index.ejs'),
155 | minify: {
156 | collapseWhitespace: true,
157 | removeAttributeQuotes: true,
158 | removeComments: true,
159 | },
160 | isBrowser: false,
161 | isDevelopment: process.env.NODE_ENV !== 'production',
162 | }),
163 | ],
164 | });
165 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.renderer.dev.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fs from 'fs';
3 | import webpack from 'webpack';
4 | import HtmlWebpackPlugin from 'html-webpack-plugin';
5 | import chalk from 'chalk';
6 | import { merge } from 'webpack-merge';
7 | import { spawn, execSync } from 'child_process';
8 | import baseConfig from './webpack.config.base';
9 | import webpackPaths from './webpack.paths';
10 | import checkNodeEnv from '../scripts/check-node-env';
11 | import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
12 |
13 | // When an ESLint server is running, we can't set the NODE_ENV so we'll check if it's
14 | // at the dev webpack config is not accidentally run in a production environment
15 | if (process.env.NODE_ENV === 'production') {
16 | checkNodeEnv('development');
17 | }
18 |
19 | const port = process.env.PORT || 1212;
20 | const manifest = path.resolve(webpackPaths.dllPath, 'renderer.json');
21 | const requiredByDLLConfig = module.parent.filename.includes(
22 | 'webpack.config.renderer.dev.dll'
23 | );
24 |
25 | /**
26 | * Warn if the DLL is not built
27 | */
28 | if (
29 | !requiredByDLLConfig &&
30 | !(fs.existsSync(webpackPaths.dllPath) && fs.existsSync(manifest))
31 | ) {
32 | console.log(
33 | chalk.black.bgYellow.bold(
34 | 'The DLL files are missing. Sit back while we build them for you with "npm run build-dll"'
35 | )
36 | );
37 | execSync('npm run postinstall');
38 | }
39 |
40 | export default merge(baseConfig, {
41 | devtool: 'inline-source-map',
42 |
43 | mode: 'development',
44 |
45 | target: ['web', 'electron-renderer'],
46 |
47 | entry: [
48 | `webpack-dev-server/client?http://localhost:${port}/dist`,
49 | 'webpack/hot/only-dev-server',
50 | 'core-js',
51 | 'regenerator-runtime/runtime',
52 | path.join(webpackPaths.srcRendererPath, 'index.tsx'),
53 | ],
54 |
55 | output: {
56 | path: webpackPaths.distRendererPath,
57 | publicPath: '/',
58 | filename: 'renderer.dev.js',
59 | library: {
60 | type: 'umd',
61 | },
62 | },
63 |
64 | module: {
65 | rules: [
66 | {
67 | test: /\.s?css$/,
68 | use: [
69 | 'style-loader',
70 | {
71 | loader: 'css-loader',
72 | options: {
73 | modules: true,
74 | sourceMap: true,
75 | importLoaders: 1,
76 | },
77 | },
78 | 'sass-loader',
79 | {
80 | loader: 'postcss-loader',
81 | options: {
82 | postcssOptions: {
83 | plugins: [require('tailwindcss'), require('autoprefixer')],
84 | },
85 | },
86 | },
87 | ],
88 | include: /\.module\.s?(c|a)ss$/,
89 | },
90 | {
91 | test: /\.s?css$/,
92 | use: [
93 | 'style-loader',
94 | 'css-loader',
95 | 'sass-loader',
96 | {
97 | loader: 'postcss-loader',
98 | options: {
99 | postcssOptions: {
100 | plugins: [require('tailwindcss'), require('autoprefixer')],
101 | },
102 | },
103 | },
104 | ],
105 | exclude: /\.module\.s?(c|a)ss$/,
106 | },
107 | //Font Loader
108 | {
109 | test: /\.(woff|woff2|eot|ttf|otf)$/i,
110 | type: 'asset/resource',
111 | },
112 | // SVG Font
113 | {
114 | test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
115 | use: {
116 | loader: 'url-loader',
117 | options: {
118 | limit: 10000,
119 | mimetype: 'image/svg+xml',
120 | },
121 | },
122 | },
123 | // Common Image Formats
124 | {
125 | test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
126 | use: 'url-loader',
127 | },
128 | ],
129 | },
130 | plugins: [
131 | requiredByDLLConfig
132 | ? null
133 | : new webpack.DllReferencePlugin({
134 | context: webpackPaths.dllPath,
135 | manifest: require(manifest),
136 | sourceType: 'var',
137 | }),
138 |
139 | new webpack.NoEmitOnErrorsPlugin(),
140 |
141 | /**
142 | * Create global constants which can be configured at compile time.
143 | *
144 | * Useful for allowing different behaviour between development builds and
145 | * release builds
146 | *
147 | * NODE_ENV should be production so that modules do not perform certain
148 | * development checks
149 | *
150 | * By default, use 'development' as NODE_ENV. This can be overriden with
151 | * 'staging', for example, by changing the ENV variables in the npm scripts
152 | */
153 | new webpack.EnvironmentPlugin({
154 | NODE_ENV: 'development',
155 | }),
156 |
157 | new webpack.LoaderOptionsPlugin({
158 | debug: true,
159 | }),
160 |
161 | new ReactRefreshWebpackPlugin(),
162 |
163 | new HtmlWebpackPlugin({
164 | filename: path.join('index.html'),
165 | template: path.join(webpackPaths.srcRendererPath, 'index.ejs'),
166 | minify: {
167 | collapseWhitespace: true,
168 | removeAttributeQuotes: true,
169 | removeComments: true,
170 | },
171 | isBrowser: false,
172 | env: process.env.NODE_ENV,
173 | isDevelopment: process.env.NODE_ENV !== 'production',
174 | nodeModules: webpackPaths.appNodeModulesPath,
175 | }),
176 | ],
177 |
178 | node: {
179 | __dirname: false,
180 | __filename: false,
181 | },
182 |
183 | devServer: {
184 | port,
185 | compress: true,
186 | hot: true,
187 | headers: { 'Access-Control-Allow-Origin': '*' },
188 | static: {
189 | publicPath: '/',
190 | },
191 | historyApiFallback: {
192 | verbose: true,
193 | disableDotRule: false,
194 | },
195 | onBeforeSetupMiddleware() {
196 | console.log('Starting Main Process...');
197 | spawn('npm', ['run', 'start:main'], {
198 | shell: true,
199 | env: process.env,
200 | stdio: 'inherit',
201 | })
202 | .on('close', (code) => process.exit(code))
203 | .on('error', (spawnError) => console.error(spawnError));
204 | },
205 | },
206 | });
207 |
--------------------------------------------------------------------------------
/src/main/menu.ts:
--------------------------------------------------------------------------------
1 | import {
2 | app,
3 | Menu,
4 | shell,
5 | BrowserWindow,
6 | MenuItemConstructorOptions,
7 | } from 'electron';
8 |
9 | interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions {
10 | selector?: string;
11 | submenu?: DarwinMenuItemConstructorOptions[] | Menu;
12 | }
13 |
14 | export default class MenuBuilder {
15 | mainWindow: BrowserWindow;
16 |
17 | constructor(mainWindow: BrowserWindow) {
18 | this.mainWindow = mainWindow;
19 | }
20 |
21 | buildMenu(): Menu {
22 | if (
23 | process.env.NODE_ENV === 'development' ||
24 | process.env.DEBUG_PROD === 'true'
25 | ) {
26 | this.setupDevelopmentEnvironment();
27 | }
28 |
29 | const template =
30 | process.platform === 'darwin'
31 | ? this.buildDarwinTemplate()
32 | : this.buildDefaultTemplate();
33 |
34 | const menu = Menu.buildFromTemplate(template);
35 | Menu.setApplicationMenu(menu);
36 |
37 | return menu;
38 | }
39 |
40 | setupDevelopmentEnvironment(): void {
41 | this.mainWindow.webContents.on('context-menu', (_, props) => {
42 | const { x, y } = props;
43 |
44 | Menu.buildFromTemplate([
45 | {
46 | label: 'Inspect element',
47 | click: () => {
48 | this.mainWindow.webContents.inspectElement(x, y);
49 | },
50 | },
51 | ]).popup({ window: this.mainWindow });
52 | });
53 | }
54 |
55 | buildDarwinTemplate(): MenuItemConstructorOptions[] {
56 | const subMenuAbout: DarwinMenuItemConstructorOptions = {
57 | label: 'Electron',
58 | submenu: [
59 | {
60 | label: 'About ElectronReact',
61 | selector: 'orderFrontStandardAboutPanel:',
62 | },
63 | { type: 'separator' },
64 | { label: 'Services', submenu: [] },
65 | { type: 'separator' },
66 | {
67 | label: 'Hide ElectronReact',
68 | accelerator: 'Command+H',
69 | selector: 'hide:',
70 | },
71 | {
72 | label: 'Hide Others',
73 | accelerator: 'Command+Shift+H',
74 | selector: 'hideOtherApplications:',
75 | },
76 | { label: 'Show All', selector: 'unhideAllApplications:' },
77 | { type: 'separator' },
78 | {
79 | label: 'Quit',
80 | accelerator: 'Command+Q',
81 | click: () => {
82 | app.quit();
83 | },
84 | },
85 | ],
86 | };
87 | const subMenuEdit: DarwinMenuItemConstructorOptions = {
88 | label: 'Edit',
89 | submenu: [
90 | { label: 'Undo', accelerator: 'Command+Z', selector: 'undo:' },
91 | { label: 'Redo', accelerator: 'Shift+Command+Z', selector: 'redo:' },
92 | { type: 'separator' },
93 | { label: 'Cut', accelerator: 'Command+X', selector: 'cut:' },
94 | { label: 'Copy', accelerator: 'Command+C', selector: 'copy:' },
95 | { label: 'Paste', accelerator: 'Command+V', selector: 'paste:' },
96 | {
97 | label: 'Select All',
98 | accelerator: 'Command+A',
99 | selector: 'selectAll:',
100 | },
101 | ],
102 | };
103 | const subMenuViewDev: MenuItemConstructorOptions = {
104 | label: 'View',
105 | submenu: [
106 | {
107 | label: 'Reload',
108 | accelerator: 'Command+R',
109 | click: () => {
110 | this.mainWindow.webContents.reload();
111 | },
112 | },
113 | {
114 | label: 'Toggle Full Screen',
115 | accelerator: 'Ctrl+Command+F',
116 | click: () => {
117 | this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
118 | },
119 | },
120 | {
121 | label: 'Toggle Developer Tools',
122 | accelerator: 'Alt+Command+I',
123 | click: () => {
124 | this.mainWindow.webContents.toggleDevTools();
125 | },
126 | },
127 | ],
128 | };
129 | const subMenuViewProd: MenuItemConstructorOptions = {
130 | label: 'View',
131 | submenu: [
132 | {
133 | label: 'Toggle Full Screen',
134 | accelerator: 'Ctrl+Command+F',
135 | click: () => {
136 | this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
137 | },
138 | },
139 | ],
140 | };
141 | const subMenuWindow: DarwinMenuItemConstructorOptions = {
142 | label: 'Window',
143 | submenu: [
144 | {
145 | label: 'Minimize',
146 | accelerator: 'Command+M',
147 | selector: 'performMiniaturize:',
148 | },
149 | { label: 'Close', accelerator: 'Command+W', selector: 'performClose:' },
150 | { type: 'separator' },
151 | { label: 'Bring All to Front', selector: 'arrangeInFront:' },
152 | ],
153 | };
154 | const subMenuHelp: MenuItemConstructorOptions = {
155 | label: 'Help',
156 | submenu: [
157 | {
158 | label: 'Learn More',
159 | click() {
160 | shell.openExternal('https://electronjs.org');
161 | },
162 | },
163 | {
164 | label: 'Documentation',
165 | click() {
166 | shell.openExternal(
167 | 'https://github.com/electron/electron/tree/main/docs#readme'
168 | );
169 | },
170 | },
171 | {
172 | label: 'Community Discussions',
173 | click() {
174 | shell.openExternal('https://www.electronjs.org/community');
175 | },
176 | },
177 | {
178 | label: 'Search Issues',
179 | click() {
180 | shell.openExternal('https://github.com/electron/electron/issues');
181 | },
182 | },
183 | ],
184 | };
185 |
186 | const subMenuView =
187 | process.env.NODE_ENV === 'development' ||
188 | process.env.DEBUG_PROD === 'true'
189 | ? subMenuViewDev
190 | : subMenuViewProd;
191 |
192 | return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp];
193 | }
194 |
195 | buildDefaultTemplate() {
196 | const templateDefault = [
197 | {
198 | label: '&File',
199 | submenu: [
200 | {
201 | label: '&Open',
202 | accelerator: 'Ctrl+O',
203 | },
204 | {
205 | label: '&Close',
206 | accelerator: 'Ctrl+W',
207 | click: () => {
208 | this.mainWindow.close();
209 | },
210 | },
211 | ],
212 | },
213 | {
214 | label: '&View',
215 | submenu:
216 | process.env.NODE_ENV === 'development' ||
217 | process.env.DEBUG_PROD === 'true'
218 | ? [
219 | {
220 | label: '&Reload',
221 | accelerator: 'Ctrl+R',
222 | click: () => {
223 | this.mainWindow.webContents.reload();
224 | },
225 | },
226 | {
227 | label: 'Toggle &Full Screen',
228 | accelerator: 'F11',
229 | click: () => {
230 | this.mainWindow.setFullScreen(
231 | !this.mainWindow.isFullScreen()
232 | );
233 | },
234 | },
235 | {
236 | label: 'Toggle &Developer Tools',
237 | accelerator: 'Alt+Ctrl+I',
238 | click: () => {
239 | this.mainWindow.webContents.toggleDevTools();
240 | },
241 | },
242 | ]
243 | : [
244 | {
245 | label: 'Toggle &Full Screen',
246 | accelerator: 'F11',
247 | click: () => {
248 | this.mainWindow.setFullScreen(
249 | !this.mainWindow.isFullScreen()
250 | );
251 | },
252 | },
253 | ],
254 | },
255 | {
256 | label: 'Help',
257 | submenu: [
258 | {
259 | label: 'Learn More',
260 | click() {
261 | shell.openExternal('https://electronjs.org');
262 | },
263 | },
264 | {
265 | label: 'Documentation',
266 | click() {
267 | shell.openExternal(
268 | 'https://github.com/electron/electron/tree/main/docs#readme'
269 | );
270 | },
271 | },
272 | {
273 | label: 'Community Discussions',
274 | click() {
275 | shell.openExternal('https://www.electronjs.org/community');
276 | },
277 | },
278 | {
279 | label: 'Search Issues',
280 | click() {
281 | shell.openExternal('https://github.com/electron/electron/issues');
282 | },
283 | },
284 | ],
285 | },
286 | ];
287 |
288 | return templateDefault;
289 | }
290 | }
291 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "electron-react-boilerplate",
3 | "productName": "ElectronReact",
4 | "description": "Electron application boilerplate based on React, React Router, Webpack, React Fast Refresh for rapid application development",
5 | "scripts": {
6 | "build": "concurrently \"npm run build:main\" \"npm run build:renderer\"",
7 | "build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts",
8 | "build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts",
9 | "rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir src",
10 | "lint": "cross-env NODE_ENV=development eslint . --cache --ext .js,.jsx,.ts,.tsx",
11 | "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never",
12 | "postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts && opencollective-postinstall",
13 | "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer",
14 | "start:main": "cross-env NODE_ENV=development electron -r ts-node/register/transpile-only ./src/main/main.ts",
15 | "start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts",
16 | "test": "jest"
17 | },
18 | "lint-staged": {
19 | "*.{js,jsx,ts,tsx}": [
20 | "cross-env NODE_ENV=development eslint --cache"
21 | ],
22 | "*.json,.{eslintrc,prettierrc}": [
23 | "prettier --ignore-path .eslintignore --parser json --write"
24 | ],
25 | "*.{css,scss}": [
26 | "prettier --ignore-path .eslintignore --single-quote --write"
27 | ],
28 | "*.{html,md,yml}": [
29 | "prettier --ignore-path .eslintignore --single-quote --write"
30 | ]
31 | },
32 | "build": {
33 | "productName": "ElectronReact",
34 | "appId": "org.erb.ElectronReact",
35 | "asar": true,
36 | "asarUnpack": "**\\*.{node,dll}",
37 | "files": [
38 | "dist",
39 | "node_modules",
40 | "package.json"
41 | ],
42 | "afterSign": ".erb/scripts/notarize.js",
43 | "mac": {
44 | "target": {
45 | "target": "default",
46 | "arch": [
47 | "arm64",
48 | "x64"
49 | ]
50 | },
51 | "type": "distribution",
52 | "hardenedRuntime": true,
53 | "entitlements": "assets/entitlements.mac.plist",
54 | "entitlementsInherit": "assets/entitlements.mac.plist",
55 | "gatekeeperAssess": false
56 | },
57 | "dmg": {
58 | "contents": [
59 | {
60 | "x": 130,
61 | "y": 220
62 | },
63 | {
64 | "x": 410,
65 | "y": 220,
66 | "type": "link",
67 | "path": "/Applications"
68 | }
69 | ]
70 | },
71 | "win": {
72 | "target": [
73 | "nsis"
74 | ]
75 | },
76 | "linux": {
77 | "target": [
78 | "AppImage"
79 | ],
80 | "category": "Development"
81 | },
82 | "directories": {
83 | "app": "release/app",
84 | "buildResources": "assets",
85 | "output": "release/build"
86 | },
87 | "extraResources": [
88 | "./assets/**"
89 | ],
90 | "publish": {
91 | "provider": "github",
92 | "owner": "electron-react-boilerplate",
93 | "repo": "electron-react-boilerplate"
94 | }
95 | },
96 | "repository": {
97 | "type": "git",
98 | "url": "git+https://github.com/electron-react-boilerplate/electron-react-boilerplate.git"
99 | },
100 | "author": {
101 | "name": "Electron React Boilerplate Maintainers",
102 | "email": "electronreactboilerplate@gmail.com",
103 | "url": "https://electron-react-boilerplate.js.org"
104 | },
105 | "contributors": [
106 | {
107 | "name": "Amila Welihinda",
108 | "email": "amilajack@gmail.com",
109 | "url": "https://github.com/amilajack"
110 | },
111 | {
112 | "name": "John Tran",
113 | "email": "jptran318@gmail.com",
114 | "url": "https://github.com/jooohhn"
115 | }
116 | ],
117 | "license": "MIT",
118 | "bugs": {
119 | "url": "https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues"
120 | },
121 | "keywords": [
122 | "electron",
123 | "boilerplate",
124 | "react",
125 | "typescript",
126 | "ts",
127 | "sass",
128 | "webpack",
129 | "hot",
130 | "reload"
131 | ],
132 | "homepage": "https://github.com/electron-react-boilerplate/electron-react-boilerplate#readme",
133 | "jest": {
134 | "testURL": "http://localhost/",
135 | "testEnvironment": "jsdom",
136 | "transform": {
137 | "\\.(ts|tsx|js|jsx)$": "ts-jest"
138 | },
139 | "moduleNameMapper": {
140 | "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/.erb/mocks/fileMock.js",
141 | "\\.(css|less|sass|scss)$": "identity-obj-proxy"
142 | },
143 | "moduleFileExtensions": [
144 | "js",
145 | "jsx",
146 | "ts",
147 | "tsx",
148 | "json"
149 | ],
150 | "moduleDirectories": [
151 | "node_modules",
152 | "release/app/node_modules"
153 | ],
154 | "testPathIgnorePatterns": [
155 | "release/app/dist"
156 | ],
157 | "setupFiles": [
158 | "./.erb/scripts/check-build-exists.ts"
159 | ]
160 | },
161 | "devDependencies": {
162 | "@pmmmwh/react-refresh-webpack-plugin": "0.5.1",
163 | "@teamsupercell/typings-for-css-modules-loader": "^2.5.1",
164 | "@testing-library/jest-dom": "^5.14.1",
165 | "@testing-library/react": "^12.1.2",
166 | "@types/enzyme": "^3.10.10",
167 | "@types/enzyme-adapter-react-16": "^1.0.6",
168 | "@types/history": "4.7.9",
169 | "@types/jest": "^27.0.2",
170 | "@types/node": "16.11.6",
171 | "@types/react": "^17.0.33",
172 | "@types/react-dom": "^17.0.10",
173 | "@types/react-router": "^5.1.17",
174 | "@types/react-router-dom": "^5.3.2",
175 | "@types/react-test-renderer": "^17.0.1",
176 | "@types/terser-webpack-plugin": "^5.0.4",
177 | "@types/webpack-env": "^1.16.3",
178 | "@typescript-eslint/eslint-plugin": "^5.2.0",
179 | "autoprefixer": "^10.4.0",
180 | "browserslist-config-erb": "^0.0.3",
181 | "chalk": "^4.1.2",
182 | "concurrently": "^6.3.0",
183 | "core-js": "^3.19.0",
184 | "cross-env": "^7.0.3",
185 | "css-loader": "^6.5.0",
186 | "css-minimizer-webpack-plugin": "^3.1.1",
187 | "detect-port": "^1.3.0",
188 | "electron": "^15.3.0",
189 | "electron-builder": "^22.13.1",
190 | "electron-devtools-installer": "^3.2.0",
191 | "electron-notarize": "^1.1.1",
192 | "electron-rebuild": "^3.2.3",
193 | "enzyme": "^3.11.0",
194 | "enzyme-adapter-react-16": "^1.15.6",
195 | "enzyme-to-json": "^3.6.2",
196 | "eslint": "^7.32.0",
197 | "eslint-config-airbnb-base": "^14.2.1",
198 | "eslint-config-erb": "^4.0.3",
199 | "eslint-plugin-compat": "^3.13.0",
200 | "eslint-plugin-import": "^2.25.2",
201 | "eslint-plugin-jest": "^25.2.2",
202 | "eslint-plugin-jsx-a11y": "^6.4.1",
203 | "eslint-plugin-promise": "^5.1.1",
204 | "eslint-plugin-react": "^7.26.1",
205 | "eslint-plugin-react-hooks": "^4.2.0",
206 | "file-loader": "^6.2.0",
207 | "html-webpack-plugin": "^5.5.0",
208 | "husky": "7.0.4",
209 | "identity-obj-proxy": "^3.0.0",
210 | "jest": "^27.3.1",
211 | "lint-staged": "^11.2.6",
212 | "mini-css-extract-plugin": "^2.4.3",
213 | "opencollective-postinstall": "^2.0.3",
214 | "postcss": "^8.3.11",
215 | "postcss-loader": "^6.2.0",
216 | "prettier": "^2.4.1",
217 | "react-refresh": "^0.10.0",
218 | "react-refresh-typescript": "^2.0.2",
219 | "react-test-renderer": "^17.0.2",
220 | "rimraf": "^3.0.2",
221 | "sass": "^1.43.4",
222 | "sass-loader": "^12.3.0",
223 | "style-loader": "^3.3.1",
224 | "tailwindcss": "^2.2.19",
225 | "terser-webpack-plugin": "^5.2.4",
226 | "ts-jest": "^27.0.7",
227 | "ts-loader": "^9.2.6",
228 | "ts-node": "^10.4.0",
229 | "typescript": "^4.4.4",
230 | "url-loader": "^4.1.1",
231 | "webpack": "^5.60.0",
232 | "webpack-bundle-analyzer": "^4.5.0",
233 | "webpack-cli": "^4.9.1",
234 | "webpack-dev-server": "^4.4.0",
235 | "webpack-merge": "^5.8.0"
236 | },
237 | "dependencies": {
238 | "electron-debug": "^3.2.0",
239 | "electron-log": "^4.4.1",
240 | "electron-updater": "^4.3.9",
241 | "history": "4.x.x",
242 | "react": "^17.0.2",
243 | "react-dom": "^17.0.2",
244 | "react-router-dom": "^5.3.0",
245 | "regenerator-runtime": "^0.13.9"
246 | },
247 | "devEngines": {
248 | "node": ">=14.x",
249 | "npm": ">=7.x"
250 | },
251 | "collective": {
252 | "url": "https://opencollective.com/electron-react-boilerplate-594"
253 | },
254 | "browserslist": [],
255 | "prettier": {
256 | "overrides": [
257 | {
258 | "files": [
259 | ".prettierrc",
260 | ".eslintrc"
261 | ],
262 | "options": {
263 | "parser": "json"
264 | }
265 | }
266 | ],
267 | "singleQuote": true
268 | },
269 | "husky": {
270 | "hooks": {
271 | "pre-commit": "lint-staged"
272 | }
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 2.1.0
2 |
3 | - Migrate to `css-minifier-webpack-plugin`
4 |
5 | # 2.0.1
6 |
7 | ## Fixes
8 |
9 | - Fix broken css linking in production build
10 |
11 | # 2.0.0
12 |
13 | ## Breaking Changes
14 |
15 | - drop redux
16 | - remove counter example app
17 | - simplify directory structure
18 | - move `dll` dir to `.erb` dir
19 | - fix icon/font import paths
20 | - migrate to `react-refresh` from `react-hot-loader`
21 | - migrate to webpack@5
22 | - migrate to electron@11
23 | - remove e2e tests and testcafe integration
24 | - rename `app` dir to more conventional `src` dir
25 | - rename `resources` dir to `assets`
26 | - simplify npm scripts
27 | - drop stylelint
28 | - simplify styling of boilerplate app
29 | - remove `START_HOT` env variable
30 | - notarize support
31 | - landing page boilerplate
32 | - docs updates
33 | - restore removed debugging support
34 |
35 | # 1.4.0
36 |
37 | - Migrate to `eslint-config-erb@2`
38 | - Rename `dev` npm script to `start`
39 | - GitHub Actions: only publish GitHub releases when on master branch
40 |
41 | # 1.3.1
42 |
43 | - Fix sass building bug ([#2540](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2540))
44 | - Fix CI bug related to E2E tests and network timeouts
45 | - Move automated dependency PRs to `next` ([#2554](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2554))
46 | - Bump dependencies to patch semver
47 |
48 | # 1.3.0
49 |
50 | - Fixes E2E tests ([#2516](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2516))
51 | - Fixes preload entrypoint ([#2503](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2503))
52 | - Downgrade to `electron@8`
53 | - Bump dependencies to latest semver
54 |
55 | # 1.2.0
56 |
57 | - Migrate to redux toolkit
58 | - Lazy load routes with react suspense
59 | - Drop support for azure-pipelines and use only github actions
60 | - Bump all deps to latest semver
61 | - Remove `test-e2e` script from tests (blocked on release of https://github.com/DevExpress/testcafe-browser-provider-electron/pull/65)
62 | - Swap `typed-css-modules-webpack-plugin` for `typings-for-css-modules-loader`
63 | - Use latest version of `eslint-config-erb`
64 | - Remove unnecessary file extensions from ts exclude
65 | - Add experimental support for vscode debugging
66 | - Revert https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2365 as default for users, provide as opt in option
67 |
68 | # 1.1.0
69 |
70 | - Fix #2402
71 | - Simplify configs (https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2406)
72 |
73 | # 1.0.0
74 |
75 | - Migrate to TypeScript from Flow ([#2363](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2363))
76 | - Use browserslist for `@babel/preset-env` targets ([#2368](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2368))
77 | - Use preload script, disable `nodeIntegration` in renderer process for [improved security](https://www.electronjs.org/docs/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content) ([#2365](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2365))
78 | - Add support for azure pipelines ([#2369](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2369))
79 | - Disable sourcemaps in production
80 |
81 | # 0.18.1 (2019.12.12)
82 |
83 | - Fix HMR env bug ([#2343](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2343))
84 | - Bump all deps to latest semver
85 | - Bump to `electron@7`
86 |
87 | # 0.18.0 (2019.11.19)
88 |
89 | - Bump electron to `electron@6` (`electron@7` introduces breaking changes to testcafe end to end tests)
90 | - Revert back to [two `package.json` structure](https://www.electron.build/tutorials/two-package-structure)
91 | - Bump all deps to latest semver
92 |
93 | # 0.17.1 (2018.11.20)
94 |
95 | - Fix `yarn test-e2e` and testcafe for single package.json structure
96 | - Fixes incorrect path in `yarn start` script
97 | - Bumped deps
98 | - Bump g++ in travis
99 | - Change clone arguments to clone only master
100 | - Change babel config to target current electron version
101 |
102 | For full change list, see https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2021
103 |
104 | # 0.17.0 (2018.10.30)
105 |
106 | - upgraded to `babel@7` (thanks to @vikr01 🎉🎉🎉)
107 | - migrated from [two `package.json` structure](https://www.electron.build/tutorials/two-package-structure) (thanks to @HyperSprite!)
108 | - initial auto update support (experimental)
109 | - migrate from greenkeeper to [renovate](https://renovatebot.com)
110 | - added issue template
111 | - use `babel-preset-env` to target current electron version
112 | - add [opencollective](https://opencollective.com/electron-react-boilerplate-594) banner message display in postinstall script (help support ERB 🙏)
113 | - fix failing ci issues
114 |
115 | # 0.16.0 (2018.10.3)
116 |
117 | - removed unused dependencies
118 | - migrate from `react-redux-router` to `connect-react-router`
119 | - move webpack configs to `./webpack` dir
120 | - use `g++` on travis when testing linux
121 | - migrate from `spectron` to `testcafe` for e2e tests
122 | - add linting support for config styles
123 | - changed stylelint config
124 | - temporarily disabled flow in appveyor to make ci pass
125 | - added necessary infra to publish releases from ci
126 |
127 | # 0.15.0 (2018.8.25)
128 |
129 | - Performance: cache webpack uglify results
130 | - Feature: add start minimized feature
131 | - Feature: lint and fix styles with prettier and stylelint
132 | - Feature: add greenkeeper support
133 |
134 | # 0.14.0 (2018.5.24)
135 |
136 | - Improved CI timings
137 | - Migrated README commands to yarn from npm
138 | - Improved vscode config
139 | - Updated all dependencies to latest semver
140 | - Fix `electron-rebuild` script bug
141 | - Migrated to `mini-css-extract-plugin` from `extract-text-plugin`
142 | - Added `optimize-css-assets-webpack-plugin`
143 | - Run `prettier` on json, css, scss, and more filetypes
144 |
145 | # 0.13.3 (2018.5.24)
146 |
147 | - Add git precommit hook, when git commit will use `prettier` to format git add code
148 | - Add format code function in `lint-fix` npm script which can use `prettier` to format project js code
149 |
150 | # 0.13.2 (2018.1.31)
151 |
152 | - Hot Module Reload (HMR) fixes
153 | - Bumped all dependencies to latest semver
154 | - Prevent error propagation of `CheckNativeDeps` script
155 |
156 | # 0.13.1 (2018.1.13)
157 |
158 | - Hot Module Reload (HMR) fixes
159 | - Bumped all dependencies to latest semver
160 | - Fixed electron-rebuild script
161 | - Fixed tests scripts to run on all platforms
162 | - Skip redux logs in console in test ENV
163 |
164 | # 0.13.0 (2018.1.6)
165 |
166 | #### Additions
167 |
168 | - Add native dependencies check on postinstall
169 | - Updated all dependencies to latest semver
170 |
171 | # 0.12.0 (2017.7.8)
172 |
173 | #### Misc
174 |
175 | - Removed `babel-polyfill`
176 | - Renamed and alphabetized npm scripts
177 |
178 | #### Breaking
179 |
180 | - Changed node dev `__dirname` and `__filename` to node built in fn's (https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/1035)
181 | - Renamed `src/bundle.js` to `src/renderer.prod.js` for consistency
182 | - Renamed `dll/vendor.js` to `dll/renderer.dev.dll.js` for consistency
183 |
184 | #### Additions
185 |
186 | - Enable node_modules cache on CI
187 |
188 | # 0.11.2 (2017.5.1)
189 |
190 | Yay! Another patch release. This release mostly includes refactorings and router bug fixes. Huge thanks to @anthonyraymond!
191 |
192 | ⚠️ Windows electron builds are failing because of [this issue](https://github.com/electron/electron/issues/9321). This is not an issue with the boilerplate ⚠️
193 |
194 | #### Breaking
195 |
196 | - **Renamed `./src/main.development.js` => `./src/main.{dev,prod}.js`:** [#963](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/963)
197 |
198 | #### Fixes
199 |
200 | - **Fixed reloading when not on `/` path:** [#958](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/958) [#949](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/949)
201 |
202 | #### Additions
203 |
204 | - **Added support for stylefmt:** [#960](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/960)
205 |
206 | # 0.11.1 (2017.4.23)
207 |
208 | You can now debug the production build with devtools like so:
209 |
210 | ```
211 | DEBUG_PROD=true npm run package
212 | ```
213 |
214 | 🎉🎉🎉
215 |
216 | #### Additions
217 |
218 | - **Added support for debugging production build:** [#fab245a](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/941/commits/fab245a077d02a09630f74270806c0c534a4ff95)
219 |
220 | #### Bug Fixes
221 |
222 | - **Fixed bug related to importing native dependencies:** [#933](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/933)
223 |
224 | #### Improvements
225 |
226 | - **Updated all deps to latest semver**
227 |
228 | # 0.11.0 (2017.4.19)
229 |
230 | Here's the most notable changes since `v0.10.0`. Its been about a year since a release has been pushed. Expect a new release to be published every 3-4 weeks.
231 |
232 | #### Breaking Changes
233 |
234 | - **Dropped support for node < 6**
235 | - **Refactored webpack config files**
236 | - **Migrate to two-package.json project structure**
237 | - **Updated all devDeps to latest semver**
238 | - **Migrated to Jest:** [#768](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/768)
239 | - **Migrated to `react-router@4`**
240 | - **Migrated to `electron-builder@4`**
241 | - **Migrated to `webpack@2`**
242 | - **Migrated to `react-hot-loader@3`**
243 | - **Changed default live reload server PORT to `1212` from `3000`**
244 |
245 | #### Additions
246 |
247 | - **Added support for Yarn:** [#451](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/451)
248 | - **Added support for Flow:** [#425](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/425)
249 | - **Added support for stylelint:** [#911](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/911)
250 | - **Added support for electron-builder:** [#876](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/876)
251 | - **Added optional support for SASS:** [#880](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/880)
252 | - **Added support for eslint-plugin-flowtype:** [#911](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/911)
253 | - **Added support for appveyor:** [#280](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/280)
254 | - **Added support for webpack dlls:** [#860](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/860)
255 | - **Route based code splitting:** [#884](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/884)
256 | - **Added support for Webpack Bundle Analyzer:** [#922](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/922)
257 |
258 | #### Improvements
259 |
260 | - **Parallelize renderer and main build processes when running `npm run build`**
261 | - **Dynamically generate electron app menu**
262 | - **Improved vscode integration:** [#856](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/856)
263 |
264 | #### Bug Fixes
265 |
266 | - **Fixed hot module replacement race condition bug:** [#917](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/917) [#920](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/920)
267 |
268 | # 0.10.0 (2016.4.18)
269 |
270 | #### Improvements
271 |
272 | - **Use Babel in main process with Webpack build:** [#201](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/201)
273 | - **Change targets to built-in support by webpack:** [#197](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/197)
274 | - **use es2015 syntax for webpack configs:** [#195](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/195)
275 | - **Open application when webcontent is loaded:** [#192](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/192)
276 | - **Upgraded dependencies**
277 |
278 | #### Bug fixed
279 |
280 | - **Fix `npm list electron-prebuilt` in package.js:** [#188](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/188)
281 |
282 | # 0.9.0 (2016.3.23)
283 |
284 | #### Improvements
285 |
286 | - **Added [redux-logger](https://github.com/fcomb/redux-logger)**
287 | - **Upgraded [react-router-redux](https://github.com/reactjs/react-router-redux) to v4**
288 | - **Upgraded dependencies**
289 | - **Added `npm run dev` command:** [#162](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/162)
290 | - **electron to v0.37.2**
291 |
292 | #### Breaking Changes
293 |
294 | - **css module as default:** [#154](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/154).
295 | - **set default NODE_ENV to production:** [#140](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/140)
296 |
297 | # 0.8.0 (2016.2.17)
298 |
299 | #### Bug fixed
300 |
301 | - **Fix lint errors**
302 | - **Fix Webpack publicPath for production builds**: [#119](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/119).
303 | - **package script now chooses correct OS icon extension**
304 |
305 | #### Improvements
306 |
307 | - **babel 6**
308 | - **Upgrade Dependencies**
309 | - **Enable CSS source maps**
310 | - **Add json-loader**: [#128](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/128).
311 | - **react-router 2.0 and react-router-redux 3.0**
312 |
313 | # 0.7.1 (2015.12.27)
314 |
315 | #### Bug fixed
316 |
317 | - **Fixed npm script on windows 10:** [#103](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/103).
318 | - **history and react-router version bump**: [#109](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/109), [#110](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/110).
319 |
320 | #### Improvements
321 |
322 | - **electron 0.36**
323 |
324 | # 0.7.0 (2015.12.16)
325 |
326 | #### Bug fixed
327 |
328 | - **Fixed process.env.NODE_ENV variable in webpack:** [#74](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/74).
329 | - **add missing object-assign**: [#76](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/76).
330 | - **packaging in npm@3:** [#77](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/77).
331 | - **compatibility in windows:** [#100](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/100).
332 | - **disable chrome debugger in production env:** [#102](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/102).
333 |
334 | #### Improvements
335 |
336 | - **redux**
337 | - **css-modules**
338 | - **upgrade to react-router 1.x**
339 | - **unit tests**
340 | - **e2e tests**
341 | - **travis-ci**
342 | - **upgrade to electron 0.35.x**
343 | - **use es2015**
344 | - **check dev engine for node and npm**
345 |
346 | # 0.6.5 (2015.11.7)
347 |
348 | #### Improvements
349 |
350 | - **Bump style-loader to 0.13**
351 | - **Bump css-loader to 0.22**
352 |
353 | # 0.6.4 (2015.10.27)
354 |
355 | #### Improvements
356 |
357 | - **Bump electron-debug to 0.3**
358 |
359 | # 0.6.3 (2015.10.26)
360 |
361 | #### Improvements
362 |
363 | - **Initialize ExtractTextPlugin once:** [#64](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/64).
364 |
365 | # 0.6.2 (2015.10.18)
366 |
367 | #### Bug fixed
368 |
369 | - **Babel plugins production env not be set properly:** [#57](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/57).
370 |
371 | # 0.6.1 (2015.10.17)
372 |
373 | #### Improvements
374 |
375 | - **Bump electron to v0.34.0**
376 |
377 | # 0.6.0 (2015.10.16)
378 |
379 | #### Breaking Changes
380 |
381 | - **From react-hot-loader to react-transform**
382 |
383 | # 0.5.2 (2015.10.15)
384 |
385 | #### Improvements
386 |
387 | - **Run tests with babel-register:** [#29](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/29).
388 |
389 | # 0.5.1 (2015.10.12)
390 |
391 | #### Bug fixed
392 |
393 | - **Fix #51:** use `path.join(__dirname` instead of `./`.
394 |
395 | # 0.5.0 (2015.10.11)
396 |
397 | #### Improvements
398 |
399 | - **Simplify webpack config** see [#50](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/50).
400 |
401 | #### Breaking Changes
402 |
403 | - **webpack configs**
404 | - **port changed:** changed default port from 2992 to 3000.
405 | - **npm scripts:** remove `start-dev` and `dev-server`. rename `hot-dev-server` to `hot-server`.
406 |
407 | # 0.4.3 (2015.9.22)
408 |
409 | #### Bug fixed
410 |
411 | - **Fix #45 zeromq crash:** bump version of `electron-prebuilt`.
412 |
413 | # 0.4.2 (2015.9.15)
414 |
415 | #### Bug fixed
416 |
417 | - **run start-hot breaks chrome refresh(CTRL+R) (#42)**: bump `electron-debug` to `0.2.1`
418 |
419 | # 0.4.1 (2015.9.11)
420 |
421 | #### Improvements
422 |
423 | - **use electron-prebuilt version for packaging (#33)**
424 |
425 | # 0.4.0 (2015.9.5)
426 |
427 | #### Improvements
428 |
429 | - **update dependencies**
430 |
431 | # 0.3.0 (2015.8.31)
432 |
433 | #### Improvements
434 |
435 | - **eslint-config-airbnb**
436 |
437 | # 0.2.10 (2015.8.27)
438 |
439 | #### Features
440 |
441 | - **custom placeholder icon**
442 |
443 | #### Improvements
444 |
445 | - **electron-renderer as target:** via [webpack-target-electron-renderer](https://github.com/chentsulin/webpack-target-electron-renderer)
446 |
447 | # 0.2.9 (2015.8.18)
448 |
449 | #### Bug fixed
450 |
451 | - **Fix hot-reload**
452 |
453 | # 0.2.8 (2015.8.13)
454 |
455 | #### Improvements
456 |
457 | - **bump electron-debug**
458 | - **babelrc**
459 | - **organize webpack scripts**
460 |
461 | # 0.2.7 (2015.7.9)
462 |
463 | #### Bug fixed
464 |
465 | - **defaultProps:** fix typos.
466 |
467 | # 0.2.6 (2015.7.3)
468 |
469 | #### Features
470 |
471 | - **menu**
472 |
473 | #### Bug fixed
474 |
475 | - **package.js:** include webpack build.
476 |
477 | # 0.2.5 (2015.7.1)
478 |
479 | #### Features
480 |
481 | - **NPM Script:** support multi-platform
482 | - **package:** `--all` option
483 |
484 | # 0.2.4 (2015.6.9)
485 |
486 | #### Bug fixed
487 |
488 | - **Eslint:** typo, [#17](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/17) and improve `.eslintrc`
489 |
490 | # 0.2.3 (2015.6.3)
491 |
492 | #### Features
493 |
494 | - **Package Version:** use latest release electron version as default
495 | - **Ignore Large peerDependencies**
496 |
497 | #### Bug fixed
498 |
499 | - **Npm Script:** typo, [#6](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/6)
500 | - **Missing css:** [#7](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/7)
501 |
502 | # 0.2.2 (2015.6.2)
503 |
504 | #### Features
505 |
506 | - **electron-debug**
507 |
508 | #### Bug fixed
509 |
510 | - **Webpack:** add `.json` and `.node` to extensions for imitating node require.
511 | - **Webpack:** set `node_modules` to externals for native module support.
512 |
513 | # 0.2.1 (2015.5.30)
514 |
515 | #### Bug fixed
516 |
517 | - **Webpack:** #1, change build target to `atom`.
518 |
519 | # 0.2.0 (2015.5.30)
520 |
521 | #### Features
522 |
523 | - **Ignore:** `test`, `tools`, `release` folder and devDependencies in `package.json`.
524 | - **Support asar**
525 | - **Support icon**
526 |
527 | # 0.1.0 (2015.5.27)
528 |
529 | #### Features
530 |
531 | - **Webpack:** babel, react-hot, ...
532 | - **Flux:** actions, api, components, containers, stores..
533 | - **Package:** darwin (osx), linux and win32 (windows) platform.
534 |
--------------------------------------------------------------------------------