Electron OCR: OCR tool under MacOS based on electron + react + Tesseract


GitHub repo address
Article address
Download maxos Darwin x64

The author has not found too comfortable OCR tools on MacOS, resulting in a lot of things can only hand hit when reading, slightly annoyed. Just a few days ago, Tesseract was used to encapsulate one with electron. Here, we will briefly describe some pits and key points in the development process, and we will organize electron and make a series in the future


It looks like this:
Electron OCR: OCR tool under MacOS based on electron + react + Tesseract

Now install Tesseract on this machine:

brew install imagemagick
brew install tesseract --all-languages

Then download and open it directly.



  • use npm install or npm link to install dependences

  • use npm install -g electron-prebuilt to enable the global electron

Develop & Hot-Reloading

  • use npm start to start webpak hot-middle server

  • use npm run electron-test to use electron and set env to development


  • use npm run buildto generate list file for web modules

  • usenpm run package-osx to build and package into dmg

Web part

The web part of the author still adopts webpack + react + Redux (to be added), and the separate code of this part can be used for referenceMy webpack packageas well asWebpack-React-Redux-BoilerplateThis demonstration boilerplate. It should be noted that API and 0. X series have changed greatly after electron 1. X, and many projects on GitHub will not be available after upgrading to 1.2.0.

Environment construction supporting hot reload

Electron is actually a packaged approximate browser, so hot reload is not different from pure web development. It starts with a hot load server and monitors 3000 ports. However, what needs to be modified is that all scripts in electron must start from localhost:3000 Loading, the main modifications are as follows:

var devEntry = [
    //Modify the default loading address of WHM
//Modify the default public path prefix
config.output.publicPath  = ` http://localhost : ${port} / dist / '// public directory name

stay dev.html You also need to modify the address of the script loaded under:

    <title>Index For Debug</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<div id="root"></div>

Introducing native modules into the rendering process

const {dialog} = window.require('electron').remote;
const fs = window.require("fs");

First of all, in order to avoid webpack errors in packagingelectronIt does not exist. It is recommended to use all modules provided by node or electronwindow.requireIn this way, webpack ignores the introduction.

Native part

Create local window

 * Created by apple on 16/6/3.
const electron = require('electron');
//Used to control the application life cycle
const {app} = electron;
//Use to create a local window
const {BrowserWindow} = electron;

//Create a global reference for the window object, otherwise it may be automatically recycled by JavaScript garbage collection mechanism
let win;

 *@ function create window
function createWindow() {
    //Create a browser like window
    win = new BrowserWindow({width: 800, height: 600});

    //Load the application entry file. This file is a test file, so the test is loaded

    //Start the debugging tool. If it is in the development environment, you do not need to open it
    // win.webContents.openDevTools();

    //Set window close event
    win.on('closed', () => {
        //Because a global reference is set above, it is necessary to dereference the object here
        //If your application supports opening multiple windows, you can store all the references in an array and delete them dynamically here
        win = null;

//Callback after basic environment is ready
app.on('ready', createWindow);

//Callback after all windows are closed
app.on('window-all-closed', () => {
    //In OSX, although the main window is closed, the user still wants to use the menu bar, so there is no forced closing here
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {

//Callback after the application is reactivated
app.on('activate', () => {
    //Activate the application again after the menu bar in the dock is selected
    if (win === null) {


Generally speaking, there are three packaging methods recommended by electronelectron-packagerThis is a convenient tool. However, there is an egg pain problem. Electron can’t download it all the time. It doesn’t work with SS and proxychains4. Therefore, it is finally packaged in a programming way:

const exec = require('child_process').exec;

const argv = require('minimist')(process.argv.slice(2));

const platform = argv._ [0]; // target platform for compilation

const packager = require('electron-packager');

console.log ("Current NODE_ ENV = " +  process.env.NODE_ Env); // determine the compile time environment

const arch = "x64";

    dir: "./",
    out: `release/`,
    override: true,
    prune: true,
    download: {
        mirror: " https://npm.taobao.org/mirrors/electron/ "// set the download address of electron
}, function done_callback(err, appPaths) { /* … */

Then encapsulate the script into the package.json Chinese:

"package-osx": "npm run clean-electron && NODE_ENV=production node -r babel-register package.js darwin",

Avoid packing nodes_ modules

In web development, we will add dependencies such as react and Redux to the package.json However, the electron packer will change the node_ Modules are also packaged into the application. Then the code has been packaged and compiled into a unified JS script through webpack, so you can set thepruneTrue to avoid packing all of the dev dependencies. Similarly, we need to put all non local modules in dev dependencies.