diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 3cecd05..0000000 --- a/.dockerignore +++ /dev/null @@ -1,48 +0,0 @@ -# Logs -logs -*.log - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release -.eslintcache - -# Dependency directory -# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git -node_modules - -# OSX -.DS_Store - -# App packaged -release -app/main.prod.js -app/main.prod.js.map -app/renderer.prod.js -app/renderer.prod.js.map -app/style.css -app/style.css.map -dist -dll -main.js -main.js.map - -.idea -npm-debug.log.* -.*.dockerfile diff --git a/configs/.eslintrc b/.erb/configs/.eslintrc similarity index 100% rename from configs/.eslintrc rename to .erb/configs/.eslintrc diff --git a/configs/webpack.config.base.js b/.erb/configs/webpack.config.base.js similarity index 78% rename from configs/webpack.config.base.js rename to .erb/configs/webpack.config.base.js index 98088c3..adff345 100644 --- a/configs/webpack.config.base.js +++ b/.erb/configs/webpack.config.base.js @@ -4,7 +4,7 @@ import path from 'path'; import webpack from 'webpack'; -import { dependencies as externals } from '../app/package.json'; +import { dependencies as externals } from '../../src/package.json'; export default { externals: [...Object.keys(externals || {})], @@ -25,7 +25,7 @@ export default { }, output: { - path: path.join(__dirname, '..', 'app'), + path: path.join(__dirname, '../../src'), // https://github.com/webpack/webpack/issues/1114 libraryTarget: 'commonjs2', }, @@ -35,11 +35,7 @@ export default { */ resolve: { extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'], - modules: [path.join(__dirname, '..', 'app'), 'node_modules'], - }, - - optimization: { - namedModules: true, + modules: [path.join(__dirname, '../src'), 'node_modules'], }, plugins: [ diff --git a/configs/webpack.config.eslint.js b/.erb/configs/webpack.config.eslint.js similarity index 71% rename from configs/webpack.config.eslint.js rename to .erb/configs/webpack.config.eslint.js index bd00048..cf829f8 100644 --- a/configs/webpack.config.eslint.js +++ b/.erb/configs/webpack.config.eslint.js @@ -1,4 +1,4 @@ /* eslint import/no-unresolved: off, import/no-self-import: off */ -require('@babel/register'); +require('../.erb/scripts/node_modules/@babel/register'); module.exports = require('./webpack.config.renderer.dev.babel').default; diff --git a/configs/webpack.config.main.prod.babel.js b/.erb/configs/webpack.config.main.prod.babel.js similarity index 72% rename from configs/webpack.config.main.prod.babel.js rename to .erb/configs/webpack.config.main.prod.babel.js index c50767c..b2d1f9a 100644 --- a/configs/webpack.config.main.prod.babel.js +++ b/.erb/configs/webpack.config.main.prod.babel.js @@ -8,36 +8,36 @@ import { merge } from 'webpack-merge'; import TerserPlugin from 'terser-webpack-plugin'; import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; import baseConfig from './webpack.config.base'; -import CheckNodeEnv from '../internals/scripts/CheckNodeEnv'; -import DeleteSourceMaps from '../internals/scripts/DeleteSourceMaps'; +import CheckNodeEnv from '../scripts/CheckNodeEnv'; +import DeleteSourceMaps from '../scripts/DeleteSourceMaps'; CheckNodeEnv('production'); DeleteSourceMaps(); +const devtoolsConfig = process.env.DEBUG_PROD === 'true' ? { + devtool: 'source-map' +} : {}; + export default merge(baseConfig, { - devtool: process.env.DEBUG_PROD === 'true' ? 'source-map' : 'none', + ...devtoolsConfig, mode: 'production', target: 'electron-main', - entry: './app/main.dev.ts', + entry: './src/main.dev.ts', output: { - path: path.join(__dirname, '..'), - filename: './app/main.prod.js', + path: path.join(__dirname, '../../'), + filename: './src/main.prod.js', }, optimization: { - minimizer: process.env.E2E_BUILD - ? [] - : [ - new TerserPlugin({ - parallel: true, - sourceMap: true, - cache: true, - }), - ], + minimizer: [ + new TerserPlugin({ + parallel: true, + }), + ] }, plugins: [ @@ -60,7 +60,6 @@ export default merge(baseConfig, { NODE_ENV: 'production', DEBUG_PROD: false, START_MINIMIZED: false, - E2E_BUILD: false, }), ], diff --git a/configs/webpack.config.renderer.dev.babel.js b/.erb/configs/webpack.config.renderer.dev.babel.js similarity index 85% rename from configs/webpack.config.renderer.dev.babel.js rename to .erb/configs/webpack.config.renderer.dev.babel.js index b4c452f..7e372f9 100644 --- a/configs/webpack.config.renderer.dev.babel.js +++ b/.erb/configs/webpack.config.renderer.dev.babel.js @@ -1,10 +1,3 @@ -/** - * Build config for development electron renderer process that uses - * Hot-Module-Replacement - * - * https://webpack.js.org/concepts/hot-module-replacement/ - */ - import path from 'path'; import fs from 'fs'; import webpack from 'webpack'; @@ -12,7 +5,8 @@ import chalk from 'chalk'; import { merge } from 'webpack-merge'; import { spawn, execSync } from 'child_process'; import baseConfig from './webpack.config.base'; -import CheckNodeEnv from '../internals/scripts/CheckNodeEnv'; +import CheckNodeEnv from '../scripts/CheckNodeEnv'; +import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; // When an ESLint server is running, we can't set the NODE_ENV so we'll check if it's // at the dev webpack config is not accidentally run in a production environment @@ -22,8 +16,8 @@ if (process.env.NODE_ENV === 'production') { const port = process.env.PORT || 1212; const publicPath = `http://localhost:${port}/dist`; -const dll = path.join(__dirname, '..', 'dll'); -const manifest = path.resolve(dll, 'renderer.json'); +const dllDir = path.join(__dirname, '../dll'); +const manifest = path.resolve(dllDir, 'renderer.json'); const requiredByDLLConfig = module.parent.filename.includes( 'webpack.config.renderer.dev.dll' ); @@ -31,7 +25,7 @@ const requiredByDLLConfig = module.parent.filename.includes( /** * Warn if the DLL is not built */ -if (!requiredByDLLConfig && !(fs.existsSync(dll) && fs.existsSync(manifest))) { +if (!requiredByDLLConfig && !(fs.existsSync(dllDir) && fs.existsSync(manifest))) { console.log( chalk.black.bgYellow.bold( 'The DLL files are missing. Sit back while we build them for you with "yarn build-dll"' @@ -50,10 +44,7 @@ export default merge(baseConfig, { entry: [ 'core-js', 'regenerator-runtime/runtime', - ...(process.env.PLAIN_HMR ? [] : ['react-hot-loader/patch']), - `webpack-dev-server/client?http://localhost:${port}/`, - 'webpack/hot/only-dev-server', - require.resolve('../app/index.tsx'), + require.resolve('../../src/index.tsx'), ], output: { @@ -63,6 +54,20 @@ export default merge(baseConfig, { module: { rules: [ + { + test: /\.[jt]sx?$/, + exclude: /node_modules/, + use: [ + { + loader: require.resolve('babel-loader'), + options: { + plugins: [ + require.resolve('react-refresh/babel'), + ].filter(Boolean), + }, + }, + ], + }, { test: /\.global\.css$/, use: [ @@ -194,24 +199,16 @@ export default merge(baseConfig, { }, ], }, - resolve: { - alias: { - 'react-dom': '@hot-loader/react-dom', - }, - }, plugins: [ + requiredByDLLConfig ? null : new webpack.DllReferencePlugin({ - context: path.join(__dirname, '..', 'dll'), + context: path.join(__dirname, '../dll'), manifest: require(manifest), sourceType: 'var', }), - new webpack.HotModuleReplacementPlugin({ - multiStep: true, - }), - new webpack.NoEmitOnErrorsPlugin(), /** @@ -233,6 +230,8 @@ export default merge(baseConfig, { new webpack.LoaderOptionsPlugin({ debug: true, }), + + new ReactRefreshWebpackPlugin(), ], node: { @@ -261,16 +260,14 @@ export default merge(baseConfig, { disableDotRule: false, }, before() { - if (process.env.START_HOT) { - console.log('Starting Main Process...'); - spawn('npm', ['run', 'start-main-dev'], { + console.log('Starting Main Process...'); + spawn('npm', ['run', 'start:main'], { shell: true, env: process.env, stdio: 'inherit', }) .on('close', (code) => process.exit(code)) .on('error', (spawnError) => console.error(spawnError)); - } }, }, }); diff --git a/configs/webpack.config.renderer.dev.dll.babel.js b/.erb/configs/webpack.config.renderer.dev.dll.babel.js similarity index 81% rename from configs/webpack.config.renderer.dev.dll.babel.js rename to .erb/configs/webpack.config.renderer.dev.dll.babel.js index fa0b172..401c022 100644 --- a/configs/webpack.config.renderer.dev.dll.babel.js +++ b/.erb/configs/webpack.config.renderer.dev.dll.babel.js @@ -6,15 +6,15 @@ import webpack from 'webpack'; import path from 'path'; import { merge } from 'webpack-merge'; import baseConfig from './webpack.config.base'; -import { dependencies } from '../package.json'; -import CheckNodeEnv from '../internals/scripts/CheckNodeEnv'; +import { dependencies } from '../../package.json'; +import CheckNodeEnv from '../scripts/CheckNodeEnv'; CheckNodeEnv('development'); -const dist = path.join(__dirname, '..', 'dll'); +const dist = path.join(__dirname, '../dll'); export default merge(baseConfig, { - context: path.join(__dirname, '..'), + context: path.join(__dirname, '../..'), devtool: 'eval', @@ -62,9 +62,9 @@ export default merge(baseConfig, { new webpack.LoaderOptionsPlugin({ debug: true, options: { - context: path.join(__dirname, '..', 'app'), + context: path.join(__dirname, '../../src'), output: { - path: path.join(__dirname, '..', 'dll'), + path: path.join(__dirname, '../dll'), }, }, }), diff --git a/configs/webpack.config.renderer.prod.babel.js b/.erb/configs/webpack.config.renderer.prod.babel.js similarity index 88% rename from configs/webpack.config.renderer.prod.babel.js rename to .erb/configs/webpack.config.renderer.prod.babel.js index 0fc0185..ce3cd73 100644 --- a/configs/webpack.config.renderer.prod.babel.js +++ b/.erb/configs/webpack.config.renderer.prod.babel.js @@ -10,30 +10,31 @@ import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; import { merge } from 'webpack-merge'; import TerserPlugin from 'terser-webpack-plugin'; import baseConfig from './webpack.config.base'; -import CheckNodeEnv from '../internals/scripts/CheckNodeEnv'; -import DeleteSourceMaps from '../internals/scripts/DeleteSourceMaps'; +import CheckNodeEnv from '../scripts/CheckNodeEnv'; +import DeleteSourceMaps from '../scripts/DeleteSourceMaps'; CheckNodeEnv('production'); DeleteSourceMaps(); +const devtoolsConfig = process.env.DEBUG_PROD === 'true' ? { + devtool: 'source-map' +} : {}; + export default merge(baseConfig, { - devtool: process.env.DEBUG_PROD === 'true' ? 'source-map' : 'none', + ...devtoolsConfig, mode: 'production', - target: - process.env.E2E_BUILD || process.env.ERB_SECURE !== 'true' - ? 'electron-renderer' - : 'electron-preload', + target: 'electron-renderer', entry: [ 'core-js', 'regenerator-runtime/runtime', - path.join(__dirname, '..', 'app/index.tsx'), + path.join(__dirname, '../../src/index.tsx'), ], output: { - path: path.join(__dirname, '..', 'app/dist'), + path: path.join(__dirname, '../../src/dist'), publicPath: './dist/', filename: 'renderer.prod.js', }, @@ -46,9 +47,6 @@ export default merge(baseConfig, { use: [ { loader: MiniCssExtractPlugin.loader, - options: { - publicPath: './', - }, }, { loader: 'css-loader', @@ -181,13 +179,10 @@ export default merge(baseConfig, { }, optimization: { - minimizer: process.env.E2E_BUILD - ? [] - : [ + minimizer: + [ new TerserPlugin({ parallel: true, - sourceMap: true, - cache: true, }), new OptimizeCSSAssetsPlugin({ cssProcessorOptions: { @@ -213,7 +208,6 @@ export default merge(baseConfig, { new webpack.EnvironmentPlugin({ NODE_ENV: 'production', DEBUG_PROD: false, - E2E_BUILD: false, }), new MiniCssExtractPlugin({ diff --git a/.erb/img/erb-banner.png b/.erb/img/erb-banner.png new file mode 100644 index 0000000..1d92246 Binary files /dev/null and b/.erb/img/erb-banner.png differ diff --git a/internals/img/erb-logo.png b/.erb/img/erb-logo.png similarity index 100% rename from internals/img/erb-logo.png rename to .erb/img/erb-logo.png diff --git a/internals/img/eslint-padded-90.png b/.erb/img/eslint-padded-90.png similarity index 100% rename from internals/img/eslint-padded-90.png rename to .erb/img/eslint-padded-90.png diff --git a/internals/img/eslint-padded.png b/.erb/img/eslint-padded.png similarity index 100% rename from internals/img/eslint-padded.png rename to .erb/img/eslint-padded.png diff --git a/internals/img/eslint.png b/.erb/img/eslint.png similarity index 100% rename from internals/img/eslint.png rename to .erb/img/eslint.png diff --git a/internals/img/jest-padded-90.png b/.erb/img/jest-padded-90.png similarity index 100% rename from internals/img/jest-padded-90.png rename to .erb/img/jest-padded-90.png diff --git a/internals/img/jest-padded.png b/.erb/img/jest-padded.png similarity index 100% rename from internals/img/jest-padded.png rename to .erb/img/jest-padded.png diff --git a/internals/img/jest.png b/.erb/img/jest.png similarity index 100% rename from internals/img/jest.png rename to .erb/img/jest.png diff --git a/internals/img/js-padded.png b/.erb/img/js-padded.png similarity index 100% rename from internals/img/js-padded.png rename to .erb/img/js-padded.png diff --git a/internals/img/js.png b/.erb/img/js.png similarity index 100% rename from internals/img/js.png rename to .erb/img/js.png diff --git a/internals/img/npm.png b/.erb/img/npm.png similarity index 100% rename from internals/img/npm.png rename to .erb/img/npm.png diff --git a/internals/img/react-padded-90.png b/.erb/img/react-padded-90.png similarity index 100% rename from internals/img/react-padded-90.png rename to .erb/img/react-padded-90.png diff --git a/internals/img/react-padded.png b/.erb/img/react-padded.png similarity index 100% rename from internals/img/react-padded.png rename to .erb/img/react-padded.png diff --git a/internals/img/react-router-padded-90.png b/.erb/img/react-router-padded-90.png similarity index 100% rename from internals/img/react-router-padded-90.png rename to .erb/img/react-router-padded-90.png diff --git a/internals/img/react-router-padded.png b/.erb/img/react-router-padded.png similarity index 100% rename from internals/img/react-router-padded.png rename to .erb/img/react-router-padded.png diff --git a/internals/img/react-router.png b/.erb/img/react-router.png similarity index 100% rename from internals/img/react-router.png rename to .erb/img/react-router.png diff --git a/internals/img/react.png b/.erb/img/react.png similarity index 100% rename from internals/img/react.png rename to .erb/img/react.png diff --git a/internals/img/webpack-padded-90.png b/.erb/img/webpack-padded-90.png similarity index 100% rename from internals/img/webpack-padded-90.png rename to .erb/img/webpack-padded-90.png diff --git a/internals/img/webpack-padded.png b/.erb/img/webpack-padded.png similarity index 100% rename from internals/img/webpack-padded.png rename to .erb/img/webpack-padded.png diff --git a/internals/img/webpack.png b/.erb/img/webpack.png similarity index 100% rename from internals/img/webpack.png rename to .erb/img/webpack.png diff --git a/internals/img/yarn-padded-90.png b/.erb/img/yarn-padded-90.png similarity index 100% rename from internals/img/yarn-padded-90.png rename to .erb/img/yarn-padded-90.png diff --git a/internals/img/yarn-padded.png b/.erb/img/yarn-padded.png similarity index 100% rename from internals/img/yarn-padded.png rename to .erb/img/yarn-padded.png diff --git a/internals/img/yarn.png b/.erb/img/yarn.png similarity index 100% rename from internals/img/yarn.png rename to .erb/img/yarn.png diff --git a/internals/mocks/fileMock.js b/.erb/mocks/fileMock.js similarity index 100% rename from internals/mocks/fileMock.js rename to .erb/mocks/fileMock.js diff --git a/internals/scripts/.eslintrc b/.erb/scripts/.eslintrc similarity index 100% rename from internals/scripts/.eslintrc rename to .erb/scripts/.eslintrc diff --git a/internals/scripts/BabelRegister.js b/.erb/scripts/BabelRegister.js similarity index 76% rename from internals/scripts/BabelRegister.js rename to .erb/scripts/BabelRegister.js index bf41c5a..b3642f5 100644 --- a/internals/scripts/BabelRegister.js +++ b/.erb/scripts/BabelRegister.js @@ -2,5 +2,5 @@ const path = require('path'); require('@babel/register')({ extensions: ['.es6', '.es', '.jsx', '.js', '.mjs', '.ts', '.tsx'], - cwd: path.join(__dirname, '..', '..'), + cwd: path.join(__dirname, '../..'), }); diff --git a/internals/scripts/CheckBuildsExist.js b/.erb/scripts/CheckBuildsExist.js similarity index 78% rename from internals/scripts/CheckBuildsExist.js rename to .erb/scripts/CheckBuildsExist.js index 802394c..e538f39 100644 --- a/internals/scripts/CheckBuildsExist.js +++ b/.erb/scripts/CheckBuildsExist.js @@ -3,14 +3,9 @@ import path from 'path'; import chalk from 'chalk'; import fs from 'fs'; -const mainPath = path.join(__dirname, '..', '..', 'app', 'main.prod.js'); +const mainPath = path.join(__dirname, '../../src/main.prod.js'); const rendererPath = path.join( - __dirname, - '..', - '..', - 'app', - 'dist', - 'renderer.prod.js' + __dirname, '../../src/dist/renderer.prod.js' ); if (!fs.existsSync(mainPath)) { diff --git a/internals/scripts/CheckNativeDep.js b/.erb/scripts/CheckNativeDep.js similarity index 96% rename from internals/scripts/CheckNativeDep.js rename to .erb/scripts/CheckNativeDep.js index 1f0c439..a5889de 100644 --- a/internals/scripts/CheckNativeDep.js +++ b/.erb/scripts/CheckNativeDep.js @@ -34,7 +34,7 @@ ${chalk.whiteBright.bgGreen.bold('yarn remove your-package')} 'Then, instead of installing the package to the root "./package.json":' )} ${chalk.whiteBright.bgRed.bold('yarn add your-package')} - ${chalk.bold('Install the package to "./app/package.json"')} + ${chalk.bold('Install the package to "./src/package.json"')} ${chalk.whiteBright.bgGreen.bold('cd ./app && yarn add your-package')} Read more about native dependencies at: ${chalk.bold( diff --git a/internals/scripts/CheckNodeEnv.js b/.erb/scripts/CheckNodeEnv.js similarity index 100% rename from internals/scripts/CheckNodeEnv.js rename to .erb/scripts/CheckNodeEnv.js diff --git a/internals/scripts/CheckPortInUse.js b/.erb/scripts/CheckPortInUse.js similarity index 100% rename from internals/scripts/CheckPortInUse.js rename to .erb/scripts/CheckPortInUse.js diff --git a/.erb/scripts/DeleteSourceMaps.js b/.erb/scripts/DeleteSourceMaps.js new file mode 100644 index 0000000..efb48d3 --- /dev/null +++ b/.erb/scripts/DeleteSourceMaps.js @@ -0,0 +1,7 @@ +import path from 'path'; +import rimraf from 'rimraf'; + +export default function deleteSourceMaps() { + rimraf.sync(path.join(__dirname, '../../src/dist/*.js.map')); + rimraf.sync(path.join(__dirname, '../../src/*.js.map')); +} diff --git a/internals/scripts/ElectronRebuild.js b/.erb/scripts/ElectronRebuild.js similarity index 72% rename from internals/scripts/ElectronRebuild.js rename to .erb/scripts/ElectronRebuild.js index e89a4f6..ce277d7 100644 --- a/internals/scripts/ElectronRebuild.js +++ b/.erb/scripts/ElectronRebuild.js @@ -1,9 +1,9 @@ import path from 'path'; import { execSync } from 'child_process'; import fs from 'fs'; -import { dependencies } from '../../app/package.json'; +import { dependencies } from '../../src/package.json'; -const nodeModulesPath = path.join(__dirname, '..', '..', 'app', 'node_modules'); +const nodeModulesPath = path.join(__dirname, '../../src/node_modules'); if ( Object.keys(dependencies || {}).length > 0 && @@ -16,7 +16,7 @@ if ( ? electronRebuildCmd.replace(/\//g, '\\') : electronRebuildCmd; execSync(cmd, { - cwd: path.join(__dirname, '..', '..', 'app'), + cwd: path.join(__dirname, '../../src'), stdio: 'inherit', }); } diff --git a/.erb/scripts/Notarize.js b/.erb/scripts/Notarize.js new file mode 100644 index 0000000..4767e49 --- /dev/null +++ b/.erb/scripts/Notarize.js @@ -0,0 +1,28 @@ +const { notarize } = require('electron-notarize'); +const { build } = require('../../package.json'); + +exports.default = async function notarizeMacos(context) { + const { electronPlatformName, appOutDir } = context; + if (electronPlatformName !== 'darwin') { + return; + } + + if (!process.env.CI) { + console.warn('Skipping notarizing step. Packaging is not running in CI'); + return; + } + + if (!('APPLE_ID' in process.env && 'APPLE_ID_PASS' in process.env)) { + console.warn('Skipping notarizing step. APPLE_ID and APPLE_ID_PASS env variables must be set'); + return; + } + + const appName = context.packager.appInfo.productFilename; + + await notarize({ + appBundleId: build.appId, + appPath: `${appOutDir}/${appName}.app`, + appleId: process.env.APPLE_ID, + appleIdPassword: process.env.APPLE_ID_PASS, + }); +}; diff --git a/.eslintignore b/.eslintignore index 6e2dcea..fe55df3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -32,13 +32,13 @@ node_modules # App packaged release -app/*.main.prod.js -app/main.prod.js -app/main.prod.js.map -app/renderer.prod.js -app/renderer.prod.js.map -app/style.css -app/style.css.map +src/*.main.prod.js +src/main.prod.js +src/main.prod.js.map +src/renderer.prod.js +src/renderer.prod.js.map +src/style.css +src/style.css.map dist dll main.js diff --git a/.eslintrc.js b/.eslintrc.js index f1451b5..fee6d71 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,7 +16,7 @@ module.exports = { // See https://github.com/benmosher/eslint-plugin-import/issues/1396#issuecomment-575727774 for line below node: {}, webpack: { - config: require.resolve('./configs/webpack.config.eslint.js'), + config: require.resolve('./.erb/configs/webpack.config.eslint.js'), }, }, 'import/parsers': { diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 748af5f..769ba9d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,20 +14,20 @@ jobs: os: [macos-latest] steps: - - name: Check out Git repository + - name: Checkout git repo uses: actions/checkout@v1 - - name: Install Node.js, NPM and Yarn + - name: Install Node, NPM and Yarn uses: actions/setup-node@v1 with: node-version: 14 - - name: yarn install + - name: Install dependencies run: | yarn install - - name: Publish Releases + - name: Publish releases env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - yarn package-ci + yarn postinstall && yarn build && yarn electron-builder diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 550d0e3..70ba784 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,16 +31,3 @@ jobs: yarn lint yarn tsc yarn test - yarn build-e2e - - - if: matrix.os == 'ubuntu-latest' - run: | - Xvfb :99 & - disown -ar - echo "::set-env name=DISPLAY:::99" - # TODO: Testcafe e2e are broken because of: - # https://github.com/DevExpress/testcafe/issues/4512 - # Tests are currently broken on linux and macos - # - if: matrix.os == 'windows-latest' - # run: | - # yarn test-e2e diff --git a/.gitignore b/.gitignore index 09c02bf..dd6c4e3 100644 --- a/.gitignore +++ b/.gitignore @@ -32,12 +32,12 @@ node_modules # App packaged release -app/main.prod.js -app/main.prod.js.map -app/renderer.prod.js -app/renderer.prod.js.map -app/style.css -app/style.css.map +src/main.prod.js +src/main.prod.js.map +src/renderer.prod.js +src/renderer.prod.js.map +src/style.css +src/style.css.map dist dll main.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 0dd5f43..1cefea1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,12 +2,12 @@ "version": "0.2.0", "configurations": [ { + "name": "Electron: Main", "type": "node", "request": "launch", - "name": "Electron: Main", "protocol": "inspector", "runtimeExecutable": "yarn", - "runtimeArgs": ["start-main-debug"], + "runtimeArgs": ["start:main --inspect=5858 --remote-debugging-port=9223"], "preLaunchTask": "Start Webpack Dev" }, { diff --git a/.vscode/settings.json b/.vscode/settings.json index 63e5500..9993f5e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,8 +3,6 @@ ".babelrc": "jsonc", ".eslintrc": "jsonc", ".prettierrc": "jsonc", - ".stylelintrc": "json", - ".dockerignore": "ignore", ".eslintignore": "ignore" }, @@ -15,9 +13,9 @@ "search.exclude": { ".git": true, ".eslintcache": true, - "app/dist": true, - "app/main.prod.js": true, - "app/main.prod.js.map": true, + "src/dist": true, + "src/main.prod.js": true, + "src/main.prod.js.map": true, "bower_components": true, "dll": true, "release": true, diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ca39a07..42cb740 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,7 +4,7 @@ { "type": "npm", "label": "Start Webpack Dev", - "script": "start-renderer-dev", + "script": "start:renderer", "options": { "cwd": "${workspaceFolder}" }, diff --git a/CHANGELOG.md b/CHANGELOG.md index d3cdf69..4dcfc71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -144,7 +144,7 @@ For full change list, see https://github.com/electron-react-boilerplate/electron #### Breaking - Changed node dev `__dirname` and `__filename` to node built in fn's (https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/1035) -- Renamed `app/bundle.js` to `app/renderer.prod.js` for consistency +- Renamed `src/bundle.js` to `src/renderer.prod.js` for consistency - Renamed `dll/vendor.js` to `dll/renderer.dev.dll.js` for consistency #### Additions @@ -159,7 +159,7 @@ Yay! Another patch release. This release mostly includes refactorings and router #### Breaking -- **Renamed `./app/main.development.js` => `./app/main.{dev,prod}.js`:** [#963](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/963) +- **Renamed `./src/main.development.js` => `./src/main.{dev,prod}.js`:** [#963](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/963) #### Fixes diff --git a/README.md b/README.md index 5f940a1..d937e69 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,13 @@ - +

