This paper mainly records some pits encountered in the daily development of electron and how to fill the pits to help other developers to step on fewer pits. Suggest to pay attention to collection, so as to meet when convenient access!

Electron is a desktop framework that uses the Node and Chromium architecture. If you are familiar with developing the desktop using Web technologies, you may have heard of or are using this framework.

Here is a record of some of the questions you have in reading the document and the pit you stepped on in the development process!

Electron?

  1. What are Spectron and Devtron for?

    • SpectronYou can go with the othersmochaSuch testing frameworks are combined to testelectron
    • DevtronElectron DevTools is an extension to Electron DevTools that helps you inspect, monitor and debug applications. The default state is disabled
  2. function?

    • Set the CONTent-security-Policy header field for HTTP
    • To prevent XSS attacks, security considerations can be set incontentSets the source of the script that is allowed to load
  3. What does electron forge do?

    • Electron is a quick build tool for build electron, which includes packaging, automatic updates, and more
    • Internal writinghtmlandjsIt is written native and does not integrate third-party frameworks
  4. What is the difference between using iframe and WebView in electron?

    • Official recommendationiframeInstead ofwebview.webviewTags can load a URL page in visitor mode, as this tag is based onChromium webview, the current architecture changes rapidly and is not stable enough. butwebviewIt provides many functions, such as controlling whether visitors can move forward or backward
  5. What is the difference between window.open() using Native and Chrome?

    • inelectronThe use ofwindow.open()Opening a URL to use will create oneBrowserWindowExample, usingnativeThe window can be set upnativeWindowOpen: trueTo use thechromeThe built-inwindow.open(), open the window synchronously
  6. What’s the difference between electron packager and electron Builder? Why is the electron Builder recommended?

    • electron-packagerelectron-builderBoth modules are packed for electron applications, comparedelectron-builderIt has richer features, supports more platforms, packs more lightweight files, supports nonelectronBuilt-in automatic updates (the built-in automatic updates need to be uploaded to support platforms such as Git)
  7. Does electron rebuild simplify native recompile when using the Node native module in electron?

    • Due to theelectronThe built-innodeIf the version is inconsistent with the version of your computer, it is in usenodeNative modules may have an error,Error: The module '/path/to/native/module.node'
    • There are three ways to solve this problem (two are described in detail below, and the other ways refer to official documentation).

The electron processes communicate with each other

  1. The main process communicates to the renderer

    • Use by the main processwin.webContents.sendSend a message
    • The renderer process usesipcRenderer.onReceives the message
  2. The renderer communicates with the main process

    • The renderer process usesipcRenderer.sendoripcRenderer.invokeSend a message
    • Use by the main processipcMain.onoripcMain.handleReceives the message
  3. The renderer communicates with the renderer

  • Notification event
    • Forward through main process (before Electron 5)
    • ipcRenderer.sendTo(After Electron 5)
  • Data sharing
    • Web technology (localStorage, sessionStorage, indexedDB, embeddable database, etc.)
    • Use Remote (use it sparingly, which may affect performance)

Because the technology stack used by the company isvue, so it needs to beelectronandvueCombine them, and of course the way to combine them is not too troublesome, which we chose hereelectron-vueThis open source framework. It has combined the two and can be packaged separatelyweb, but in the process of use there are still some questions and pits, record

