Javascript фреймворк разработки бизнес приложений

от автора

Мысль о своем фреймворке зародилась когда я еще активно работал с 1С. Хотелось иметь простую и открытую платформу для создания несложных бизнес приложений (простые системы учета, CRM и прочие). Не раз искал open source решения, но ничего подходящего не находил.

Весной 2011-го открыл здесь полемику на тему свободного ПО в области систем учета. Решили даже делать HabraERP. Мне пришлось по состоянию здоровья выпасть на два месяца, а по возвращению я ожидаемо увидел что все заглохло.

Хоть с HabraERP дальше обсуждений дело не пошло, я понял, что создание нужной мне платформы-фреймворка — возможно.

Спустя неполных 10 лет я готов представить вам KateJS — открытый javascript фреймворк разработки бизнес-приложений.

История

Как создавался фреймворк

Было понятно, что единым языком для клиента и сервера будет Javascript. Сначала была идея сделать сервер на Java c подключенным движком для JS, однако, я довольно быстро осознал, что нужную квалификацию даже для минимальной версии буду набирать неоправданно долго. Обратил внимание на NodeJS. Пройдя первый же туториал понял — это то что нужно.

Фронт первой версии был на ExtJS — я взял то, что визуально напоминало учетные системы. На волне популярности NoSQL в качестве СУБД была выбрана CouchDB.

Получившийся в результате монстрик слабо напоминал фреймворк и был ужасен во всех смыслах. Однако, на нем была разработана система расчета и учета заказов для отдела продаж, которая была внедрена и проработала несколько лет в небольшой типографии.

Признав первую версию тупиковой, я взялся за вторую.

Намучавшись с ExtJS, фронт решено было сделать полностью своим — на базе верстки от Bootstrap, jQuery и отдельных виджетов. Бэк чуть более структурировался, а вот СУБД осталась прежней.

В процессе разработки были сформулированы и отработаны основные принципы: скорость, простота и удобство разработки приложений. Была проработана модульная структра.

На второй версии фреймворка было сделано несколько приложений, два из которых — учет в компании по предоставлению автомобилей в аренду, автоматизация сбора отчетности почтальонов — работают до сих пор.

Летом 2017го я ушел с насиженного места и погрузился в профессиональную вэб-разработку — устроился front-end разработчиком, а спустя некоторое время в рамках той же компании расширил свою квалификацию до fullstack. Первое время открывал что-то новое практически каждую неделю, а когда уже поднабрался опыта решил — третьей версии фреймворка — быть.

В основу фронта лег React, бэка — Koa
CouchDB и map/reduce — очень удобные и красивые штуки. Но не для учетных систем: «стандартная» задача как отбор и сортировка по нескольким полям одновременно превращается в головную боль. Хоть за несколько лет я уже привык к CouchDB, по объективным причинам решил взять реляционную СУБД: в фреймворке используется ORM Sequelize, проекты тестировались на MySQL и SQLite.

Основу удалось собрать чуть менее чем за год. Фреймворк даже пригодился на работе — один проект был полностью сделан на нем, во втором — для «админки» была использована фронт часть. Была разработана и успешно внедрена программа учета для сети компаний доставки здорового питания.

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

Идея

В основе фреймворка KateJS заложены три основных принципа:

  • Скорость. Фреймворк минимизирует временные затраты на сопутствующие вопросы и позволяет разработчику заниматься преимущественно бизнес логикой.

  • Простота. Несложная концепция и принципы разработки позволяют решать базовые задачи через пару часов изучения фреймворка.

  • Удобство. Модульность — в основе архитектуры. Легко использовать чужие модули и делать свои.

Приложение со стороны клиента описывается клиентским приложением, которое определяет набор форм, каждая из которых представляет собой набор элементов (поле ввода, кнопка, надпись и т.п.) и кода, который описывает их поведения. Приложение со стороны сервера описывается серверным приложением, которое определяет набор сущностей: в общем случае — классов, к методам которых идет обращение с фронта и других сущностей.

Особенности

Генерация по структуре

Самое сложное — начать. Но не в нашем случае. Как только мы определим и опишем структуру данных нашего приложения, мы сразу же получаем живой прототип.

Допустим нам нужен учет доходов в разрезе статей. Нам нужны две сущности — статьи доходов и доходы.

import Fields from 'katejs/lib/fields';  const IncomeArticle = {   fields: [     {       name: 'title',       type: Fields.STRING,     },   ], };  const Income = {   fields: [     {       name: 'date',       type: Fields.DATE,     },     {       name: 'article',       type: Fields.REFERENCE,       entity: 'IncomeArticle',     },     {       name: 'sum',       type: Fields.DECIMAL,     },   ], }; 

Синхронизируем БД и можем добавлять статьи доходов, вводить доходы и выбирать в них созданные статьи.

картинка из руководства - там чуть больше сущностей и полей
картинка из руководства — там чуть больше сущностей и полей

Сущности могут иметь не только примитивные и ссылочные поля, но также и «табличные части», на которые также автоматически генерируется интерфейс в виде редактируемых таблиц.

Императивное управление формами

