How to use electron to load the vue plugins installed dynamically into a plugins folder

故事扮演 提交于 2019-12-11 14:58:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!