Home > Enterprise >  Electron native NodeJS module with Webpack
Electron native NodeJS module with Webpack

Time:01-05

I'm working on a software project which I've created with Electron and React. I didn't create the project from scratch, I am using a boilerplate which uses Webpack.

The software is for managing (selling & redeeming) vouchers, so I also have to print some receipts. Using the printer over network is working fine, just as it should. For printing I'm using the node-thermal-printer package (https://www.npmjs.com/package/node-thermal-printer).

But some of the printers don't have a network interface, just USB or Serial.

When using the node-thermal-printer with a USB connected printer, you have to provide a "driver" to be able to print. They suggest either the electron-printer or printer module, which both seem to be native NodeJS modules.

The boilerplate seems to compile the native modules for the architecture that is currently used and creates a *.node file, which is copied to the .wepback/ folder during the build phase. But as soon as I want to use the package, I get an error that the module could not be found.

I'm importing the module with the following line:

const printerDriver = require("printer");

When running npm start the native dependencies are compiled and a node_printer.node file is created and copied to .webpack/main/native_modules/lib/node_printer.node.

As soon as I click the button for printing, I receive the following error:

Error: Cannot find module '/Users/stefan/Documents/Dev/vouchers/.webpack/main/native_modules/lib/node_printer.node'

But the file definitely exists. When I import the printer module using the absolute path, like const printerDriver = require("/Users/stefan/Documents/Dev/vouchers/node_modules/printer/build/Release/node_printer.node"); it is working - but that's not a solution for me.

Here is my webpack.rules.js file, which was generated using the boilerplate template:

module.exports = [
  // Add support for native node modules
  {
    // We're specifying native_modules in the test because the asset relocator loader generates a
    // "fake" .node file which is really a cjs file.
    test: /native_modules\/. \.node$/,
    use: "node-loader",
  },
  {
    test: /\.(m?js|node)$/,
    parser: { amd: false },
    use: {
      loader: "@vercel/webpack-asset-relocator-loader",
      options: {
        outputAssetBase: "native_modules",
      },
    },
  },
  // ....
]

I've spent like 3 hours only for searching the internet for a solution, but I couldn't find anything that solves the problem.

Any help is appreciated. Thank you!

CodePudding user response:

Instead of hardcoding the absolute path in the require you can just reconstruct it using a solution like:


let path = require('path')
let printerDriver = require(path.join(__dirname,'node_modules/printer/build/Release/node_printer.node')

//do stuff

It is not the best but I used this many times to solve this kind of problems

CodePudding user response:

I think I just found the solution. I provided a config in my webpack.config.js and set the printer module as an external module like this:

webpack.config.js:

module.exports = {
  // ...
  externals: {
    printer: "printer",
  }
};

Damn it, if I tried this earlier I would have saved myself a lot of hours of researching. Nevermind, I hope I can help someone else with this problem.

  •  Tags:  
  • Related