Context
I'm trying to build an app using the following stack:
I've developed simple Vue apps for a while now and I understand the basics. What I'm trying to do here is to combine Vue and Electron using this awesome tool: Vue CLI Plugin Electron Builder.
While I've successfully managed to code simple apps with this stack, I'm facing issues when it comes to exploit Electron's nodeIntegration which is supposed to give Node access directly to my Vue code.
Issue
My asynchronous calls to some methods of the systeminformation library seem to be stuck (sometimes). That is, when I want to assign a value my view's data by calling an asynchronous method of the systeminformation library, Vue seems to hang and await indefinitely.
The weired thing is that, sometimes, when I force refresh the page, I can briefly see in my console the log supposed to be output when the method returns data. It's almost like refreshing the page forces Vue or something else to update.
I'd suspect the following leads but I might be wrong:
- Vue's reactivity issue in my way of declaring and/or assigning.
- Node integration issue making Vue+Node not "bounded" properly.
- Electron's packaging of a Node library missing configuration to be used in Vue "as if it was a regular JS library".
The latter point is unclear to me as I've always used Electron+Vue to access Node libraries the same way I'd do for web libraries. There might more to it that could lead to these issues but this is as far as my knowledge goes...
Steps to reproduce
You can create a Vue+Electron as follows:
vue create myapp
vue add electron-builder
yarn add systeminformation
I'm leaving default values for Vue CLI's interactive project creation as they don't have an impact on my issue.
As per Vue CLI Plugin Electron Builder's documentation on nodeIntegration, my vue.config.js file looks like this:
module.exports = {
pluginOptions: {
electronBuilder: {
nodeIntegration: true,
},
},
};
You can then use the snippets in Scenario 1 and Scenario 2.
Scenario 1
Let's consider the following example where I assign a value using Axios:
<template>
<pre>{{ test }}</pre>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
test: null,
};
},
async mounted() {
console.log("Getting data from Axios...");
// Assign a value to the "test" data with an asynchronous HTTP call with Axios.
this.test = (
await axios.get("https://cat-fact.herokuapp.com/facts")
).data;
// It gets there as soon as the server responds.
console.log("Got it!", this.test);
},
};
</script>
Here, the asynchronous call works as expected, my test data updates properly and shows in my view as soon as the Axios call got an answer.
Scenario 2
Now, if I use the same logic to get my data from a method of the systeminformation library:
<template>
<pre>{{ test }}</pre>
</template>
<script>
import systeminformation from "systeminformation";
export default {
data() {
return {
test: null,
};
},
async mounted() {
console.log("Getting data from systeminformation...");
// Assign a value to the "test" data with an asynchronous call to a method of systeminformation.
this.test = await systeminformation.getStaticData();
// It just won't get there most of the time...
console.log("Got it!", this.test);
},
};
</script>
In that case, my view won't show the test data as Vue seems to hang on the systeminformation call indefinitely.
The console log won't even show as the await statement appears to make the mounted hook stuck.