/etoolbox

Collection of web developer utilities packaged as a desktop app

Primary LanguageTypeScript

Web Toolbox
Code author: amwebexpert@gmail.com
Icon made by: Jerry Low

Web Toolbox
Collection of web developer utilities

Powered by Create React App.

Features

Some screen captures of the implemented features...

Online demo

The app has been deployed and you can test it right here!. Whenever a feature is only available under Electron the UI element will be disabled or a corresponding popup message will be displayed. But most of the time we will try to make the feature available online.

Windows, Linux and MacOS versions

Since most of the features don't need to access desktop capabilities, Electron is actually not absolutely required. However, having a desktop application gives nice things like:

  • global OS shortcuts
  • dedicated OS window
  • ability to select exactly where a file will be stored whenever the SPA offers a Save As... button
  • etc.

Again feel free to try out the online demo before trying to package the Electron app for your platform :-)

Builded releases

The following installers are available under releases folder:

  • Windows: releases/Web Toolbox Setup <version>.exe
  • Linux: releases/Web Toolbox-<version>.AppImage
  • MacOS: releases/Web Toolbox-<version>.dmg

Build releases from source

To build a desktop version just get the source code and run the following command, which will package the installers for all the platforms:

npm install -g yarn
npm install
npm run electron:build:all

This creates the following installers:

  • Windows: build/Web Toolbox Setup <version>.exe
  • Linux: build/Web Toolbox-<version>.AppImage
  • MacOS: build/Web Toolbox-<version>.dmg

License

This project is licensed under the MIT license, Copyright (c) 2020 André Masson. For more information see LICENSE.md.

Useful links

react-router-dom

Interesting posts this app has been inspired by

Spinner

React-TypeScript-Electron sample with Create React App and Electron Builder

This project was bootstrapped with Create React App with --typescriptoption.

On the top of it, the following features have been added with relatively small changes:

  • TypeScript supports for Electron main process source code
  • Hot-reload support for Electron app
  • Electron Bulder support

Available Scripts in addition to the existing ones

npm run electron:dev

Runs the Electron app in the development mode.

The Electron app will reload if you make edits in the electron directory.
You will also see any lint errors in the console.

npm run electron:build

Builds the Electron app package for production to the dist folder.

Your Electron app is ready to be distributed!

Project directory structure

my-app/
├── package.json
│
## render process
├── tsconfig.json
├── public/
├── src/
│
## main process
├── electron/
│   ├── main.ts
│   └── tsconfig.json
│
## build output
├── build/
│   ├── index.html
│   ├── static/
│   │   ├── css/
│   │   └── js/
│   │
│   └── electron/
│      └── main.js
│
## distribution packges
└── dist/
    ├── mac/
    │   └── my-app.app
    └── my-app-0.1.0.dmg

Do it yourself from scratch

Generate a React project and install npm dependencies

create-react-app my-app --typescript
cd my-app
yarn add @types/electron-devtools-installer electron-devtools-installer electron-is-dev electron-reload
yarn add -D concurrently electron electron-builder wait-on

Make Electon main process source file

electron/tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "sourceMap": true,
    "strict": true,
    "outDir": "../build", # Output transpiled files to build/electron/
    "rootDir": "../",
    "noEmitOnError": true,
    "typeRoots": [
      "node_modules/@types"
    ]
  }
}

electron/main.ts

import { app, BrowserWindow } from 'electron';
import * as path from 'path';
import * as isDev from 'electron-is-dev';
import installExtension, { REACT_DEVELOPER_TOOLS } from "electron-devtools-installer";

let win: BrowserWindow | null = null;

function createWindow() {
  win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })

  if (isDev) {
    win.loadURL('http://localhost:3000/index.html');
  } else {
    // 'build/index.html'
    win.loadURL(`file://${__dirname}/../index.html`);
  }

  win.on('closed', () => win = null);

  // Hot Reloading
  if (isDev) {
    // 'node_modules/.bin/electronPath'
    require('electron-reload')(__dirname, {
      electron: path.join(__dirname, '..', '..', 'node_modules', '.bin', 'electron'),
      forceHardReset: true,
      hardResetMethod: 'exit'
    });
  }

  // DevTools
  installExtension(REACT_DEVELOPER_TOOLS)
    .then((name) => console.log(`Added Extension:  ${name}`))
    .catch((err) => console.log('An error occurred: ', err));

  if (isDev) {
    win.webContents.openDevTools();
  }
}

app.on('ready', createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});

Adjust package.json

Add properties for Electron

  "homepage": ".", # see https://create-react-app.dev/docs/deployment#serving-the-same-build-from-different-paths
  "main": "build/electron/main.js",

Add properties for Electron Builder

  "author": "Your Name",
  "description": "React-TypeScript-Electron sample with Create React App and Electron Builder",
  ...
  "build": {
    "extends": null, # see https://github.com/electron-userland/electron-builder/issues/2030#issuecomment-386720420
    "files": [
      "build/**/*"
    ],
    "directories": {
      "buildResources": "assets" # change the resource directory from 'build' to 'assets'
    }
  },

Add scripts

  "scripts": {
    "postinstall": "electron-builder install-app-deps",
    "electron:dev": "concurrently \"BROWSER=none yarn start\" \"wait-on http://localhost:3000 && tsc -p electron -w\" \"wait-on http://localhost:3000 && tsc -p electron && electron .\"",
    "electron:build": "yarn build && tsc -p electron && electron-builder",

Many thanks to the following articles!