I am using vue with electron to build a desktop application. I am using vue plugins to extend the functionality of the application. These vue plugins are hosted as npm modules in npm directory which can be installed from the applications plugin store using the live-plugin-manager which can be used to dynamically install plugins into plugins directory.
I am using webpack to compile the vue front-end. When I directly use these plugins, they work perfectly. I need to know if there is any way I can load these plugins dynamically from the folder each time application launches.
I have built the functionalities to install and uninstall the plugins. But I am unable to require these modules into the vue app. I tried using electron's remote.require call to fetch the module and using a loop called Vue.use() with the loaded plugin. But I keep on getting error.
// loading plugins
const plugs = await plugins.load()
console.log(plugs)
plugs.forEach(plug => {
console.log(plug.install)
Vue.use(plug)
})
// the plugins.load
const remote = window.require('electron').remote
if (remote) {
const packager = remote.require('./package').default
return packager.requireEnabled()
}
// the packager.requireEnabled() will load the enabled plugins
This error shows up every time I use the above code.
Uncaught (in promise) Error: Could not call remote function 'install'. Check that the function signature is correct. Underlying error: Vue.use is not a function
at callFunction (C:\Arjun\Tracing Paper Designs\works\Infolks\Tool\infolks-tool\node_modules\electron\dist\resources\electron.asar\browser\rpc-server.js:260:17)
at C:\Arjun\Tracing Paper Designs\works\Infolks\Tool\infolks-tool\node_modules\electron\dist\resources\electron.asar\browser\rpc-server.js:411:10
at EventEmitter.<anonymous> (C:\Arjun\Tracing Paper Designs\works\Infolks\Tool\infolks-tool\node_modules\electron\dist\resources\electron.asar\browser\rpc-server.js:275:21)
at EventEmitter.emit (events.js:194:13)
at WebContents.<anonymous> (C:\Arjun\Tracing Paper Designs\works\Infolks\Tool\infolks-tool\node_modules\electron\dist\resources\electron.asar\browser\api\web-contents.js:418:21)
at WebContents.emit (events.js:194:13)
I was able to solve the issue by dynamic bundling of the plugins using browserify . I cannot share the entire code, but I will share the method I used.
const imports = []
const pluginUses = []
this.enabled.forEach((plugin, i) => {
imports.push(`const plugin${i} = require("./modules/${plugin.name}");`)
pluginUses.push(`Vue.use(plugin${i});`)
})
return `
${imports.join('\n')}
window.BootstrapPlugin = {
install(Vue, opts) {
${pluginUses.join('\n')}
}
}
`
this.enabled
is a getter that fetch all enabled plugins. plugin.name
gets the package name of the plugin. const browserify = require('browserify')
const fs = require('fs')
const path = require('path')
// ...
function bundle() {
const b = browserify({
entries: [path.join(app.getAppPath(), 'plugins/index.js')],
paths: [path.join(app.getAppPath(), 'plugins/modules'), path.join(app.getAppPath(), 'node_modules')]
})
const stream = fs.createWriteStream(path.join(app.getAppPath(), 'dist/packages.js'))
b.bundle().pipe(stream)
}
Now I added the script dist/packages.js into the html file before the main js file (in my case dist/app.js).
Now I have a plugin BootstrapPlugin available globally that installs all the other plugins
All I have to do now is to use this plugin in the main.js file (dist/app.js)
Vue.use(window.BootstrapPlugin)
const app = new Vue({...})
Hope it helps someone :-)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.