Search code examples
electronquasarnode-serialport

Quasar Framework, Electron, and Serialport: indexOf Error


I'm setting up a test project with Quasar, Electron, and serialport. When starting the application with a minimal serialport test, I get the following error:

vue-router.esm.js?85f8:2128 TypeError: Cannot read property 'indexOf' of undefined
    at Function.getFileName (bindings.js?d8c5:178)
    at bindings (bindings.js?d8c5:82)
    at eval (win32.js?0965:1)
    at Object../node_modules/@serialport/bindings/lib/win32.js (vendor.js:340)
    at __webpack_require__ (app.js:854)
    at fn (app.js:151)
    at eval (index.js?3983:6)
    at Object../node_modules/@serialport/bindings/lib/index.js (vendor.js:252)
    at __webpack_require__ (app.js:854)
    at fn (app.js:151)

The error even happens when I only include the serialport package without doing any more. It seems to be a basic problem. Code to reproduce the problem:

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
import SerialPort from 'serialport';

@Component
export default class Index extends Vue {
  test() {
    console.log('test', SerialPort);
  }
}
</script>

I tried everything I could find here, in the Quasar forum, etc. pp.: electron-rebuild, trying to config serialport as an external dependency, ...

I'm not quite sure if the rebuild process is working as expected, but I don't know what to check to make sure it does. The electron example project with serialport is working for me. Maybe it is a Quasar related thing?

Can I get more information on the rebuild process? I tried different combinations with specifying the version, but nothing is helping.

enter image description here

I also asked this question as an issue in the serialport repository, but adding it in the vue.config.js doesn't work, because I'm using Quasar as the CLI option.

enter image description here

I think the main problem is how to rebuild serialport properly for electron when Quasar is in place, which seems to be not working as expected.


Solution

  • I also had quite some trouble getting Serialport to run in Quasar and Electron, but I got it to work. The solution is not really pretty and might break in the future.

    As you wrote, you need to run electron-rebuild. You can execute it by running "./node_modules/.bin/electron-rebuild". You should also put in in your package .json in the "scripts" section

    "install": "electron-rebuild"
    

    I used the Electron preload script to put serialport in the window object. Here is the documentation on how to enable this. In the electron-main.js, you also need to add the following line

    app.allowRendererProcessReuse = false;
    

    If missing, electron will fail to load.

    In electron-preload.js, put this

    window.serialport = require("serialport");
    

    You can now use serialport in your Quasar project by using window.serialport.

    Another problem I encountered was the fact that Quasar changes the package.json while packaging the project and removes the install script so electron-rebuild does not run while building and the packed version does not work. I managed to fix this by adding a "beforePackaging" Hook into the electron part of quasar.conf.js

    //Top of the file
    const path = require("path");
    const crossSpawn = require("cross-spawn");
    ...
    electron: {
      ...
      beforePackaging(params) {
        return new Promise(resolve => {
          const runner = crossSpawn(
            path.join("node_modules", ".bin", "electron-rebuild"),
            [""],
            {
              stdio: "inherit",
              stdout: "inherit",
              stderr: "inherit",
              cwd: params.unpackagedDir
            }
          );
    
          runner.on("close", () => {
            resolve();
          });
        });
      },
    }
    

    Maybe somebody has a nicer solution to this, but I hope, this helps.