This article has participated in the third “topic writing” track of the Denver Creators Training Camp. For details, check out: Digg Project | Creators Training Camp third is ongoing, “write” to make a personal impact.

Introduction of Electron

Electron (formerly Atom Shell) is an open source framework developed by GitHub. It uses Node.js (as the back end) and Chromium’s rendering engine (as the front end) to develop cross-platform desktop GUI applications. Electron has been used for front-end and back-end development by several open source Web applications, including GitHub’s Atom and Microsoft’s Visual Studio Code.

Electron reports error symptoms

I had this problem when I started learning to write business code on the Electron project.

Node terminal compilation error is as follows:

Module not found: Error: Can't resolve 'fs' in 'D:\electron\xxx\node_modules\electron'
Copy the code

When it comes to code, Google has two solutions.

In scenario 1, modify the Webpack Target configuration item

The solution comes from the typescript-electron link and typescript: ‘FS’ Can’t be Resolved, and the error this writer encountered was exactly the same as mine.

The author of this article is also very careful, typesetting what is also very good, I do not know how the appearance level. Please write well and don’t think too much about it

In a nutshell, the solution is to modify the Target configuration item for Webpack.

either

module.exports = {
    / /... Other content omitted
    { 
        // for files that should be compiled for electron main process 
        target: 'electron-main'
    }
    / /... Other content omitted
}
Copy the code

either

{ 
    // for files that should be compiled for electron renderer process 
    target: 'electron-renderer' 
}
Copy the code

I went to look for the corresponding modification with enthusiasm, and found that the template electron-react- Boilerplate used in the project had already been configured with the target value. A little lift up, but the helpless feeling of no-show.

Solution 2: Modify the webpack externals configuration item

In short, also modify the webPack configuration item externals

module.exports = {
  / /... Other content omitted
  "externals": {
      "fs": 'require("fs")',},/ /... Other content omitted
}  
Copy the code

Scheme link from

  • Electron Error: Can’t resolve ‘fs’
  • # [v6] Electron: Module not found: Error: Can’t resolve ‘fs’

After this is changed, there is no error. But a new error has been generated.

Module not found: Error: Can't resolve 'path' in 'D:\electron\xxx\node_modules\electron'
Copy the code

Familiar? Look, I learned CTRL + V.

  "externals": {
      "fs": 'require("fs")'."path": 'require("path")',},Copy the code

Finally keep the clouds to see the moon. The Node side build did not report an error. But the browser started reporting errors.

Cannot read property 'join' of undefinedThe Call Stack. / node_modules/electron/index. Js the renderer. Dev. Js:23020:23Object. The options. The factory the renderer. Dev. Js:69814:31
Copy the code

Error line see:

const pathFile = path.join(__dirname, 'path.txt');
Copy the code

This error reminds me why the node side of the code is executed in the browser side, and if there is something wrong.

Final plan:contextBridge.exposeInMainWorld

I added electron directly to js in render process.

const { ipcRenderer, shell, remote } = require('electron');
Copy the code

Since electron has a lot of node modules, it will of course fail on the browser side. At this point, we should use a Node – and browser-executable preload configuration item.

  • First of all:main.jsPreloading configurationpreload.js
const createWindow = () = > {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800.height: 600.webPreferences: {
      preload: path.join(__dirname, 'preload.js'),}}); }Copy the code
  • preload.jsThe introduction ofelectronAnd through thecontextBridgeExposed to thewindow
const { contextBridge, ipcRenderer, remote, shell } = require('electron');

contextBridge.exposeInMainWorld('electron', {
  ipcRenderer,
  remote,
  shell,
});
Copy the code
  • The render process changes the js import mode and obtains the corresponding module via window.electron
// Comment error introduction
//const { ipcRenderer, shell, remote } = require('electron');
const { shell, remote, ipcRenderer }  = window.electron;
Copy the code
  • Restart the project and refresh the page again.

Write in the last

In a word, this problem, or rather careless. I don’t have any project experience and naturally ignore the difference between the execution environment of main (Node side) and render (browser side). IpcRenderer is a module of the renderer process.

Remember: if you want to use certain modules in a front-end environment, make sure you use them inpreloadOption configures js throughcontextBridge.exposeInMainWorldExposed to thewindowFor the front end.

This error is actually a bit like some SSR types of error, should not be executed in the node layer, such as the node side to get window, are the execution environment mismatch caused by the error.

Of course, this may be my personal situation, do not have the wildmatch. Hope to help you.

Original is not easy, thank you for reading, grateful point praise support.

On the other

# Electron App: Unable to Load Preload script: Unable to Load Preload script Just the so-called pit too much… Say too much is tears.