Как использовать электрон для загрузки динамически установленных плагинов в папку плагинов - PullRequest
0 голосов
/ 03 июля 2019

Я использую Vue с электронным для создания настольного приложения. Я использую VUE плагины для расширения функциональности приложения. Эти плагины vue размещаются в виде модулей npm в каталоге npm, который можно установить из хранилища плагинов приложений с помощью live-plugin-manager, который можно использовать для динамической установки плагинов в каталог plugins .

Я использую webpack для компиляции vue-интерфейса. Когда я напрямую использую эти плагины, они работают отлично. Мне нужно знать, есть ли способ динамической загрузки этих плагинов из папки при каждом запуске приложения.

Я собрал функциональные возможности для установки и удаления плагинов. Но я не могу требовать эти модули в приложение VUE. Я попытался с помощью электронного вызова remote.require извлечь модуль и использовать цикл Vue.use () с загруженным плагином. Но я продолжаю получать ошибку.

    // 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 

Эта ошибка появляется каждый раз, когда я использую приведенный выше код.

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 Ответ

0 голосов
/ 04 июля 2019

Мне удалось решить проблему путем динамического объединения плагинов с помощью browserify . Я не могу поделиться всем кодом, но я поделюсь методом, который я использовал.

  • Прежде всего я включил browserify в зависимость, чтобы электрон включил ее в папку node_modules.
  • Затем я установил asar в false при упаковке, чтобы мы могли записать в файл приложения js после упаковки.
  • Каждый раз, когда приложение запускается, оно создает скрипт загрузки плагина 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')}
        }
    }
`
  • каждый плагин сохраняется в папке плагинов / модулей. При установке зависимости также устанавливаются в папку автоматически.
  • this.enabled - это метод получения всех включенных плагинов. plugin.name получает имя пакета плагина.
  • Как только этот сценарий будет создан, программа запишет его в plugins / index.js , используя fs .
  • У меня есть функция связки, которая вызывается при запуске приложения
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)
}
  • Теперь я добавил скрипт dist / packages.js в html-файл перед основным файлом js (в моем случае dist / app.js).

  • Теперь у меня есть плагин BootstrapPlugin , доступный по всему миру, который устанавливает все остальные плагины

  • Все, что мне теперь нужно сделать, это использовать этот плагин в файле main.js (dist / app.js)

Vue.use(window.BootstrapPlugin)

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

Надеюсь, это кому-нибудь поможет: -)

...