In the process of the company’s development of downloaders, encountered some pits

1. Cancel the confirmation of the electron ejection window and determine the relationship between the cross of the system

Scenario: When the user exits the APP, it is necessary to prompt the user whether to confirm to exit. At this time, a popup window will appear. If you click yes, you will continue to exit and perform the callback; otherwise, you will not exit

Problem: click on the cross, the callback returns a value of 0, since the code written in order for the buttons of [‘ confirm ‘, ‘cancel’], click on the “confirm” when the corresponding response is 0, leads to click on the “confirm” and click on the behavior of the cross is consistent, so it is not correct, click the cross should be equal to cancel to exit.

// The problem code, click ok button will exit, click the upper right cross will exit
dialog.showMessageBox(mainWindow, { buttons: ['confirm'.'cancel'] }, (response) => { 	 if (reponse === 0) {
    // Perform exit operation}});// After modifying the code, click ok to exit, and click the cross in the upper right corner not to exit
dialog.showMessageBox(mainWindow, { buttons: ['cancel'.'confirm'] }, (response) => {
  if (response === 1) { 
    // Perform a confirmation exit operation}});Copy the code

2. The code in the child process is not executed after packaging

Scenario: During local development, a subprocess is used to download resources. However, the download fails after the subprocess is packaged, and events in the subprocess are not executed. The download process is blocked

Problem: When using the subprocess in electron, the subprocess is treated as an external dependency. After packaging, the subprocess code is not added to the package, which requires additional configuration. Solution: Configure the child process file

Note: This project scaffolding is based on electron-vue, the configuration file and electron-vue remain the same

  1. Package configuration: asarUnpack This configuration is used to unpack third-party packages used by the child process, otherwise the child process cannot find these packages and cannot run. Third-party packages used by child processes need to be configured in asarUnpack. ExtraResources is used to extraResources the directory where our code subprocess files are located. If you need to reference a subprocess file in your code, use this address to find the corresponding JS file, because the path after development and packaging is different. The specific package.json configuration is as follows
    "mac": {
      "icon": "build/icons/icon.icns"."extendInfo": {
        "CFBundleURLSchemes": [
          "link"]},"asarUnpack": [
        "**/node_modules/electron-log/**/*"."**/node_modules/unzipper/**/*"."**/node_modules/axios/**/*"."**/node_modules/archiver/**/*"]."extraResources": [{"from": "src/main"."to": "app.asar.unpacked/download"}},"win": {
      "icon": "build/icons/icon.ico"."asarUnpack": [
        "**/node_modules/electron-log/**/*"."**/node_modules/unzipper/**/*"."**/node_modules/axios/**/*"."**/node_modules/archiver/**/*"]."extraResources": [{"from": "src/main"."to": "app.asar.unpacked/download"}]."target": [{"target": "nsis"."arch": [
            "x64"]]}}Copy the code
  1. Child process fork path: The fork path developed in electron is different from that of the child process after packaging. During development, the current path can be directly referenced, but the JS file of the child process after packaging cannot be obtained directly through the relative path. Therefore, the path to fork the child process should be configured as follows:process.resoucesPath: the path of the resource directory defined in electron, the path of the child process JS after packaging.
letisDev = process.env.NODE_ENV ! = ='production';
let scriptPath = isDev ? path.join(__dirname, 'child_download_serial.js') : path.join(process.resourcesPath, 'app.asar.unpacked/download/child_download_serial.js');
Copy the code

After the previous two steps are complete, you can see the code directory of the child process in the installation package after installation. At this time, the configuration is successful, and the child process and the main process can communicate normally.

The above solution works on both Windows and MAC

3. Logs in the child process cannot be output

Scenario: Want to see the output log in the process, check the execution of the child process

Problem: The child’s console is not visible in the console because the child and parent are separate and we only see the output of the parent

Solution: Listen for the child’s stdout.on(‘data’) event in the parent process, so that all console. logs in the child process will trigger data events in the parent process, and the parent process can output the console contents of the child process. Note that a silent:true configuration is required for fork. If true, the child’s stdin, stdout, and stderr will be piped to the parent, otherwise they will inherit from the parent. Similarly, you can also listen for the data event of the child process’s stderr and catch the child process’s errors

childDownload = fork(scriptPath, [], { silent: true });
childDownload.stdout.on('data', data => {
  console.log('Console for child process', data.toString());
});
Copy the code

4. The problem of the electron flash retreat

Scenario: When exiting the software, an error is reported due to code reasons, and the software is shut down successfully. However, when manually starting the software again, a flash backout occurs

Problem: After the main process fails, the error is not captured. As a result, the software cannot be opened again because the error still exists

Solution: Capture an error globally to avoid the problem that the software cannot be opened because the error is not captured in some cases

// Necessary global error capture
process.on('uncaughtException', error => {
  log.error(error.stack || JSON.stringify(error));
  app.exit();
});
Copy the code

5. The Web client awakens the client coverage problem

Scenario: Incorrect installation of the logger tool after the download is installed, click wake up on the Web to wake up the logger tool

Problem: When both packages are packaged, the corresponding appId is the same, resulting in the software installed later will replace the software installed before, when the web page wake up, the replaced software will wake up

Solution: The appId in package.json is guaranteed to be unique

6. The third-party package cannot be found when the subprocess is used in the electron task

7. Wake up the application on the web and find that a new electron window will always open

Scenario: The web page wakes up and starts the project locally. During debugging, it is found that the electron project started by itself is not woken up, but this kind of page

Solution: Uninstall the local electron package, reinstall it again, we can normally wake up the project started locally