Всем доброго времени суток, вы попали на цикл статей о разработке cms (система управления контентом). CMS будет разрабатываться на TypeScript, среда исполнения bun.js. Для упрозщения развертывания cms будет скопилирована в один исполняемый файл. Статьи по проекту буту выходить с переодичностью в 1-2 недели.
Для начала рассмотрим какими свойствами cms будет обладать:
- CMS все в одном, когда не надо дополнительных внешних баз данных, систем мониторинга
- Автоматическое развертывание системы в момент первого запуска. В автоматику входит создание всех базовых директорий, добавлений всех базовых файлов, шаблонов админки и базового шаблона, базовые насйтрови, а также первоначальная установка и настройка самой cms (создание учетной записи администратора, название и адрес сайта и другие параметры).
- Свой собственный текстовый редактор, работающий в формате модулей (каждый абзац, медиа, и дургие компоненты как отдельный моуль страницы)
- Возможность связывания страниц по критериям с возможностью перехода между ними (например, связывать новости по истории изменений), а также мультиязычность
- Функционал по точечной настройки отображения и доступности на основе geoip
- Базовые функции для SEO, robot.txt и sitemap.xml которые формируются автоматически
- Отслеживание посещений с фиксацией откуда был переход
- Автоматическое получение Let's encypt сертификатов и управлениями сертификатами
- Встроенная система бекапирования (в разные места) и система мониторинга нагрузки
- Система оповещений (почта, чаты, соц сети)
- Двухфакторная авторизация (с точечной настройкой)
- Кластеризация с масштабированием, с возможностью зонирования
Все статьи будут строиться по формату:
- Описание, что будет в этой статье
- Глосари, если будут использоваться новые термины
- Исправления, если будут в этой статье и автотесты к этим исправлениям
- Добавление нового функционала или переработка уже ранее созданного функционала
- Создание или актуализация автотестов
Сформатом статей определились, теперь займемся инициализацией проекта и созданием первых элементов системы автоматического развертывания самой cms. Проект будем писать в Zed IDE. Ранее я использовал VS Code, но решил посмотреть Zed IDE в деле.
Инициализация проекта осуществляется через bunjs следующей командой
bun init
В момент инициализации bun уточняет только один пункт необходимый нам:
и мы выбирем Blank (пустой проект).
После чего проект автоматически создается. В консоли выглядит следующим образом
А в директории создадуться несколько файлов и одна директория
Изначально при инициализации проекта bunjs автоматически создает index.ts, который и переименуем в cms.ts. После чего создадим скрипт запуска сервера, с автоматическим перезапуском сервера при изменение любого файла. Еще в файле будет добавлена версия проекта, сейчас она будет иметь версию 0.0.0-pre+1
На данном этапе мы с вами закончили с подготовкой проекта. Следующим этапом мы займемся созданием части системы инициализации, которая будет отвечать за проверку директорий и их создание. В корне создадим директорию init. В ней будут находиться все компоненты от системы инициализации и системы обновления (там будут компоненты по добавления или изменения шаблонов, структуру БД и дургие компоненты). В данной директории создадим файл initServer.ts и initFolderAndFile.ts. В initServer.ts будет центральной точкой инициализации. initFolderAndFile.ts в свою очередь будет находиться компоненты для работы с файлами и директориями.
Начнем реализацию кода с файла initFolderAndFile.ts. В нем мы создадим класс InitFolderAndFile и два метода constructor и checkDirectory, а также массив со всеми путями folders. На данный момент у нас всего 4 директории которые мы будем отслеживать.
Для работы дальнейшей работы нашего класса, мы должны вызвать методы для работы с файлами, а также типы данных для корректного типизации переменных.
Далее опишем функциональности метода checkDirectory. Наш метод будет изолирован в пределах класса и по этому будет иметь дополнительную опцию private, также данная функция будет использоваться в формате async/await. Функция будет принимать один параметр folderName и иметь тип данных string. В данную переменную будет передавать полный путь до директории проекта с директорией которую мы будем проверять (сборка полного пути будет производиться в функции constructor).
Из ранее ипортированной функций stat мы получаем информацию о директории или файле, если файла нет, то у нас выполняется блок catch (фиксация в лог файл мы добавим в следующих статьях). Переменная status имеет тип данных Stats, которая позваляет корректно хранить данные от результата выполнения функции stat (TypeScript является языком со строгой типизацией, в связи с этим нужно всегда выбирать корретные типы данных). await у stat позволяет дождаться опирации получения данных. Метод isDirectory у status отдает нам boolean ответ на проверку является ли запрошенный элемент директорией.
Далее реализуем код конснтруктора класса. В нем мы будем переберать массив с нашими директориями и заправшивать проверку существования директории, которую мы ранее создали. Для полного пути мы будем использовать функцию join, которую импортировали ранее. Данная функция позволяет создавать безопастные пути для дальнейшей работы с ними. __dirname позволяет подставить мето нахождения исполняемого файла. После этого мы для удобства выведем статусы в консоль (для этого будем использовать console.log()).
Подготовив все экспартируем класс через
export default InitFolderAndFile;
Теперь попробуем проверить работу нашего класса, сразу вывзав его в InitServer.
После этого производим вызов уже самого InitServer в главном файле проекта
Хочется отметить, что такой вызов в cms.ts временный, в дальнейшем мы будет переписывать данный файл не один раз.
Производим запуск приложения через
bun run dev
и в консоле видим следующий результат (сначала директория, потом статус).
Далее создадим функцию которая будет заниматься созданием наших директорий, createDirectory. Данная функция также будет private и асинхронной.
После создания данной функии добавим ее в работу после проверки наличия директории в конструктор. Ранее созданный console.log мы уберем, т.к. проверять корректность работы мы будем уже по средствам работы с функции создания директорий. При вызове функции мы добавили обработчик ошибок catch, что бы потом иметь возможность залогировать ошибку.
А теперь запускаем наше приложение. В консоле теперь ничего не отображается, но все изменения у нас теперь в папке проекта, теерь там появились все наши дополнительные директории. Директория tests было создана заранее для автотестов, которыми мы и займемся чуть позже.
На этом первую часть мы с вами заканчиваем. В следующей части реализуем автотесты для созданного функционала создания проверки и создания директорой.