- Electron React Boilerplate uses Electron, React, Redux, React Router, Webpack and React Hot Loader for rapid application development (HMR). + Electron React Boilerplate uses Electron, React, React Router, Webpack and React Fast Refresh.


-
- - - - - - - -
- -
-
-
[![Build Status][github-actions-status]][github-actions-url] @@ -28,7 +15,6 @@ [![DevDependency Status][david-dev-image]][david-dev-url] [![Github Tag][github-tag-image]][github-tag-url] -[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/electron-react-blpt) [![OpenCollective](https://opencollective.com/electron-react-boilerplate/backers/badge.svg)](#backers) [![OpenCollective](https://opencollective.com/electron-react-boilerplate/sponsors/badge.svg)](#sponsors) [![Good first issues open][good-first-issue-image]][good-first-issue-url] @@ -50,7 +36,7 @@ yarn ## Starting Development -Start the app in the `dev` environment. This starts the renderer process in [**hot-module-replacement**](https://webpack.js.org/guides/hmr-react/) mode and starts a webpack dev server that sends hot updates to the renderer process: +Start the app in the `dev` environment: ```bash yarn start diff --git a/app/.testcafe-electron-rc b/app/.testcafe-electron-rc deleted file mode 100644 index 708ef19..0000000 --- a/app/.testcafe-electron-rc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "mainWindowUrl": "./app.html", - "appPath": "." -} diff --git a/app/Routes.tsx b/app/Routes.tsx deleted file mode 100644 index aec0c9b..0000000 --- a/app/Routes.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/* eslint react/jsx-props-no-spreading: off */ -import React from 'react'; -import { Switch, Route } from 'react-router-dom'; -import routes from './constants/routes.json'; -import App from './containers/App'; -import HomePage from './containers/HomePage'; - -// Lazily load routes and code split with webpack -const LazyCounterPage = React.lazy(() => - import(/* webpackChunkName: "CounterPage" */ './containers/CounterPage') -); - -const CounterPage = (props: Record) => ( - Loading...}> - - -); - -export default function Routes() { - return ( - - - - - - - ); -} diff --git a/app/app.global.css b/app/app.global.css deleted file mode 100644 index aa238b9..0000000 --- a/app/app.global.css +++ /dev/null @@ -1,47 +0,0 @@ -/* - * @NOTE: Prepend a `~` to css file paths that are in your node_modules - * See https://github.com/webpack-contrib/sass-loader#imports - */ -@import '~@fortawesome/fontawesome-free/css/all.css'; - -body { - position: relative; - color: white; - height: 100vh; - background-color: #232c39; - background-image: linear-gradient( - 45deg, - rgba(0, 216, 255, 0.5) 10%, - rgba(0, 1, 127, 0.7) - ); - font-family: Arial, Helvetica, Helvetica Neue, serif; - overflow-y: hidden; -} - -h2 { - margin: 0; - font-size: 2.25rem; - font-weight: bold; - letter-spacing: -0.025em; - color: #fff; -} - -p { - font-size: 24px; -} - -li { - list-style: none; -} - -a { - color: white; - opacity: 0.75; - text-decoration: none; -} - -a:hover { - opacity: 1; - text-decoration: none; - cursor: pointer; -} diff --git a/app/app.icns b/app/app.icns deleted file mode 100644 index 4f3cbba..0000000 Binary files a/app/app.icns and /dev/null differ diff --git a/app/components/Home.css b/app/components/Home.css deleted file mode 100644 index 978a02a..0000000 --- a/app/components/Home.css +++ /dev/null @@ -1,14 +0,0 @@ -.container { - position: absolute; - top: 30%; - left: 10px; - text-align: center; -} - -.container h2 { - font-size: 5rem; -} - -.container a { - font-size: 1.4rem; -} diff --git a/app/components/Home.tsx b/app/components/Home.tsx deleted file mode 100644 index db007a9..0000000 --- a/app/components/Home.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; -import routes from '../constants/routes.json'; -import styles from './Home.css'; - -export default function Home(): JSX.Element { - return ( -
-

Home

- to Counter -
- ); -} diff --git a/app/components/css.d.ts b/app/components/css.d.ts deleted file mode 100644 index af3d030..0000000 --- a/app/components/css.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -declare module '*.scss' { - const content: { [className: string]: string }; - export default content; -} - -declare module '*.css' { - const content: { [className: string]: string }; - export default content; -} diff --git a/app/constants/routes.json b/app/constants/routes.json deleted file mode 100644 index 00770b0..0000000 --- a/app/constants/routes.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "HOME": "/", - "COUNTER": "/counter" -} diff --git a/app/containers/App.tsx b/app/containers/App.tsx deleted file mode 100644 index eedf2d6..0000000 --- a/app/containers/App.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React, { ReactNode } from 'react'; - -type Props = { - children: ReactNode; -}; - -export default function App(props: Props) { - const { children } = props; - return <>{children}; -} diff --git a/app/containers/CounterPage.tsx b/app/containers/CounterPage.tsx deleted file mode 100644 index 2f70b68..0000000 --- a/app/containers/CounterPage.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; -import Counter from '../features/counter/Counter'; - -export default function CounterPage() { - return ; -} diff --git a/app/containers/HomePage.tsx b/app/containers/HomePage.tsx deleted file mode 100644 index 4c7158c..0000000 --- a/app/containers/HomePage.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; -import Home from '../components/Home'; - -export default function HomePage() { - return ; -} diff --git a/app/containers/Root.tsx b/app/containers/Root.tsx deleted file mode 100644 index fef53fa..0000000 --- a/app/containers/Root.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import { Provider } from 'react-redux'; -import { ConnectedRouter } from 'connected-react-router'; -import { hot } from 'react-hot-loader/root'; -import { History } from 'history'; -import { Store } from '../store'; -import Routes from '../Routes'; - -type Props = { - store: Store; - history: History; -}; - -const Root = ({ store, history }: Props) => ( - - - - - -); - -export default hot(Root); diff --git a/app/features/counter/Counter.css b/app/features/counter/Counter.css deleted file mode 100644 index 31588ba..0000000 --- a/app/features/counter/Counter.css +++ /dev/null @@ -1,37 +0,0 @@ -.backButton { - position: absolute; -} - -.counter { - position: absolute; - top: 30%; - left: 45%; - font-size: 10rem; - font-weight: bold; - letter-spacing: -0.025em; -} - -.btnGroup { - position: relative; - top: 500px; - width: 480px; - margin: 0 auto; -} - -.btn { - font-size: 1.6rem; - font-weight: bold; - background-color: #fff; - border-radius: 50%; - margin: 10px; - width: 100px; - height: 100px; - opacity: 0.7; - cursor: pointer; - font-family: Arial, Helvetica, Helvetica Neue, sans-serif; -} - -.btn:hover { - color: white; - background-color: rgba(0, 0, 0, 0.5); -} diff --git a/app/features/counter/Counter.tsx b/app/features/counter/Counter.tsx deleted file mode 100644 index 1f39fce..0000000 --- a/app/features/counter/Counter.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React from 'react'; -import { useSelector, useDispatch } from 'react-redux'; -import { Link } from 'react-router-dom'; -import styles from './Counter.css'; -import routes from '../../constants/routes.json'; -import { - increment, - decrement, - incrementIfOdd, - incrementAsync, - selectCount, -} from './counterSlice'; - -export default function Counter() { - const dispatch = useDispatch(); - const value = useSelector(selectCount); - return ( -
-
- - - -
-
- {value} -
-
- - - - -
-
- ); -} diff --git a/app/features/counter/counterSlice.ts b/app/features/counter/counterSlice.ts deleted file mode 100644 index 385d180..0000000 --- a/app/features/counter/counterSlice.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { createSlice } from '@reduxjs/toolkit'; -// eslint-disable-next-line import/no-cycle -import { AppThunk, RootState } from '../../store'; - -const counterSlice = createSlice({ - name: 'counter', - initialState: { value: 0 }, - reducers: { - increment: (state) => { - state.value += 1; - }, - decrement: (state) => { - state.value -= 1; - }, - }, -}); - -export const { increment, decrement } = counterSlice.actions; - -export const incrementIfOdd = (): AppThunk => { - return (dispatch, getState) => { - const state = getState(); - if (state.counter.value % 2 === 0) { - return; - } - dispatch(increment()); - }; -}; - -export const incrementAsync = (delay = 1000): AppThunk => (dispatch) => { - setTimeout(() => { - dispatch(increment()); - }, delay); -}; - -export default counterSlice.reducer; - -export const selectCount = (state: RootState) => state.counter.value; diff --git a/app/index.tsx b/app/index.tsx deleted file mode 100644 index 4e5c01e..0000000 --- a/app/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React, { Fragment } from 'react'; -import { render } from 'react-dom'; -import { AppContainer as ReactHotAppContainer } from 'react-hot-loader'; -import { history, configuredStore } from './store'; -import './app.global.css'; - -const store = configuredStore(); - -const AppContainer = process.env.PLAIN_HMR ? Fragment : ReactHotAppContainer; - -document.addEventListener('DOMContentLoaded', () => { - // eslint-disable-next-line global-require - const Root = require('./containers/Root').default; - render( - - - , - document.getElementById('root') - ); -}); diff --git a/app/main.prod.js.LICENSE b/app/main.prod.js.LICENSE deleted file mode 100644 index 15036cd..0000000 --- a/app/main.prod.js.LICENSE +++ /dev/null @@ -1 +0,0 @@ -/*! http://mths.be/fromcodepoint v0.1.0 by @mathias */ diff --git a/app/rootReducer.ts b/app/rootReducer.ts deleted file mode 100644 index 35ea3e6..0000000 --- a/app/rootReducer.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { combineReducers } from 'redux'; -import { connectRouter } from 'connected-react-router'; -import { History } from 'history'; -// eslint-disable-next-line import/no-cycle -import counterReducer from './features/counter/counterSlice'; - -export default function createRootReducer(history: History) { - return combineReducers({ - router: connectRouter(history), - counter: counterReducer, - }); -} diff --git a/app/store.ts b/app/store.ts deleted file mode 100644 index b218d50..0000000 --- a/app/store.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { configureStore, getDefaultMiddleware, Action } from '@reduxjs/toolkit'; -import { createHashHistory } from 'history'; -import { routerMiddleware } from 'connected-react-router'; -import { createLogger } from 'redux-logger'; -import { ThunkAction } from 'redux-thunk'; -// eslint-disable-next-line import/no-cycle -import createRootReducer from './rootReducer'; - -export const history = createHashHistory(); -const rootReducer = createRootReducer(history); -export type RootState = ReturnType; - -const router = routerMiddleware(history); -const middleware = [...getDefaultMiddleware(), router]; - -const excludeLoggerEnvs = ['test', 'production']; -const shouldIncludeLogger = !excludeLoggerEnvs.includes( - process.env.NODE_ENV || '' -); - -if (shouldIncludeLogger) { - const logger = createLogger({ - level: 'info', - collapsed: true, - }); - middleware.push(logger); -} - -export const configuredStore = (initialState?: RootState) => { - // Create Store - const store = configureStore({ - reducer: rootReducer, - middleware, - preloadedState: initialState, - }); - - if (process.env.NODE_ENV === 'development' && module.hot) { - module.hot.accept( - './rootReducer', - // eslint-disable-next-line global-require - () => store.replaceReducer(require('./rootReducer').default) - ); - } - return store; -}; -export type Store = ReturnType; -export type AppThunk = ThunkAction>; diff --git a/app/utils/.gitkeep b/app/utils/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/assets/assets.d.ts b/assets/assets.d.ts new file mode 100644 index 0000000..9c17307 --- /dev/null +++ b/assets/assets.d.ts @@ -0,0 +1,14 @@ +declare module '*.svg' { + const content: any; + export default content; +} + +declare module '*.png' { + const content: any; + export default content; +} + +declare module '*.jpg' { + const content: any; + export default content; +} diff --git a/assets/entitlements.mac.plist b/assets/entitlements.mac.plist new file mode 100644 index 0000000..dad3e20 --- /dev/null +++ b/assets/entitlements.mac.plist @@ -0,0 +1,10 @@ + + + + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.allow-jit + + + diff --git a/resources/icon.icns b/assets/icon.icns similarity index 100% rename from resources/icon.icns rename to assets/icon.icns diff --git a/resources/icon.ico b/assets/icon.ico similarity index 100% rename from resources/icon.ico rename to assets/icon.ico diff --git a/resources/icon.png b/assets/icon.png similarity index 100% rename from resources/icon.png rename to assets/icon.png diff --git a/assets/icon.svg b/assets/icon.svg new file mode 100644 index 0000000..b064abf --- /dev/null +++ b/assets/icon.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/icons/1024x1024.png b/assets/icons/1024x1024.png similarity index 100% rename from resources/icons/1024x1024.png rename to assets/icons/1024x1024.png diff --git a/resources/icons/128x128.png b/assets/icons/128x128.png similarity index 100% rename from resources/icons/128x128.png rename to assets/icons/128x128.png diff --git a/resources/icons/16x16.png b/assets/icons/16x16.png similarity index 100% rename from resources/icons/16x16.png rename to assets/icons/16x16.png diff --git a/resources/icons/24x24.png b/assets/icons/24x24.png similarity index 100% rename from resources/icons/24x24.png rename to assets/icons/24x24.png diff --git a/resources/icons/256x256.png b/assets/icons/256x256.png similarity index 100% rename from resources/icons/256x256.png rename to assets/icons/256x256.png diff --git a/resources/icons/32x32.png b/assets/icons/32x32.png similarity index 100% rename from resources/icons/32x32.png rename to assets/icons/32x32.png diff --git a/resources/icons/48x48.png b/assets/icons/48x48.png similarity index 100% rename from resources/icons/48x48.png rename to assets/icons/48x48.png diff --git a/resources/icons/512x512.png b/assets/icons/512x512.png similarity index 100% rename from resources/icons/512x512.png rename to assets/icons/512x512.png diff --git a/resources/icons/64x64.png b/assets/icons/64x64.png similarity index 100% rename from resources/icons/64x64.png rename to assets/icons/64x64.png diff --git a/resources/icons/96x96.png b/assets/icons/96x96.png similarity index 100% rename from resources/icons/96x96.png rename to assets/icons/96x96.png diff --git a/babel.config.js b/babel.config.js index 4f7c1a0..618dae3 100644 --- a/babel.config.js +++ b/babel.config.js @@ -2,10 +2,7 @@ const developmentEnvironments = ['development', 'test']; -const developmentPlugins = [ - require('react-hot-loader/babel'), - require('@babel/plugin-transform-runtime'), -]; +const developmentPlugins = [require('@babel/plugin-transform-runtime')]; const productionPlugins = [ require('babel-plugin-dev-expression'), diff --git a/internals/img/erb-banner.png b/internals/img/erb-banner.png deleted file mode 100644 index cbc19d1..0000000 Binary files a/internals/img/erb-banner.png and /dev/null differ diff --git a/internals/img/redux-padded-90.png b/internals/img/redux-padded-90.png deleted file mode 100644 index 7d96a6a..0000000 Binary files a/internals/img/redux-padded-90.png and /dev/null differ diff --git a/internals/img/redux-padded.png b/internals/img/redux-padded.png deleted file mode 100644 index fd23430..0000000 Binary files a/internals/img/redux-padded.png and /dev/null differ diff --git a/internals/img/redux.png b/internals/img/redux.png deleted file mode 100755 index cda220d..0000000 Binary files a/internals/img/redux.png and /dev/null differ diff --git a/internals/scripts/CheckYarn.js b/internals/scripts/CheckYarn.js deleted file mode 100644 index aa5be8d..0000000 --- a/internals/scripts/CheckYarn.js +++ /dev/null @@ -1,5 +0,0 @@ -if (!/yarn\.js$/.test(process.env.npm_execpath || '')) { - console.warn( - "\u001b[33mYou don't seem to be using yarn. This could produce unexpected results.\u001b[39m" - ); -} diff --git a/internals/scripts/DeleteSourceMaps.js b/internals/scripts/DeleteSourceMaps.js deleted file mode 100644 index 91bbb3a..0000000 --- a/internals/scripts/DeleteSourceMaps.js +++ /dev/null @@ -1,7 +0,0 @@ -import path from 'path'; -import rimraf from 'rimraf'; - -export default function deleteSourceMaps() { - rimraf.sync(path.join(__dirname, '../../app/dist/*.js.map')); - rimraf.sync(path.join(__dirname, '../../app/*.js.map')); -} diff --git a/package.json b/package.json index 24dba73..8045e85 100644 --- a/package.json +++ b/package.json @@ -1,49 +1,28 @@ { "name": "electron-react-boilerplate", "productName": "ElectronReact", - "description": "Electron application boilerplate based on React, React Router, Webpack, React Hot Loader for rapid application development", + "description": "Electron application boilerplate based on React, React Router, Webpack, React Fast Refresh for rapid application development", "scripts": { - "build": "concurrently \"yarn build-main\" \"yarn build-renderer\"", - "build-dll": "cross-env NODE_ENV=development webpack --config ./configs/webpack.config.renderer.dev.dll.babel.js --colors", - "build-e2e": "cross-env E2E_BUILD=true yarn build", - "build-main": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.main.prod.babel.js --colors", - "build-renderer": "cross-env NODE_ENV=production webpack --config ./configs/webpack.config.renderer.prod.babel.js --colors", - "electron-rebuild": "electron-rebuild --parallel --force --types prod,dev,optional --module-dir app", + "build": "concurrently \"yarn build:main\" \"yarn build:renderer\"", + "build:main": "cross-env NODE_ENV=production webpack --config ./.erb/configs/webpack.config.main.prod.babel.js", + "build:renderer": "cross-env NODE_ENV=production webpack --config ./.erb/configs/webpack.config.renderer.prod.babel.js", + "rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir src", "lint": "cross-env NODE_ENV=development eslint . --cache --ext .js,.jsx,.ts,.tsx", - "lint-fix": "yarn --silent lint --fix; exit 0", - "lint-styles": "stylelint --ignore-path .eslintignore '**/*.*(css|scss)' --syntax scss", - "lint-styles-fix": "yarn --silent lint-styles --fix; exit 0", "package": "yarn build && electron-builder build --publish never", - "package-all": "yarn build && electron-builder build -mwl", - "package-ci": "yarn postinstall && yarn build && electron-builder --publish always", - "package-mac": "yarn build && electron-builder build --mac", - "package-linux": "yarn build && electron-builder build --linux", - "package-win": "yarn build && electron-builder build --win --x64", - "postinstall": "node -r @babel/register internals/scripts/CheckNativeDep.js && electron-builder install-app-deps && yarn build-dll && opencollective-postinstall", - "postlint-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{js,jsx,json,html,css,less,scss,yml}'", - "postlint-styles-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{css,scss}'", - "preinstall": "node ./internals/scripts/CheckYarn.js", - "prestart": "yarn build", - "start": "cross-env START_HOT=1 node -r @babel/register ./internals/scripts/CheckPortInUse.js && cross-env START_HOT=1 yarn start-renderer-dev", - "start:prod": "cross-env NODE_ENV=production electron ./app/main.prod.js", - "start-main-debug": "yarn start-main-dev --inspect=5858 --remote-debugging-port=9223", - "start-main-dev": "cross-env START_HOT=1 NODE_ENV=development electron -r ./internals/scripts/BabelRegister ./app/main.dev.ts", - "start-renderer-dev": "cross-env NODE_ENV=development webpack-dev-server --config configs/webpack.config.renderer.dev.babel.js", - "test": "cross-env BABEL_DISABLE_CACHE=1 jest", - "test-all": "yarn lint && yarn tsc && yarn build && yarn test", - "test-e2e": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test testcafe electron:./app ./test/e2e/HomePage.e2e.ts", - "test-e2e-live": "node -r @babel/register ./internals/scripts/CheckBuildsExist.js && cross-env NODE_ENV=test testcafe --live electron:./app ./test/e2e/HomePage.e2e.ts", - "test-watch": "yarn test --watch" + "postinstall": "node -r @babel/register .erb/scripts/CheckNativeDep.js && electron-builder install-app-deps && yarn cross-env NODE_ENV=development webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.babel.js && opencollective-postinstall && yarn-deduplicate yarn.lock", + "start": "node -r @babel/register ./.erb/scripts/CheckPortInUse.js && cross-env yarn start:renderer", + "start:main": "cross-env NODE_ENV=development electron -r ./.erb/scripts/BabelRegister ./src/main.dev.ts", + "start:renderer": "cross-env NODE_ENV=development webpack serve --config ./.erb/configs/webpack.config.renderer.dev.babel.js", + "test": "jest" }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ "cross-env NODE_ENV=development eslint --cache" ], - "{*.json,.{babelrc,eslintrc,prettierrc,stylelintrc}}": [ + "{*.json,.{babelrc,eslintrc,prettierrc}}": [ "prettier --ignore-path .eslintignore --parser json --write" ], "*.{css,scss}": [ - "stylelint --ignore-path .eslintignore --syntax scss --fix", "prettier --ignore-path .eslintignore --single-quote --write" ], "*.{html,md,yml}": [ @@ -52,15 +31,26 @@ }, "build": { "productName": "ElectronReact", - "appId": "org.develar.ElectronReact", + "appId": "org.erb.ElectronReact", "files": [ "dist/", "node_modules/", - "app.html", + "index.html", "main.prod.js", "main.prod.js.map", "package.json" ], + "afterSign": ".erb/scripts/Notarize.js", + "mac": { + "target": [ + "dmg" + ], + "type": "distribution", + "hardenedRuntime": true, + "entitlements": "assets/entitlements.mac.plist", + "entitlementsInherit": "assets/entitlements.mac.plist", + "gatekeeperAssess": false + }, "dmg": { "contents": [ { @@ -83,18 +73,17 @@ }, "linux": { "target": [ - "deb", - "rpm", "AppImage" ], "category": "Development" }, "directories": { - "buildResources": "resources", + "app": "src", + "buildResources": "assets", "output": "release" }, "extraResources": [ - "./resources/**" + "./assets/**" ], "publish": { "provider": "github", @@ -113,11 +102,6 @@ "url": "https://electron-react-boilerplate.js.org" }, "contributors": [ - { - "name": "Vikram Rangaraj", - "email": "vikr01@icloud.com", - "url": "https://github.com/vikr01" - }, { "name": "Amila Welihinda", "email": "amilajack@gmail.com", @@ -137,7 +121,6 @@ "electron", "boilerplate", "react", - "redux", "typescript", "ts", "sass", @@ -149,7 +132,7 @@ "jest": { "testURL": "http://localhost/", "moduleNameMapper": { - "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/internals/mocks/fileMock.js", + "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/.erb/mocks/fileMock.js", "\\.(css|less|sass|scss)$": "identity-obj-proxy" }, "moduleFileExtensions": [ @@ -161,15 +144,14 @@ ], "moduleDirectories": [ "node_modules", - "app/node_modules" + "src/node_modules" ], "setupFiles": [ - "./internals/scripts/CheckBuildsExist.js" + "./.erb/scripts/CheckBuildsExist.js" ] }, "devDependencies": { - "@amilajack/testcafe-browser-provider-electron": "^0.0.15-alpha.1", - "@babel/core": "^7.12.3", + "@babel/core": "^7.12.9", "@babel/plugin-proposal-class-properties": "^7.12.1", "@babel/plugin-proposal-decorators": "^7.12.1", "@babel/plugin-proposal-do-expressions": "^7.12.1", @@ -180,8 +162,7 @@ "@babel/plugin-proposal-json-strings": "^7.12.1", "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", - "@babel/plugin-proposal-numeric-separator": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.7", "@babel/plugin-proposal-pipeline-operator": "^7.12.1", "@babel/plugin-proposal-throw-expressions": "^7.12.1", "@babel/plugin-syntax-dynamic-import": "^7.8.3", @@ -189,30 +170,29 @@ "@babel/plugin-transform-react-constant-elements": "^7.12.1", "@babel/plugin-transform-react-inline-elements": "^7.12.1", "@babel/plugin-transform-runtime": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/preset-react": "^7.12.1", - "@babel/preset-typescript": "^7.12.1", + "@babel/preset-env": "^7.12.7", + "@babel/preset-react": "^7.12.7", + "@babel/preset-typescript": "^7.12.7", "@babel/register": "^7.12.1", + "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3", "@teamsupercell/typings-for-css-modules-loader": "^2.4.0", + "@testing-library/jest-dom": "^5.11.6", + "@testing-library/react": "^11.2.2", "@types/enzyme": "^3.10.5", "@types/enzyme-adapter-react-16": "^1.0.6", - "@types/history": "^4.7.7", + "@types/history": "4.7.6", "@types/jest": "^26.0.15", - "@types/node": "12", + "@types/node": "14.14.10", "@types/react": "^16.9.44", "@types/react-dom": "^16.9.9", - "@types/react-redux": "^7.1.9", - "@types/react-router": "^5.1.8", - "@types/react-router-dom": "^5.1.5", + "@types/react-router-dom": "^5.1.6", "@types/react-test-renderer": "^16.9.3", - "@types/redux-logger": "^3.0.8", - "@types/webpack": "^4.41.21", "@types/webpack-env": "^1.15.2", - "@typescript-eslint/eslint-plugin": "^3.6.1", - "@typescript-eslint/parser": "^3.6.1", + "@typescript-eslint/eslint-plugin": "^4.8.1", + "@typescript-eslint/parser": "^4.8.1", "babel-eslint": "^10.1.0", "babel-jest": "^26.1.0", - "babel-loader": "^8.1.0", + "babel-loader": "^8.2.2", "babel-plugin-dev-expression": "^0.2.2", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "browserslist-config-erb": "^0.0.1", @@ -220,83 +200,70 @@ "concurrently": "^5.3.0", "core-js": "^3.6.5", "cross-env": "^7.0.2", - "css-loader": "^3.6.0", + "css-loader": "^5.0.1", "detect-port": "^1.3.0", - "electron": "^8", + "electron": "^11.0.1", "electron-builder": "^22.3.6", - "electron-devtools-installer": "^2.2.4", - "electron-rebuild": "^1.10.0", + "electron-devtools-installer": "^3.1.1", + "electron-notarize": "^1.0.0", + "electron-rebuild": "^2.3.2", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.3", "enzyme-to-json": "^3.5.0", "eslint": "^7.5.0", "eslint-config-airbnb": "^18.2.0", - "eslint-config-airbnb-typescript": "^9.0.0", + "eslint-config-airbnb-typescript": "^12.0.0", "eslint-config-erb": "^2.0.0", "eslint-config-prettier": "^6.11.0", - "eslint-import-resolver-webpack": "^0.12.2", + "eslint-import-resolver-webpack": "^0.13.0", "eslint-plugin-compat": "^3.8.0", "eslint-plugin-import": "^2.22.0", - "eslint-plugin-jest": "^23.18.0", - "eslint-plugin-jsx-a11y": "6.3.1", + "eslint-plugin-jest": "^24.1.3", + "eslint-plugin-jsx-a11y": "6.4.1", "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-react": "^7.20.6", "eslint-plugin-react-hooks": "^4.0.8", - "eslint-plugin-testcafe": "^0.2.1", "file-loader": "^6.0.0", "husky": "^4.2.5", "identity-obj-proxy": "^3.0.0", "jest": "^26.1.0", "lint-staged": "^10.2.11", - "mini-css-extract-plugin": "^0.9.0", - "node-sass": "^4.14.1", + "mini-css-extract-plugin": "^1.3.1", + "node-sass": "^5.0.0", "opencollective-postinstall": "^2.0.3", "optimize-css-assets-webpack-plugin": "^5.0.3", "prettier": "^2.0.5", - "react-test-renderer": "^16.12.0", - "redux-logger": "^3.0.6", + "react-refresh": "^0.9.0", + "react-test-renderer": "^17.0.1", "rimraf": "^3.0.0", - "sass-loader": "^9.0.3", - "style-loader": "^1.2.1", - "stylelint": "^13.6.1", - "stylelint-config-prettier": "^8.0.2", - "stylelint-config-standard": "^20.0.0", - "terser-webpack-plugin": "^3.0.7", - "testcafe": "^1.8.8", - "testcafe-browser-provider-electron": "^0.0.15", - "testcafe-react-selectors": "^4.0.0", - "typescript": "^3.9.7", + "sass-loader": "^10.1.0", + "style-loader": "^2.0.0", + "terser-webpack-plugin": "^5.0.3", + "typescript": "^4.0.5", "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-bundle-analyzer": "^3.8.0", - "webpack-cli": "^3.3.12", + "webpack": "^5.5.1", + "webpack-bundle-analyzer": "^4.1.0", + "webpack-cli": "^4.2.0", "webpack-dev-server": "^3.11.0", - "webpack-merge": "^5.0.9" + "webpack-merge": "^5.4.0", + "yarn-deduplicate": "^3.1.0" }, "dependencies": { - "@fortawesome/fontawesome-free": "^5.15.0", - "@hot-loader/react-dom": "^16.13.0", - "@reduxjs/toolkit": "^1.4.0", - "connected-react-router": "^6.6.1", "electron-debug": "^3.1.0", "electron-log": "^4.2.4", "electron-updater": "^4.3.4", - "history": "^4.7.2", - "react": "^16.13.1", - "react-dom": "^16.12.0", - "react-hot-loader": "^4.12.21", - "react-redux": "^7.2.1", + "history": "^5.0.0", + "react": "^17.0.1", + "react-dom": "^17.0.1", "react-router-dom": "^5.2.0", - "redux": "^4.0.5", - "redux-thunk": "^2.3.0", "regenerator-runtime": "^0.13.5", "source-map-support": "^0.5.19" }, "devEngines": { - "node": ">=7.x", - "npm": ">=4.x", - "yarn": ">=0.21.3" + "node": ">=10.x", + "npm": ">=6.x", + "yarn": ">=1.21.3" }, "collective": { "url": "https://opencollective.com/electron-react-boilerplate-594" @@ -308,8 +275,7 @@ "files": [ ".prettierrc", ".babelrc", - ".eslintrc", - ".stylelintrc" + ".eslintrc" ], "options": { "parser": "json" @@ -318,12 +284,6 @@ ], "singleQuote": true }, - "stylelint": { - "extends": [ - "stylelint-config-standard", - "stylelint-config-prettier" - ] - }, "renovate": { "extends": [ "bliss" diff --git a/src/App.global.css b/src/App.global.css new file mode 100644 index 0000000..27effd1 --- /dev/null +++ b/src/App.global.css @@ -0,0 +1,74 @@ +/* + * @NOTE: Prepend a `~` to css file paths that are in your node_modules + * See https://github.com/webpack-contrib/sass-loader#imports + */ +@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap'); + +body { + position: relative; + color: white; + height: 100vh; + background: linear-gradient( + 200.96deg, + #fedc2a -29.09%, + #dd5789 51.77%, + #7a2c9e 129.35% + ); + font-family: 'Noto Sans JP', sans-serif; + overflow-y: hidden; + display: flex; + justify-content: center; + align-items: center; +} + +h2 { + margin: 0; + font-size: 2.25rem; + font-weight: bold; + letter-spacing: -0.025em; + color: #fff; +} + +button { + background-color: white; + padding: 10px 20px; + margin: 10px; + border-radius: 10px; + border: none; + appearance: none; + font-size: 1.3rem; + box-shadow: 0px 8px 28px -6px rgba(24, 39, 75, 0.12), + 0px 18px 88px -4px rgba(24, 39, 75, 0.14); + transition: transform ease-in 0.1s; +} + +button:hover { + transform: scale(1.1); +} + +p { + font-size: 24px; +} + +li { + list-style: none; +} + +a { + color: white; + opacity: 0.75; + text-decoration: none; +} + +a:hover { + opacity: 1; + text-decoration: none; + cursor: pointer; +} + +.Hello { + display: flex; + justify-content: center; + align-items: center; + margin: 20px 0; +} diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..66bb29b --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; +import icon from '../assets/icon.svg'; + +const Hello = () => { + return ( +
+
+ icon +
+

electron-react-boilerplate

+ +
+ ); +}; + +export default function App() { + return ( + + + + + + ); +} diff --git a/src/__tests__/App.test.tsx b/src/__tests__/App.test.tsx new file mode 100644 index 0000000..1a029da --- /dev/null +++ b/src/__tests__/App.test.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import '@testing-library/jest-dom'; +import { render } from '@testing-library/react'; +import App from '../App'; + +describe('App', () => { + it('should render', () => { + expect(render()).toBeTruthy(); + }); +}); diff --git a/app/app.html b/src/index.html similarity index 79% rename from app/app.html rename to src/index.html index 8db3498..b8284cd 100644 --- a/app/app.html +++ b/src/index.html @@ -5,10 +5,7 @@ Hello Electron React!