node-irsdk icon indicating copy to clipboard operation
node-irsdk copied to clipboard

[Guide] node-irsdk with vuejs + electron-builder

Open hmiefert opened this issue 4 years ago • 5 comments

Hi guys,

it took some time for me to figure out how to create a vuejs based electron app with node-irsdk support. I hope it's ok to leave a step by step guide here, even though it's not an issue. I wasn't sure where to put it else and thought maybe it's worth the write.

npm install -g @vue/cli

vue create myapp

cd into your app

vue add electron-builder Latest version as of writing is electron 11

npm install --save https://github.com/sabifa/node-irsdk I selected this fork, as it already fixed the import of the compiled source. If there is any better out there, let me know.

npm install --save-dev electron-rebuild

.\node-modules\.bin\electron-rebuild.cmd This will rebuild the node-irsdk to be compatible with the electron version you selected - at least on windows.

Add a vue.config.js file to your project root with the following content

module.exports = {
    pluginOptions: {
        electronBuilder: {
            externals: ['node-irsdk'],
            nodeIntegration: true
        }
    }
}

This was the most crucial part to figure out - at least for me.

Now you can run your node-irsdk code in background.js as you would in every other electron app.

....
import * as irsdk from 'node-irsdk'
....
const iracing = irsdk.init({telemetryUpdateInterval: 500, sessionInfoUpdateInterval: 2000})
iracing.on('Connected', function() {
  console.log('iRacing connected..')
})
iracing.on('Disconnected', function() {
  console.log('iRacing disconnected..')
})

*edit: as this is way outdated and as of 30/12/2022 I couldn't get a solution with existing forks, I tried to come up with my own solution. So, if you want to give it a try, you can find it here.

hmiefert avatar Apr 05 '21 19:04 hmiefert

Great idea to post it here so it's easier for others to create their first project using this package!

I am using the exact same method you described and it's been working totally fine for almost a year now! I had to enable nodeIntegration though, which could be caused by another dependency.

sabifa avatar Apr 05 '21 19:04 sabifa

If you don't mind me asking: how do you get the telemetry data to the frontend? Would you recommend using a websocket-server?

hmiefert avatar Apr 05 '21 19:04 hmiefert

Sure! I'm using the IPC communication approach.

It looks like this:

// background.ts
const setupIrSdk = (): void => {
    const irsdk = require('node-irsdk');

    irsdk.init({
      telemetryUpdateInterval: 17,
      sessionInfoUpdateInterval: 17,
    });

    const iRacing = irsdk.getInstance();

    iRacing.on('Connected', () => {
      win?.webContents.send('ir_connected');
    });

    iRacing.on('Telemetry', (data: unknown) => {
      win?.webContents.send('ir_telemetry', data);
    });

    iRacing.on('SessionInfo', (data: unknown) => {
      win?.webContents.send('ir_sessionInfo', data);
    });

    iRacing.on('Disconnected', () => {
      win?.webContents.send('ir_disconnected');
    });
  };

In order to not miss any information while the renderer process first load make sure to call this method after the vue.js process has loaded successfully. My approach for this is to send an event from within the App's created method to the main process like so:

Also take a look at listenOnIpcForIrEvents where I listen for the events from the main process 😅


<script lang="ts">
import Vue from 'vue';

const ipc = require('electron').ipcRenderer;

export default Vue.extend({
  name: 'App',
  created() {
    this.listenOnIpcForIrEvents();

    ipc.send('app_loaded');
  },
  methods: {
    listenOnIpcForIrEvents(): void {
      ipc.on('ir_connected', () => handleConnected());
      ipc.on('ir_telemetry', (event, args: { values: import('node-irsdk').TelemetryEventValues }) => handleTelemetry(args.values));
      ipc.on('ir_sessionInfo', (event, args: { data: import('node-irsdk').SessionInfoEventData }) => handleSessionInfo(args.data));
      ipc.on('ir_disconnected', () => handleDisconnected());
    },
  },
});
</script>

Finally in your background.(ts/js) call:

ipcMain.on('app_loaded', () => {
    setupIrSdk();
});

And voilà you should be good to go 🚀

sabifa avatar Apr 05 '21 20:04 sabifa

@sabifa Thanks, I only read about IPC, haven't tried it myself though. Your code is a great starting point for me, appreciate it!

hmiefert avatar Apr 06 '21 08:04 hmiefert

I had to enable nodeIntegration though, which could be caused by another dependency.

Yep, this is a must. Otherwise I got an error in the frontend: __dirname is not defined

hmiefert avatar Apr 06 '21 18:04 hmiefert