简体   繁体   English

如何使用电子将动态安装的Vue插件加载到plugins文件夹中

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

I am using vue with electron to build a desktop application. 我正在将vue与electronic一起使用来构建桌面应用程序。 I am using vue plugins to extend the functionality of the application. 我正在使用vue插件来扩展应用程序的功能。 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. 这些vue插件在npm目录中作为npm模块托管,可以使用live-plugin-manager从应用程序插件存储中安装,该插件可用于将插件动态安装到plugins目录中。

I am using webpack to compile the vue front-end. 我正在使用webpack编译vue前端。 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. 但是我无法要求这些模块进入vue应用程序。 I tried using electron's remote.require call to fetch the module and using a loop called Vue.use() with the loaded plugin. 我尝试使用electronic的remote.require调用来获取模块,并使用已加载插件的名为Vue.use()的循环。 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 . 我能够通过使用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. 首先,我将browserify包含在依赖项中,以便电子将其包含在node_modules文件夹中。
  • Then I set asar as false while packaging so that we can write into the app js file after bundling. 然后在打包时将asar设置为false,以便我们可以在捆绑后将其写入app js文件。
  • Each time the app starts it creates a js plugin loading script like: 每次应用启动时,都会创建一个js插件加载脚本,如下所示:
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. 每个插件都保存到plugins / modules文件夹中。 The dependencies are also installed into the folder automatically while installing. 依赖项也将在安装时自动安装到文件夹中。
  • The this.enabled is a getter that fetch all enabled plugins. this.enabled是获取所有已启用插件的吸气剂。 plugin.name gets the package name of the plugin. plugin.name获取插件的软件包名称。
  • Once this script is created the program will write it into plugins/index.js using fs . 创建此脚本后,程序将使用fs将其写入plugins / index.js
  • 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). 现在,我将脚本dist / packages.js添加到html文件中,然后添加到主要js文件(在我的情况下为dist / app.js)之前。

  • Now I have a plugin BootstrapPlugin available globally that installs all the other plugins 现在,我有一个全局可用的BootstrapPlugin插件,可以安装所有其他插件

  • All I have to do now is to use this plugin in the main.js file (dist/app.js) 我现在要做的就是在main.js文件(dist / app.js)中使用此插件

Vue.use(window.BootstrapPlugin)

const app = new Vue({...})

Hope it helps someone :-) 希望它可以帮助某人:-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM