As a developer, I often need to switch host in my work, so that I can quickly develop and test in different environments. Ali has an iHost, which is easy to use, but unfortunately it is not open. After leaving, I did not find a better host switching tool, so I simply wrote one myself. The project is open source

Code address, welcome to ridicule.

The technology used

As a desktop application, eletron is the first choice for front-end development and react technology stack is the front-end framework.

The project is generated based on the electron- replay 0-Boilerplate, and the technologies used include:

  1. react 16.x
  2. redux 4.x
  3. redux-thunk 2.x
  4. react-router 4.x
  5. ant-design 3.x
  6. reselect 3.x
  7. redux-actions 3.x
  8. webpack 4.x
  9. node-sass 4.x

Main logic and presentation

In fact, the difficulty of the whole application is not much. The main task is to generate some entries and read and write the host file based on the activation state of the entries. The basic operations are as follows:

Functional design

  1. Three TAB page
    • Host setting page: add, delete, change and check host entries
    • Current host: Displays the current host in effect
    • Original host: a copy of the original host manuscript will be backed up after the application is started for restoration
  2. The host Settings
    • The ability to create a host entry and write the corresponding host
    • Host can be added, deleted, or checked
    • You can also create a host group for unified management
    • Click the checkbox on the left, and the host setting of the active state will change in real time. However, a 2-second delay is set during editing to avoid frequent reading and writing of files during the continuous input process

To operate the host file, you need to change the permissions of the /private/etc/host file and /private/etc directory. Therefore, the application will pop up when entering the computer user password popup window for authorization.

Record several major technology uses

Story – the actions and bindActionCreators

Redux-based projects are often criticized for the complexity of actions, reducer and too much template code. Redux-actions is a great tool for solving this problem. Learn how to use it yourself. It is important to note, however, that redux’s bindActionCreators does not support actionCreator with nested objects, for example

const actionsCreators = {
	add: function() {xx}, change: {changeTitle:function() {
			xx
		},
		changeDate: function() {
			xx
		}
	}
}

const { add, change } = bindActionCreators(actionsCreator, dispatch)


Copy the code

In this case, the actionCreators in change will not be successfully bound because the actionCreators generated by Redux-Actions can be nested. So the original bindActionCreators and Redux-Actions were uncomfortable. BindActionCreators was slightly rewritten in the project to support nesting.

reselect

For some computation-based data, it is not a good idea to store both raw and computed data on the Store. It is easy to miss because of the double update required for each update. Redux is different from Mobx, which has computed decorators for computing attributes. This is where Reselect comes in. Not only does it solve the problem of computational data, but its greater value is the ability to reduce double calculations, as rerender computations of large amounts of data can be done without double calculations with the same inputs. The problem is that there’s an extra layer of selectors that can drive some people crazy

State persistent storage

In order to keep the previous state every time you open the App, the entire store layer needs to be stored, so we write a simple Redux middleware with the help of electron-json-storage:


import storage from 'electron-json-storage'; // Synchronize store to a file's persistent storage middleware, Const storageState = store => dispatch => action => {dispatch(action); const nextState = store.getState(); const { menuTree, checkedKeys } = nextState.host.menus; const { systemHost } = nextState.host.systemHost; const defaultDataPath = storage.getDefaultDataPath(); const dataPath = storage.getDataPath(); console.log('paths:', defaultDataPath, dataPath);
  
  storage.set('HostState-xu', nextState); // create a hoststate-xu. json file that is as unique as possible and does not conflict with other applications};export default storageState;

Copy the code

Each action change is synchronized to remain state.

electron-react-boilerplateBring the pit point

The flow and eslint

Flow and some ESLint rules can cause a lot of confusion and extra work up front, so you can modify some of the rules at your discretion, but for Flow and ESLint personally, it is recommended to use them more often to reduce the number of minor problems later on.

But the eslint-import plug-in in the project had problems setting the alias in conjunction with Webpack, and the Webpack alias configuration did not take effect for the test cases either.

A few key processing points:

  1. .eslintrc should be changed to.eslintrc.js
  2. Reference. Eslintrc. JspathNeed to berequireCan’t,import
  3. Eslintrc.js will show up in vscodeEslint serverThe problem of failure is mainly due to the projectwebpack.config.render.dev.jsEnvironment variables have been detected by themselvesCheckNodeEnv('development')Comment out this line of code.

The electron-react- Boilerplate is constantly updated, the configuration of the latest VERSION of ESLint may be inconsistent with that of me at that time, and some processing experience may also be outdated, list some reference issues: #620,#1321,# 1509

Quotation of pictures

The path of reference image is always a problem after packaging, the official suggestion is to introduce the image in the render process through require, go through the loader to generate base64 image, directly through the path.join and __dirname to generate path in the development environment is no problem. However, an error will be reported after packaging.

However, there are also problems in using pictures in the main process, and the appeal scheme is not effective. So far, no solution has been found, and relevant issue has been proposed

The static resource path like electron may have some problems in the development and generation environment, which needs further study. Students who know about it can give advice.

The shell of the exec

I wanted to use ShellJS to do some command processing, but FOUND that it has the electron compatibility problem

Because the requirements are not complex, they are handled directly by child_process.exec.

A weird packing problem

Due to the introduction of pictures, I will often package verification and find a problem when I come back. If there is a problem with the packaging last time, I will package again after modification and find that the program still cannot be started. At this time, I need to disconnect the network and start it successfully. It’s not clear why.

Stage summary

It is interesting to write a complete electron project for solving practical needs for the first time. In the follow-up project, we still need to do some tests, continuous integration and automatic update processing. At present, we are not experienced enough, gay friends in the community, please give us your advice and learn together!