Electron – Vue pit and filling pit?

  1. This frame uses the VUE-electron module. What does it do?

    • Append the electron API to the Vue object without explicitly introducing electron into the Vue (require('electron'))
    • vue-electronThe source code is very simple, will$electronMount it to the vUE prototype
    const electron = require('electron')
    
    module.exports = {
      install: function (Vue) {
        Object.defineProperties(Vue.prototype, {
          $electron: {
            get () {
              return electron
            },
          },
        })
      },
    }
    
    Copy the code
  2. This frame uses the Vuex-electron module, what does it do?

    • State can be shared between multiple processes, such as inelectronThe main and renderer processes share the same state and store data on disk
  3. Did __dirname and __filename pack in the main process and not get the path we expected?

    • This problem is also encountered when calling native DLLS. If the correct path can be obtained before packaging, the file will be put in the virtual file app.asar after packaging, and the path will be wrong
    • Solutions:electron-vueProvided in the__staticGlobal variables solve this problem by simply putting static files into__staticFolder (path.join(__static, '/xxx.dll'))
    • If you only useelectronFor the framework itself, you need to set your own development time path and packaged access path
  4. ReferenceError: Process is not defined

    • Can be found inindex.ejsLt.<% if (! process.browser) { %>Modified into<% if (! require('process').browser) { %>(Do not use this method if you need to package as Web.)
    • Or in thewebpack.renderer.config.jsModify the following code (which is actually used in the configuration pageprocessParameters, if you need to package as web, you can use this method, but not inwebpack.web.config.jsAdd the code to
    new HtmlWebpackPlugin({
          filename: 'index.html'.template: path.resolve(__dirname, '.. /src/index.ejs'),
    +      templateParameters(compilation, assets, options) {
    +        return{ + compilation: compilation, + webpack: compilation.getStats().toJson(), + webpackConfig: compilation.options, + htmlWebpackPlugin: { + files: assets, + options: options + }, + process, + }; +},minify: {
            collapseWhitespace: true.removeAttributeQuotes: true.removeComments: true
          },
          nodeModules: process.env.NODE_ENV ! = ='production'
            ? path.resolve(__dirname, '.. /node_modules')
            : false
        }),
    Copy the code
  5. After the project is built, the electron version is 2.x by default. After the upgrade, an error message is displayed indicating module is not defined

    • Cause New VersionelectronDisabled by defaultnodeIn integration,main/index.jsAdd the following code to create the window
    mainWindow = new BrowserWindow({
      height: 563.useContentSize: true.width: 1000,
    +  webPreferences: {
    +    nodeIntegration: true+}})Copy the code
  6. Unable to install vue-devtools

    • The reason is thatvue-devtoolsNeed external network to download, science can be online
  7. Mutations in vuex in this project will result in an error Please, don’t use direct commit’s, use dispatch instead of this.

    • Instead of using synchronous methods, you should use a callactionsTo triggermutations
    • The reason is thatvuex-electronIt’s loaded with interprocess sharingmutationsThe plug-in
    • Solution: 1. Instore/index.jsLt.createSharedMutationsPlug-in comments
    • 2. By callingactionsTo triggermutationsAnd in the main processmain/index.jsAdd the codeimport '.. /renderer/store'
    • 3. The queryvuex-electronGithub, according to the documentation Settingswhitelist, will not be repeated here
  8. Data stored in VUEX persists even when the project is refreshed and restarted (here you can set the user’s data stored for a long time)

    • vuex-electronYes Data is stored on disks. The default path can passapp.getPath('userData')Find one below the storage pathvuex.jsonInstall different fileselectronApplication, file directory will generate onevuex.jsonfile
    • vuex-electronInternally usedelectron-storeThis module, this module cansetData, butvuex-electronIt’s not going to be exposed
    • Solution: If you want to refresh or close the data reset as in the Web, directly in question 9 below this, willpluginsDelete the loaded module
  9. Error: Can’t resolve ‘fs’ in XXXX Error: Can’t resolve ‘fs’ in XXXX

    • Modify therenderer/store/index.jsIn the Webvuex-electronAnd delete display importvuex-electron
    import Vue from 'vue'
    import Vuex from 'vuex'
    - import { createPersistedState, createSharedMutations } from 'vuex-electron'
    import modules from './modules'
    
    Vue.use(Vuex)
    
    export default newVuex.Store({ modules, + plugins: process.env.IS_WEB ? [], [+require('vuex-electron').createPersistedState(),
    +    require('vuex-electron').createSharedMutations()
      ],
      strict: process.env.NODE_ENV ! = ='production'
    })
    Copy the code
  10. Packaging error

    • The easiest thing to get wrong here isdownloading parts=8 size=63 MB url=https://github.com/electron/electron/releases/download/vx.x/electron-vx.x-win32-x64.zipfailure
    • Solution: Go manuallyhttps://npm.taobao.org/mirrors/electronFind the corresponding ELECTRON version download
    • Place the downloaded files manuallyC:\Users\ user name \AppData\Local\electron\CacheAppData is a hidden folder.

Electron calls the native method

Installation Environment (Step 1 is not required for the MAC environment)

  1. Administrator Permission Executionnpm install --global windows-build-toolsInstall the python and C++ environment

    If it cannot be installed, install it separately
  • Python (v2.7, 3.x not supported)
  • Visual C++ Build Tools or vs2015 or above
  1. npm install -g node-gypCompile the native Node module (electron requires compilation to use the native node module)
  2. node-gyp listCheck to see if the Node. lib library is missing, and install it as promptednode-gyp install
  3. insrc/main/index.jsEnable render layer Node integration in

C/C++ DLL is invoked from the Node-ffi module

  1. NPM install ffi-napi –save Installs modules that call C/C++ DLLS

    • If the Python path cannot be found, set the Python environment variable orNPM config set python Your Python path
    • If not, try yarn installation
  2. NPM install auto-rebuild — –save-dev Installs the auto-compile native node module

    • If you do not install it, you can compile it manually as follows
    • Enter theNode_module/ffi - for a folderperformNode - gyp rebuild -- target = 'current versions of the electron - arch = x64 - dist - url = https://atom.io/download/atom-shellCompile node native modules
    • Arch: the architecture of the computer (X64 or IA32), if the node environment is 32-bit, then this is ia32, if the node environment is 64-bit, then this is X64.
    • If the path error, change the domestic – dist-url=https://npm.taobao.org/mirrors/atom-shell image path
    • To enter theNode_module/ref - for a folderperformNode - gyp rebuild -- target = 'current versions of the electron - arch = x64 - dist - url = https://atom.io/download/atom-shellCompile node native modules
  3. This step is not required if you manually compile the preceding step

  4. All that is left is to call native methods in the main process, and renderer calls via ipcRenderer and ipcMain communication, for a small example

    / / main process
    // Call an example
    const ffi = require('ffi-napi')
    const CTEST =  ffi.Library('DLL file path', {
      // The method and parameter types in the file
      'Add': ['float'['float'.'float']],
      'Hello': ['string'[]],'StrLength': ['int'['string']]})// Synchronous call
    CTEST.Hello()
    
    // Asynchronous invocation
    CTEST.StrLength.async('1234', (error, res) => {
      console.log(error, res)
    })
    Copy the code

There are two things to note here

  • If not usedelectron-vueThis framework (electron-vueStatic file path has been handled), need to note that there will be some problems with the static file path after packaging, can be in thepackage.jsonSave the DLL file configured after the build file
    "extraFiles": [{"from": ""."to": ""}]Copy the code
  • A 64 – bit DLL cannot be invoked on a 32 – bit machine, and an error is reported

The C# DLL is called from the electron-edge-js module

  1. npm install electron-edge-js --saveInstall the module that calls C# DLL
  2. hereelectronThe version of version 7.x cannot be 8.x. There is a bug in page refresh of version 7.x. Currently, this module is supported
    * Electron 1.6.x-node. js v7.4.0. * Electron 1.7.x-node. js v7.9.0. * Electron 1.8.x-node. js v8.2.1 -node.js v8.9.3. * Electron 3. x-node.js v10.2.0. * Electron 4.0.4+ -node.js v10.11.0. * Electron 5. x-node.js V12.0.0. * Electron 6.x-node. js v12.4.0. * Electron 7.x-node. js v12.8.1Copy the code
/ / main process
// Call an example

const edge = require('electron-edge-js')
const edgeDll = edge.func({
  assemblyFile: 'DLL file path'.typeName: "Edge_test.Class1".methodName: "Concat"
})

edgeDll({ first: 'aaa'.second: 'bb' }, function (error, result) {
  if (error) throw error
  console.log('c # DLLS:,result)
})
Copy the code

Use RobotJS to control the mouse and keyboard and node-serialport for serial communication

  1. The use method is not described here, the document can be queried. These modules are also Node native modules and therefore need to be compiled
  2. Same as above for automatic compilationnpx electron-buildSometimes automatic compilation does not work, so manual compilation is required
  3. Manually compileNPM rebuild - runtime = electron - disturl = https://atom.io/download/atom-shell - target = > < electron version - abi = < corresponding node version of abi >Or go directly to the module folder and compile through Node-gyp:node-gyp rebuild
  4. Abi search url: github.com/mapbox/node…

Automatic updates

Abandoned because the project code is placed in its own service and will not be signedelectronBuilt-in automatic updates. The packaging method used for the project iselectron-builder, the final decision to useelectron-updaterThe module updates automatically, it doesn’t depend on any server and can store updates from S3, GitHub, or any other static file, avoiding the update mechanism built into Electron

MAC code must be signed

Here is a simplified example

  1. npm install electron-updater --saveInstall the automatic update module
  2. Update code is written to the main process
    // Every time the application is started, it will automatically check the file server for updates and automatically restart the file server
    import { autoUpdater } from 'electron-updater'
    
    autoUpdater.on('update-downloaded', () => {
      autoUpdater.quitAndInstall()
    })
    
    app.on('ready', () = > {if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
    })
    Copy the code
  3. Configure the package update server address (here configure getting updates from your own file server)
    "build": {
      "publish": {
        "provider": "generic"."url": "http://127.0.0.1:8080"// Server address}}Copy the code
  4. Package and install, update and modify if necessarypackage.jsonThe version, repackaged, will.exe latest.yml .exe.blockmapThrow 3 files directly at the file server address. The next time the user opens the app, it automatically updates

Start a node service in electron

  • Create a child in the main process to execute the Node service (child_process.fork). The child and the main process communicate with each other through the process and pass through after the main process receives dataipcMainandipcRendererThe main process communicates with the render layer.

The above are some of the problems I encountered in reading the document and the project. Please record and share them to help other friends avoid some problems. Thank you for reading!

If the article lets you have harvest, welcome to pay attention to the public number, not regular push quality article!!