Реактивные формы это конечно хорошо, но старый добрый императивный подход проще и понятней. Работа с интерфейсом в KateJS похожа на работу с интерфейсом в визуальных средах: накидываем контроллов на форму и прописываем обработчики событий, в которых меняя свойство атрибута элемента, мы меняем его вид/поведения.

export default class Register extends Form {   constructor(args) {     super(args);      this.elements = [       {         id: 'email',         type: Elements.INPUT,         title: 'E-mail',       },       {         id: 'password1',         title: 'Password',         type: Elements.INPUT,         onChange: () => this.validate(),         inputType: 'password',       },       {         id: 'password2',         title: 'Confirm password',         type: Elements.INPUT,         onChange: () => this.validate(),         inputType: 'password',       },       {         id: 'errorMessage',         type: Elements.LABEL,         title: 'Passwords do not match',         hidden: true,       },       {         id: 'register',         title: 'Register',         type: Elements.BUTTON,         onClick: () => this.register(),         fullWidth: true,       },     ];   }   validate() {     // Доступ к элементу форм происходит через this.content[element_id]     const valid = this.content.password1.value === this.content.password1.value;     this.content.register.disabled = !valid;     this.content.errorMessage.hidden = valid;   }   register() {     // register logic   } } 

Модульность — наследование

Если вам нравится чье-то открытое решение, но хочется добавить в него что-то от себя, можно, конечно, взять код и поправить его в нужных местах. Но если оригинальное решение после этого доработали, а вам нужны и эти доработки и свои, то придется непросто.

В KateJS формы, сущности и приложения несложно изменить, не меняя их исходный код. Можно отнаследоваться от оригинального класса и поменять его поведение. Пример. Элементы формы создаются в конструкторе в свойстве-массиве elements: чтобы изменить форму, достаточно внести в этот массив изменения. В автоматически сгенерированной форме IncomeItem элементы с id wallet и article идут друг под другом; чтобы расположить их в линию — объединим их в группу. Код класса формы нам недоступен, чтобы отнаследоваться напрямую, но сам класс доступен, поэтому воспользуемся класс-миксином: IncomeFormMixin

 export default ItemForm => class IncomeItem extends ItemForm {   constructor(args) {     super(args);     this.elements.splice(1, 2, {       type: Elements.GRID,       elements: [         { ...this.elements.get('wallet'), cols: 6 },         { ...this.elements.get('article'), cols: 6 },       ],     });   } }; 

поле-массив elements дополнено методом get для получения элемента по его id

AppClient

    ...      this.forms = {       ...this.forms,       IncomeItem: IncomeFormMixin(this.forms.IncomeItem),     };      ... 

Конкретно такой способ не идеален, т.к. основывается на индексе элементов, но подход иллюстрирует.

Сами приложения — клиентское и серверное — также описываются класс-миксинами, что автоматически позволяет их использовать как модули. К примеру, приложение AppUser добавляет сущности User, Role, формы авторизации и регистрации. Все что нужно для его подключения и добавления в ваше приложение этой функциональности — просто указать его в списке родителей.

import { AppUser } from 'katejs-modules/lib/client';  const AppClient = parent => class Client extends use(parent, AppUser) {   ... } 

Точно также и ваше приложение автоматически становится модулем и может быть использовано другими разработчиками. Если вы его опубликуете.

В комплекте к фреймворку идет несколько модулей (пользователи и роли — один из них), которые описаны в документации.

Примеры

Первым примером хочу привести «проект выходного дня» — Passstore — корпоративный менеджер паролей. Приложение хоть и синтетическое, но вполне может подойти компаниям, занимающимся разработкой на заказ со штатом 5+ человек. В приложении ведется список проектов, в каждом из которых указывается список участников с указанием их роли в проекте. Учетные данные — пароли — привязываются к проекту, с указанием ролей, которым разрешено эти данные просматривать. В итоге те, кому можно, видят то, что нужно.

Приложение для простоты использует SQLite и готово к запуску сразу после установки зависимостей. Но можно его частично оценить без лишних телодвижений: по ссылке выше можно покликать readonly вариант.

Сам проект Passstore сделан менее чем за день. Больше времени ушло на создание readonly демо версии и оформление сайта.

Второй пример — Ассистент — простая система учета. Позволяет вести учет денежных средств, взаиморасчетов, товарных остатков, формировать на основе данных отчеты. Каких-либо отчетных форм для ИФНС приложение не содержит.

Пардон за повтор картинки
Пардон за повтор картинки

Развернуть приложение несложно — в репозитории есть базовая информация по настройке. Если планируете дорабатывать — лучше использовать его как модуль: в этом случае, при появлении обновлений достаточно будет просто поставить свежий пакет.

Если вам интересна учетная система как пользователю — напишите мне в личку — скину доступ в развернутый вариант.

Итого

К фреймворку я подготовил документацию, включающую небольшое руководство: создание системы учета личных финансов. Документация и исходники доступны по ссылкам на KateJS.ru

Фреймворк, модули, Ассистента я развиваю в свободное от работы время. Буду рад, если фреймворк придется вам по душе и вы решите что-нибудь реализовать на нем. По мере возможности готов отвечать на вопросы и исправлять недочеты.

Если у вас появятся идеи по развитию самого фреймворка или, например, Ассистента — пишите — обсудим.

ссылка на оригинал статьи https://habr.com/ru/post/520012/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *