Перейти к основному содержимому

06 Проект bi-magic-resources

Данный проект является публичной версией закрытого проекта luxmsbi-web-resources. Оба проекта по функционалу идентичны и решают одни и те же задачи:

  • Управлять ресурсами всех атласов, а в общем случае умеет получать в виде файлов .json настройки атласа, дешбордов и дешлетов и изменять их прямо в проекте, с последующей выгрузкой на сервер.
  • Использовать git и версионировать разработку.
  • Настроить CI/СD для управления ресурсами на деве, тесте, проде и т.д.
  • Работать над ресурсами проекта командам разработчиков.
  • Позволяет вносить изменения в поведение и внешний вид итогового веб-клиента без привлечения devops и backend а лишь силами встроенных методов и скриптов проекта BMR и провайдера в лице luxmsbi-web-client
  • Можно массово загружать все ресурсы на сервер (или же только специфических атласов, если требуется), проверяя перед этим, новый ли это файл (т.е. его нужно на сервере создать), файл которого больше нет (его надо удалить на сервере), или существующий (будет перезаписан).

Первичная настройка проекта выглядит так:

  • Зайдите на https://github.com/luxms/bi-magic-resources
  • Ознакомьтесь с документацией в https://github.com/luxms/bi-magic-resources#readme
  • Сделайте форк данного проекта в свой github аккаунт и сделайте git clone себе на компьютер. Если у вас есть команда - то пусть это лучше сначала форкает тимлид, а вы потом клоните его версию, но это опционально. Идея только в том, чтобы вы использовали единый репозиторий по понятным причинам.
  • Этот проект создаст необходимое окружение.
  • Запустите npm install (или yarn, лично мы больше любим его).
  • В корне проекта найдите файл config.json и добавьте в поле server адрес инстанса Luxms BI ("server": "https//mysite.ru/").

Т.е. тот урл адрес, под которым у вас открываются дашборды, но только до символа “#”.
Вот полный список параметров config.json из документации (для ленивых):
В конфигурацию входят:


server - http адрес сервера, например "http://project.luxmsbi.com/"
username - имя пользователя для доступа к серверу. Требуются админские права
password - пароль для пользователя username
port - порт для запуска локального сервера для npm start
force - выдавать ли предупреждение перед обновлением источника
noRemove - запрещает удалять файлы, если при синхронизации они не найдены
include - регулярное выражение для схем, которые следует включить в сборку перед запуском проекта или отправкой на сервер (^ds_\w+$ по умолчанию)
exclude - регулярное выражение для схем, которые следует исключить из сборки (если например компоненты в указанных атласах не готовы для работы)
kerberos - http адрес сервера для аутентификации kerberos, например HTTP@sso.luxms.com

Если значения server, username или password нигде не найдены, то их потребуется ввести с клавиатуры.

Создайте в папке src папку ds_res (проект по умолчанию пустой и без файлов и папок, потому хотя бы одну папку нужно создать для запуска)

Создайте в корне проекта файл authConfig.json с содержимым


{
"master": {
"username": "ваш логин от BI",
"password": "ваш пароль"
}
}

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

P.S. Вы можете, вообще говоря, и указать просто


{
"username": "ваш логин",
"password": "ваш пароль"
}

Но первый способ вам понадобится, когда и если вы будете разрабатывать компоненты, находясь в другой ветке проекта. Тогда для каждой ветки нужно указать свою пару логина и пароля. Так можно делать, например? когда у вас будут отдельные ветки для дева, теста, прода, каждая из которых имеет свой адрес сервера и доступы к нему.

Концепция

Каждый ваш проект на BMR в идеале должен быть отдельным репозиторием (для учебных целей или личного пользования сойдет и простой форк проекта на Github). Где в качестве первого коммита можете использовать выбранную вами копию проекта BMR.

Если же вы хотите развернуть такой проект где-то в вашем аккаунте компании на Gitlab, то последовательность действий примерно такая:

Создаем у себя полностью пустой проект в гитлабе через веб-интерфейс (даже без Readme.md, отожмите соответствующую галочку), назовем его, например, так же bi-magic-resources.

git clone git@github.com:luxms/bi-magic-resources.git --origin luxms
cd bi-magic-resources
git remote add origin git@my.git.server.com:user/bi-magic-resources.git - вымышленный адрес вашего репозитория
git push origin master

Если будут изменения в нашем проекте на Github - забираем себе изменения:

git checkout master
git pull luxms master
git push origin master

И мержим ветку master в свои рабочие ветки

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

Каждая ветка данного проекта - это потенциально отдельный подпроект, который может содержать свой набор модулей в package.json, свой адрес сервера в config.json и свой набор ресурсов и логин-пароль в authConfig.json.

Однако мы настоятельно рекомендуем не использовать ветки как проекты, а лишь делать из них этапы некоего CI/CD и временные ветки для разработки фич. Для проектов делать-таки отдельный репозиторий.

к сведению

Если вы ведете разработку в закрытом контуре , то для установки node_modules вам потребуется доп.настройка от ваших DevOps репозитория с npm пакетами, к которому вы будете подключаться при установке пакетов.

Каждая папка внутри src данного проекта, которая начинается с префикса ds_ - это папка, отображающая разделы ресурсов одноименного атласа. Вы можете создавать и простые папки типа components, utils, services и прочие, но есть разница:

В папках произвольного именования файлы хранятся как есть и с ними ничего не происходит, если только они не являются частью импорта внутри компонентов, расположенных в папках ds_. Однако в папках с ds_ и их подпапках при старте приложения и предварительном билдовании перед отправкой на сервер все компоненты, если для них это имеет место будут билдиться вебпаком. Т.е. ваши MyComponent.tsx превратятся в MyComponent.js и MyComponent.js.map и именно эта пара уйдет на сервер при соотв. команде скрипта.

Процесс разработки

Рассмотрим ваш типичный рабочий процесс в данном проекте на примере.

Допустим, вам нужно создать совсем новый компонент визуализации, который вы хотите встроить в конкретный дешлет конкретного дешборда у некоего атласа (назовем его ds_51).

У вас есть два способа: через типы визуализации Внешний и Внутренний.
Их классы отображения соответсвенно external и internal.

В первом случае вы пишете хардкорный html с подключением стилей, скриптов, вспомогательной библиотеки bixel.js (подробнее в следующем разделе) или иными библиотеками для визуализации (D3.js например) и разрабатываете с учетом событийной системы, создаваемой данной библиотекой или пишете React компоненты и полностью используете только React-подход.

Лично мы пропагандируем использование internal как более гибкого способа разработки, плюс таким образом вы получаете по итогу цельное React-приложение + вам доступны ряд методов, которых нет и не может быть в external.

Допустим, что у вас есть ваши собственные UI-компоненты ,которые будут использоваться в более чем одном компоненте.
Вы можете хранить их например в папке src/components с любым деревом папок, которое вам удобно и импортировать в ваш React-компонент, который вы только что создали в папке ds_51.

Итак:

  1. Укажите адрес сервера в config.json, логин пароль в authConfig.json
  2. Создайте файлы MyComponent.tsx, MyComponent.scss и ряд еще каких-то файлов, которые вам понадобятся для разработки на сегодня. Вы выбрали разработку на internal, ибо таков Путь
  3. Перезапустите проект, если он был запущен на момент создания новых файлов , чтобы webpack проекта подхватил ваши файлы и следил за изменениями в дальнейшем.
  4. Откройте localhost с нужным портом, который можно поменять в config.json в ключе port.
  5. Отправляйтесь в соответствующий атлас, где находится дешлет, в который вы хотите встроить ваш новый компонент.

Простейший код компонента React MyComponent.tsx, например


import React from 'react';
import './MyComponents.scss';

class Test extends React.Component<any> {
constructor(props) {
super(props);
}
public render() {
return (
<div>Hello world</div>
);
}
}

export default Test; // обязательно должен содержать export default!

Или функциональный его вариант, без разницы


import React from 'react';
import './MyComponents.scss';

const Test = (props) {
return (
<div>Hello world</div>
);
}

export default Test;
  1. В режиме редактирования дешборда выберите или создайте нужный дешлет, укажите тип визуализации Внутренний и в блоке Файл выберите MyComponent.js ибо именно в таком виде вы его увидите в списке файлов. Сохраните работу и выйдите из режима редактирования. Уже к этому моменту вы увидите результат рендера вашего компонента. В примере выше это Hello world. Если вы посмотрите на дешлет через инспектор браузера, то никаких фреймов вы не увидите, потому что обвязка посчитает этот компонент нативной частью себя (и будет технически права).

  2. Вы разрабатываете компонент в соответствии с бизнес-логикой для него, пишете стили и т.д. Закончили, увидели удовлетворяющий вас результат на локальном сервере и готовитесь залить это в ресурсы на дев стенд и пойти домой под песню Патрика Суэйзи “She’s like the wind”.

  3. Все как обычно при работе с git:

git commit -am "Never gonna give you up"
git pull
git push

Я бы на всякий случай напомнил вам, что ветку master лучше использовать как финальный результат сборки и мержа иных временных веток (как продакшн). Или новыми ветками задать нужный вам уровень этапов деплоя, который вас устроит, например dev, test, production. Тогда каждый этап последовательно, без пропусков мержится в соответствующую ветку. dev-test, test-prod. Но не dev-prod (только в самых исключительных случаях и понимая, что делаете). Все зависит от того, как устроены процессы вашей разработки в компании. Не бойтесь мержа и ветвления. Просто договоритесь в команде, кто выступает в роли dungeon merge-мастера.

  1. Все, вы сохранили свой прогресс в git. Теперь будем отправлять ресурсы на сервер. Убедитесь, что перед этим, вы сделали git pull и у вас актуальная версия проекта (ветки) без неразрешенных мерж-конфликтов.
  2. Наберите команду yarn push (npm run push) и увидите, что в консоли идет подключение к серверу, который вы указали в config.json с логином и паролем из authConfig.json. Затем идет прогрессбар, отражающий этап сравнения вашей версии файлов и того, что на сервере.
  3. Затем вы увидите итоговый диалог, где проект подскажет вам статус файлов и запросит подтверждения на продолжение. Вводите Y и увидите прогрессбар окончательной загрузки ваших ресурсов на сервер.
  4. Прогрессбар завершился, ошибок нет. Идите на сервер по “боевому” адресу и проверьте ,что по ссылке на дешборд данного атласа не с локали вы видите тот же функционал, что и на локали. Это значит, что ресурсы корректно залились.
осторожно

Перед отправкой ресурсов на сервер через yarn push (npm run push) обязательно делайте git pull. Помните о том, что отправка ресурсов перепишет их контент на тот, что конкретно у вас сейчас в проекте. Потому. работая в команде, вы должны доверять только тому, что есть в git, а не на сервере. Избегайте заливки на сервер файлов, которых нет в git, иначе вы получите расхождение версий файлов и при ближайшем пуше ресурсов просто все удалите. Если вы таки не можете за этим следить, то хотя бы используйте ключ "noRemove": true внутри config.json

Ибо в скриптах ВMR есть такой хитрый скрипт yarn pull (npm run pull) который стоит использовать очень ограниченно и осторожно, в идеале разово при первичном наполнении ветки проекта или тогда, когда вы указываете в config.json ключ "dashboards": true, который, при использовании npm run pull позволит вам получить в проекте конфиги дешлетов, дешбордов и датасетов, которые будет храниться в специфических папках, которые у вас автоматически заведутся для каждой папки типа ds_ . Тогда вы сможете хранить конфиги в git и править конфиги этих сущностей так же массово, как вы будете управлять вашими компонентами.

Этот скрипт pull сам создаст все папки атласов, которые в данный момент присутствуют на сервере и скачает все файлы и рассортирует их по папкам, включая вложенные. Единственный его минус: он не умеет собирать из .js и .js.map пары итоговый .tsx например.
Простим ему) он и не должен, ибо ваши файлы в первую очередь хранятся в git, а не на сервере. Однако вам придется после его работы вручную удалять сбилженные версии ваших компонентов, которые прилетели с сервера, благодаря работе этого скрипта. Благо, что такая операция, как я уже говорил, делается очень редко если не сказать единожды.

к сведению

Вам не обязательно в BMR хранить полный перечень папок с атласами ,которые есть на сервере. Это не нужно. Храните только те, с которыми работает ваша команда сейчас. Те атласы, которые в BMR не присутствуют явно, просто не будут участвовать в итоговом массовой сборке и отправке при команде yarn push. То есть вы можете например создать папку ds_res и в ней хранить ровно тот набор компонентов, который хотите сейчас и не смотреть на ресурсы других атласов. Они останутся нетронутыми.