问题
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)
回答1:
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.
- First of all I included browserify into the dependency so that electron will include it in node_modules folder.
- Then I set asar as false while packaging so that we can write into the app js file after bundling.
- Each time the app starts it creates a js plugin loading script like:
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')}
}
}
`
- each plugin are saved into plugins/modules folder. The dependencies are also installed into the folder automatically while installing.
- The
this.enabled
is a getter that fetch all enabled plugins.plugin.name
gets the package name of the plugin. - Once this script is created the program will write it into plugins/index.js using fs.
- I have a bundle function which is called on app launch
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 :-)
来源:https://stackoverflow.com/questions/56866935/how-to-use-electron-to-load-the-vue-plugins-installed-dynamically-into-a-plugins