A permissive license whose main conditions require preservation of copyright and license notices. Contributors provide an express grant of patent rights. Licensed works, modifications, and larger works may be distributed under different terms and without source code.
Минимайс
Минимайс — это простая, но мощная система плагинов, подобная OSGi и основанная на NodeJS. Она разработана с использованием ES6 и интегрированной среды разработки VSCode.
let minima = new Minima(path.join(__dirname, 'plugins'));
minima.start();
Архитектура Минимайса показана ниже.
Система имеет три функции:
$ npm install --g babel-cli
Установите с помощью npm:
$ npm install --save minimajs
Minima — это контейнер системы плагинов. Необходимо создать экземпляр системы плагинов и запустить его.
import { Minima } from 'minimajs';
import path from 'path';
let minima = new Minima(path.join(__dirname, 'plugins'));
minima.start();
Примеры плагинов
Создайте простой плагин в каталоге plugins, как показано ниже.
Файл plugin.json в папке demoPlugin показан ниже. Здесь определяется logService.
{
"id": "demoPlugin",
"startLevel": 5,
"version": "1.0.0",
"services": [{
"name": "logService",
"service": "LogService.js"
}]
}
Activator.js в папке demoPlugin показан ниже. Он обрабатывает extensionPoint «commands».
import { Minima, Extension, ExtensionAction, PluginContext, log } from 'minimajs';
export default class Activator {
constructor() {
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
this.handleCommandExtensions = this.handleCommandExtensions.bind(this);
this.extensionChangedListener = this.extensionChangedListener.bind(this);
}
/**
* 插件入口
*
* @param {PluginContext} context 插件上下文
* @memberof Activator
*/
start(context) {
context.addExtensionChangedListener(this.extensionChangedListener);
this.handleCommandExtensions();
}
handleCommandExtensions() {
let extensions = Minima.instance.getExtensions('commands');
for (let extension of extensions) {
let Command = extension.owner.loadClass(extension.data.command).default;
let command = new Command();
command.run();
}
log.logger.info(`The commands extension size is ${extensions.size}.`);
}
extensionChangedListener(extension, action) {
this.handleCommandExtensions();
}
stop(context) {}
}
Затем создайте ещё один плагин с именем demoPlugin2, как показано ниже. demoPlugin2 будет использовать logService, зарегистрированный demoPlugin, и регистрировать расширение в extensionPoint «commands».
В EchoCommand demoPlugin2 загрузит класс из demoPlugin.
// 1 plugin.config
{
"id": "demoPlugin2",
"version": "1.0.0",
"dependencies": [{
"id": "demoPlugin",
"version": "1.0.0"
}],
"extensions": [{
"id": "commands",
"data": {
"name": "echo",
"command": "commands/EchoCommand.js"
}
}]
}
// 2 Activator.js
import { PluginContext, log } from 'minimajs';
export default class Activator {
static logService = null;
constructor() {
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
}
/**
* 插件入口
*
* @param {PluginContext} context 插件上下контекст
* @memberof Activator
*/
start(context) {
let logService = context.getDefaultService('logService');
if (!logService) {
throw new Error('The logService can not be null.');
}
Activator.logService = logService;
logService.log('Get the logService successfully.');
}
stop(context) {}
}
После запуска... Текст запроса:
[2017-7-30 12:03:50.833] [INFO] log - Loading plugins from /Users/lorry/VSCodeProjects/minima-github/minimajs/example/build/plugins.
[2017-7-30 12:03:50.839] [INFO] log - Plugin demoPlugin is loaded from /Users/lorry/VSCodeProjects/minima-github/minimajs/example/build/plugins/demoPlugin.
[2017-7-30 12:03:50.840] [INFO] log - Plugin demoPlugin2 is loaded from /Users/lorry/VSCodeProjects/minima-github/minimajs/example/build/plugins/demoPlugin2.
[2017-7-30 12:03:50.840] [INFO] log - Plugins are loaded from /Users/lorry/VSCodeProjects/minima-github/minimajs/example/build/plugins completed.
[2017-7-30 12:03:50.841] [INFO] log - There are 2 plugins loaded.
[2017-7-30 12:03:50.845] [INFO] log - Starting the plugins with active initializedState.
[2017-7-30 12:03:50.846] [INFO] log - The plugin demoPlugin is starting.
[2017-7-30 12:03:50.929] [INFO] log - The commands extension size is 0.
[2017-7-30 12:03:50.954] [INFO] log - The plugin demoPlugin is active.
[2017-7-30 12:03:50.955] [INFO] log - The plugin demoPlugin2 is starting.
[2017-7-30 12:03:50.979] [INFO] console - Get the logService successfully.
[2017-7-30 12:03:51.033] [INFO] console - The echo command is executed.
[2017-7-30 12:03:51.034] [INFO] log - The commands extension size is 1.
[2017-7-30 12:03:51.034] [INFO] log - The plugin demoPlugin2 is active.
[2017-7-30 12:03:51.034] [INFO] log - The plugins with active initializedState are started.
Перевод текста на русский язык:
[2017–7–30 12:03:50.833] [INFO] log — Загрузка плагинов из /Users/lorry/VSCodeProjects/minima-github/minimajs/example/build/plugins.
[2017–7–30 12:03:50.839] [INFO] log — Плагин demoPlugin загружен из /Users/lorry/VSCodeProjects/minima-github/minimajs/example/build/plugins/demoPlugin.
[2017–7–30 12:03:50.840] [INFO] log — Плагин demoPlugin2 загружен из /Users/lorry/VSCodeProjects/minima-github/minimajs/example/build/plugins/demoPlugin2.
[2017–7–30 12:03:50.840] [INFO] log — Плагины загружены из /Users/lorry/VSCodeProjects/minima-github/minimajs/example/build/plugins, загрузка завершена.
[2017–7–30 12:03:50.841] [INFO] log — Загружено 2 плагина.
[2017–7–30 12:03:50.845] [INFO] log — Запуск плагинов с активным инициализированным состоянием.
[2017–7–30 12:03:50.846] [INFO] log — Начинается работа плагина demoPlugin.
[2017–7–30 12:03:50.929] [INFO] log — Размер расширения команд равен 0.
[2017–7–30 12:03:50.954] [INFO] log — Плагин demoPlugin активен.
[2017–7–30 12:03:50.955] [INFO] log — Начинается работа плагина demoPlugin2.
[2017–7–30 12:03:50.979] [INFO] console — Успешно получен доступ к службе logService.
[2017–7–30 12:03:51.033] [INFO] console — Выполнена команда echo.
[2017–7–30 12:03:51.034] [INFO] log — Размер расширения команд равен 1.
[2017–7–30 12:03:51.034] [INFO] log — Плагин demoPlugin2 активен.
[2017–7–30 12:03:51.034] [INFO] log — Запущены плагины с активным инициализированным состоянием. Текст запроса:
is Activator.js. This file is optional, thus, the plugin is started or stopped directly. The plugin may include other files also, such as HTML, CSS, and so on.
Below is a fully plugin.json example.
{
"id": "demoPlugin",
"name": "demoPlugin",
"description": "The demo plugin.",
"version": "1.0.1",
"startLevel": 5,
"initializedState": "active",
"activator": "PluginActivator.js",
"stoppable": true,
"dependencies": [{
"id": "demoPlugin",
"version": "1.0.0"
}],
"services": [{
"name": "myService",
"service": "MyService.js",
"properties": {
"vendor": "lorry"
}
}],
"extensions": [{
"id": "myExtension",
"data": {
"extensionData": "lorry"
}
}, {
"id": "myExtension2",
"data": {
"extensionData": "lorry2"
}
}, {
"id": "minima.menus",
"data": [{
"url": "view.js",
"text": "view"
}]
}]
}
Перевод текста на русский язык:
Это файл Activator.js. Этот файл является необязательным, поэтому плагин запускается или останавливается напрямую. Плагин также может включать другие файлы, такие как HTML, CSS и так далее.
Ниже приведён полный пример файла plugin.json.
{
"id": "demoPlugin",
"name": "demoPlugin",
"description": "Демонстрационный плагин.",
"version": "1.0.1",
"startLevel": 5,
"initializedState": "active",
"activator": "PluginActivator.js",
"stoppable": true,
"dependencies": [
{
"id": "demoPlugin",
"version": "1.0.0"
}
],
"services": [
{
"name": "myService",
"service": "MyService.js",
"properties": {
"vendor": "lorry"
}
}
],
"extensions": [
{
"id": "myExtension",
"data": {
"extensionData": "lorry"
}
},
{
"id": "myExtension2",
"data": {
"extensionData": "lorry2"
}
},
{
"id": "minima.menus",
"data": [
{
"url": "view.js",
"text": "view"
}
]
}
]
}
``` **Атрибуты**
Идентификатор — это уникальный идентификатор ExtensionPoint, данные — это содержимое расширения, которое будет зарегистрировано в ExtensionPoint и может быть получено с помощью метода getExtensions класса Minima.Instance или PluginContext.getExtensions.
```json
[{
"id": "myExtension",
"data": {
"extensionData": "lorry"
}
}, {
"id": "myExtension2",
"data": {
"extensionData": "lorry2"
}
}, {
"id": "minima.menus",
"data": [{
"url": "view.js",
"text": "view"
}]
}]
Атрибут data — это любое значение, определяемое плагином, который предоставляет ExtensionPoint. Атрибут data может быть строкой, массивом, объектом и т. д.
Activator предназначен для определения запуска и остановки. Каждый Activator содержит две функции с именами start и stop. Когда плагин запускается, вызывается функция start. Функция stop вызывается, когда плагин останавливается.
Activator является необязательным. Плагин может быть определён без Activator. Таким образом, он будет запускаться или останавливаться напрямую. Кроме того, файл Activator по умолчанию — Activator.js в каталоге плагина. Если вы определите Activator с другим именем файла, вам нужно указать атрибут activator в plugin.json.
Activator определяется следующим образом:
export default class Activator {
constructor() {
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
}
start(context) {
// TODO: do something when starting
}
stop(context) {
// TODO: do something when stopping
}
}
В каждой функции start и stop в Activator есть параметр с именем context. Это экземпляр PluginContext. Вы можете использовать PluginContext для доступа к функциональным возможностям фреймворка, таким как добавление или получение сервиса, получение расширений, получение плагинов, установка другого плагина и т.д.
Activator используется для инициализации ресурсов текущего плагина и освобождения их после остановки. Любое исключение, возникающее в функции start, блокирует запуск плагина, плагин останется в состоянии «разрешено». Но плагин всё равно остановится, если исключение произойдёт в методе stop.
PluginContext — это общий класс при определении плагина. Он предоставляет следующие функциональные возможности:
Плагин — ещё один общий класс при определении плагина. Он обеспечивает следующие функциональные возможности:
Фреймворк minimajs поддерживает установку, запуск, остановку и удаление во время выполнения. У каждого плагина есть установленные, разрешённые, запущенные, активные, останавливаемые, удалённые определения состояний.
Когда фреймворк устанавливает плагин, он читает файл plugin.json, проверяет plugin.json и создаёт экземпляр плагина. Если плагин установлен, его состояние — «установленное».
После установки плагина фреймворк немедленно разрешает его зависимости. Это означает, что плагин найдёт все зависимые плагины. Если зависимый плагин не существует или не может быть разрешён, плагин не может быть успешно разрешён, поэтому его состояние остаётся «установленным», в противном случае его состояние «разрешено». Как только плагин находится в состоянии «разрешён», это означает, что он готов к работе. Минимайз фреймворк: запуск, остановка и удаление плагина
Когда минимайз фреймворк запускает плагин, он выполняет следующие действия:
Когда минимайз фреймворк останавливает плагин, он выполняет следующие действия:
Когда минимайз фреймворк удаляет плагин, он выполняет следующие действия:
Как создать сервис
Сервис в минимайз фреймворке используется для взаимодействия между плагинами. Один плагин регистрирует сервис, другой плагин может использовать этот сервис. Сервис можно зарегистрировать и отменить регистрацию во время выполнения.
Сервис предоставляет некоторые общие функции, такие как определение класса LogService, как показано ниже.
export default class LogService {
log(message) {
if (message) {
console.log(message);
}
}
}
Мы можем зарегистрировать сервис в файле plugin.json или экземпляре PluginContext функции start в активаторе.
Можно указать имя, путь к файлу сервиса относительно каталога плагина и свойства сервиса. Обратите внимание, что свойства сервиса используются для фильтрации сервисов, зарегистрированных с тем же именем сервиса.
{
"id": "demoPlugin",
"startLevel": 5,
"version": "1.0.0",
"services": [{
"name": "logService",
"service": "service/LogService.js",
"properties": {
"vendor": "lorry"
}
}]
}
Также мы можем зарегистрировать сервис в активаторе.
export default class Activator {
constructor() {
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
}
start(context) {
this.logServiceRegistry = context.addService('logService', new LogService());
}
stop(context) {
context.removeService(this.logServiceRegistry); // This is Optional, it will be done by the minimajs framework when stopping.
}
}
Удаление сервиса в функции stop необязательно, минимайз фреймворк удалит сервисы, зарегистрированные плагином, при остановке.
Плагин может получить сервис с помощью PluginContext или Minima.instance.
Ниже показано использование PluginContext. Можно получить пустой сервис, если сервис не зарегистрирован или отменён, и необходимо убедиться, что сервис не равен нулю перед использованием сервиса.
export default class Activator {
constructor() {
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
}
start(context) {
let logService = context.getDefaultService('logService');
// or let logService = **Контекст.getDefaultService('logService', {vendor: 'lorry'})**
Пусть logServices = контекст.getServices('logService');
// или пусть logServices = контекст.getServices('logservice', {vendor: 'lorry'});
}
stop(контекст) {
}
}
4 Event
Вы можете использовать PluginContext или Minima.instance для прослушивания события изменения сервиса. Например, ниже.
export default class Activator {
static logService;
constructor() {
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
this.serviceChangedListener = this.serviceChangedListener.bind(this);
}
start(context) {
Activator.logService = context.getDefaultService('logService');
context.addServiceChangedListener
}
serviceChangedListener(name, action) {
if (name === 'logService') {
Activator.logService = context.getDefaultService('logService');
}
}
stop(context) {
}
}
Функция расширения предоставляет возможность плагину расширять функциональность другого плагина без изменения кода. Эта функция следует модели расширяемости ExtensionPoint-Extension. Расширение доступно при запуске плагина и удаляется после остановки.
Расширение, которое будет расширено во время выполнения, должно определить идентификатор extensionPoint. ExtensionPoint уникален. И плагин должен обрабатывать расширения, зарегистрированные другими плагинами.
import { Minima, Extension, ExtensionAction, PluginContext, log } from 'minimajs';
export default class Activator {
constructor() {
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
this.handleCommandExtensions = this.handleCommandExtensions.bind(this);
this.extensionChangedListener = this.extensionChangedListener.bind(this);
}
/**
* Плагин входа
*
* @param {PluginContext} контекст Контекст плагина
* Член Activator
*/
start(контекст) {
контекст.addExtensionChangedListener(this.extensionChangedListener);
this.handleCommandExtensions();
}
handleCommandExtensions() {
пусть расширения = Minima.instance.getExtensions('commands');
для (пусть расширение из расширений) {
пусть Command = расширение.владелец.loadClass(расширение.данные.команда).по умолчанию;
пусть команда = новая команда();
команда.запустить();
}
log.logger.info(`Размер расширения команд составляет ${extensions.size}.`);
}
extensionChangedListener(расширение, действие) {
этот.handleCommandExtensions();
}
остановить (контекст) {}
}
Плагин будет расширять функциональность другого плагина, он определит атрибут extensions плагина.json. Расширение и его содержимое должны соответствовать правилам ExtensionPoint.
Ниже приведён атрибут extensions файла plugin.json.
{
"id": "demoPlugin2",
"version": "1.0.0",
"dependencies": [{
"id": "demoPlugin",
"version": "1.0.0"
}],
"extensions": [{
"id": "commands",
"data": {
"name": "echo",
"command": "commands/EchoCommand.js"
}
}]
}
Ниже приведено определение EchoCommand.js.
импорт {Minima} из 'minimajs';
экспорт по умолчанию класс EchoCommand {
конструктор() {
это.run = это.run.bind(это);
}
запустить() {
пусть demoPlugin = Minima.instance.getPlugin('demoPlugin');
пусть Assert = demoPlugin.loadClass('utilities/Assert.js').по умолчанию;
Assert.notNull('demoPlugin', demoPlugin);
console.log('Выполнена команда echo.');
}
}
Расширение должно соответствовать требованиям ExtensionPoint.
Плагину, который может быть расширен другими плагинами, потребуется прослушивать событие изменения расширения и реагировать на него. Мы можем использовать PluginContext.addExtensionChangedListener или Minima.instance.addExtensionChangedListener для прослушивания события изменения расширения. ``` импорт { Minima, Extension, ExtensionAction, PluginContext, log } из 'minimajs';
экспорт default класс Activator { конструктор() { this.start = this.start.bind(this); this.stop = this.stop.bind(this);
this.handleCommandExtensions = this.handleCommandExtensions.bind(this);
this.extensionChangedListener = this.extensionChangedListener.bind(this);
}
/**
* 插件入口
*
* @param {PluginContext} context 插件上下文
* @memberof Activator
*/
старт(контекст) {
контекст.addExtensionChangedListener(this.extensionChangedListener);
this.handleCommandExtensions();
}
handleCommandExtensions() {
let extensions = Minima.instance.getExtensions('commands');
for (let extension of extensions) {
let Command = extension.owner.loadClass(extension.data.command).default;
let command = new Command();
command.run();
}
log.logger.info(`Размер расширения команд: ${extensions.size}.`);
}
extensionChangedListener(расширение, действие) {
this.handleCommandExtensions();
}
стоп(контекст) {}
}
**Как использовать журнал для поиска ошибок**
Имейте в виду, что вы можете получить подробную информацию из файла log.log в корневом каталоге среды выполнения.
## О проекте
### Вклад
Для сообщений об ошибках и запросов функций, пожалуйста, свяжитесь со мной по адресу: 23171532@qq.com.
### Автор
Ларри Чен
Имеет 10-летний опыт работы с фреймворком плагинов. Эксперт в OSGi.
## Дискуссионная группа QQ
При возникновении проблем, пожалуйста, свяжитесь со мной через группу QQ, как показано ниже.

## Лицензия
Apache License 2.0.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )