Создать приложение
Это руководство даёт обзор начальной конфигурации, охватывая фронтенд, базу данных и API-сервис. Мы быстро и практично создадим новое fullstack-приложение.
Введение
Хотя платформа является полиглотом и поддерживает различные языки программирования, в этом руководстве мы сосредоточимся исключительно на использовании JavaScript. В результате мы создадим практическое приложение, состоящее из формы, отображаемой в модальном окне (pop-up), с функцией экспорта данных в PDF.
Предварительные требования
Перед началом убедитесь, что у вас есть:
-
Платформа Netuno, предварительно установленная на вашем компьютере. Если у вас возникнут вопросы на этом этапе, обратитесь к руководству Установка платформы.
-
Доступ к терминалу или командной строке в среде разработки.
Создать новое приложение
Выполните приведённые ниже инструкции, чтобы инициализировать новое приложение:
Откройте терминал и перейдите в корневую папку, где установлен Netuno.
Выполните команду создания приложения:
./netuno app
Создание с параметром
Можно задать имя приложения непосредственно при выполнении команды, например:
./netuno app name=moio_prilozhenie
При задании имени приложения избегайте пробелов, диакритических знаков или специальных символов. Предпочитайте строчные буквы, разделённые дефисами или подчёркиваниями (например: app-prodazhi или upravlenie_personalom), чтобы сохранить совместимость с URL-адресами и папками системы.
Начальная конфигурация
Мастер командной строки задаст несколько вопросов для настройки вашего проекта. Укажите:
- Имя приложения: идентификатор вашего проекта.
- Тип базы данных: система управления базами данных, которая будет использоваться.
- Язык: язык интерфейса вашего приложения по умолчанию.
Рекомендация базы данных для начинающих
Во время пошаговой настройки, когда будет предложено выбрать тип базы данных, рекомендуем выбрать H2 Database.
H2 Database — встроенная база данных, уже интегрированная в сервер Netuno. Большое преимущество в том, что она не требует установки или настройки внешних серверов (таких как PostgreSQL или MySQL), что делает начальную разработку и тестирование гораздо практичнее и быстрее.
Команда для запуска сервера
После создания нового приложения запустите сервер платформы Netuno. Это сделает ваш проект доступным в браузере и готовым к дальнейшей разработке.
Выполните приведённую ниже команду в терминале и дождитесь запуска.
./netuno server app=moio_prilozhenie
Передав параметр app=moio_prilozhenie, сервер понимает, что это будет приложение по умолчанию, выполняемое в данном экземпляре. Когда сервер работает, вы уже можете начать редактировать свой проект.
Все файлы и исходный код вашего приложения хранятся и упорядочены внутри папки 📂 apps/moiapp.
При первом доступе к интерфейсу администрирования Backoffice вашего приложения система запросит аутентификацию. Для локальных сред разработки используйте следующие стандартные учётные данные:
Пользователь: dev
Пароль: dev
Рекомендуем изменить эти учётные данные при переносе приложения в производственную среду.
Редактор кода
Чтобы обеспечить лучший опыт разработки, мы рекомендуем использовать современные лёгкие редакторы кода с хорошей экосистемой расширений.
Если у вас ещё нет любимого редактора, рекомендуем следующие бесплатные варианты, широко используемые сообществом:
- VS Codium: vscodium.com
- VS Code: code.visualstudio.com
- WebStorm: jetbrains.com/webstorm
Примечание: если вы предпочитаете более мощные инструменты и не против инвестировать в лицензии, WebStorm от JetBrains — отличный премиальный вариант.
Откройте папку приложения в вашем редакторе:
📂 apps/moio_prilozhenie
Все файлы приложения хранятся и упорядочены внутри этой папки. Вся разработка, создание маршрутов, логика базы данных и визуальные интерфейсы будут происходить внутри этой папки.
Чтобы точно знать, где создавать каждый тип файлов и как Netuno организует бэкенд и фронтенд, рекомендуем прочитать подробную документацию о структуре папок приложения:
Смотрите руководство: Папки приложения
Краткое описание этапов
Закрепив начальные знания о Netuno, мы применим эти концепции на практике, создав полноценную функциональность от начала до конца.
Практическая цель — добавить в интерфейс два новых интерактивных компонента:
- Кнопку, отвечающую за загрузку и отображение формы клиентов внутри плавающего окна (Modal).
- Кнопку, предназначенную для генерации и экспорта списка зарегистрированных клиентов в PDF-файл.
Чтобы достичь этого результата организованно и понятно, мы разделили разработку на логическую последовательность этапов. Мы будем следовать этому сценарию:
-
Картирование интерфейса: проанализировать структуру папок приложения, чтобы найти, где определён основной HTML дашборда.
-
Интеграция с React: настроить и добавить основу двух новых кнопок с использованием фреймворка React во фронтенде.
-
Логика модального окна: построить и запрограммировать поведение кнопки для корректного открытия формы клиентов.
-
Интерфейс экспорта: построить и разместить в интерфейсе кнопку, которая запустит скачивание PDF-файла.
-
Разработка сервиса (API): запрограммировать бэкенд, создав сервис, который будет читать данные и динамически генерировать PDF-файл со списком клиентов.
Начнём!
Шаблон дашборда
Перейдите в папку server/templates и откройте файл, отвечающий за предоставление HTML экрана дашборда.
server/templates/dashboard.html
Изучая код файла dashboard.html, прокрутите страницу до конца. Вы найдёте изолированный элемент <div>. Именно в этой точке платформа Netuno «внедряет» и запускает весь интерактивный интерфейс, построенный на React.
...
<div id="app-dashboard"></div>
Хотя HTML-скелет находится в папке server/templates, фактическая разработка интерфейса и визуальная логика происходят не там.
Чтобы изменить поведение дашборда или добавить новые компоненты с помощью React, необходимо перейти в папку, предназначенную для разработки фронтенда.
Именно в этой папке 📂 ui/ вы найдёте компоненты дашборда и сможете разрабатывать новые визуальные функциональности вашего приложения.
Создать форму
На этом этапе мы создадим структуру базы данных, необходимую для этого руководства: форму с названием Клиент, содержащую текстовое поле Имя.
- В Backoffice откройте область разработки, нажав кнопку Сборка (в правом верхнем углу).
- В боковом меню перейдите в Управление > Формы и создайте новую форму с Заголовком: Клиент.
- Нажмите Сохранить.
Имя таблицы будет автоматически заполнено как klient (оставьте в нижнем регистре, как рекомендуется для баз данных).
Если у вас есть вопросы по расширенным настройкам этого экрана, обратитесь к полной документации в разделе Формы.
Создать поле
После создания формы она появится в левом боковом меню в категории Поля.
- Нажмите Клиент, чтобы добавить новый столбец:
- Введите текст «Имя» в Заголовок поля.
- Выберите тип данных "text" в поле Тип.
- Отметьте параметры Разрешить фильтрацию (чтобы включить поиск) и Показывать в результатах (чтобы отображать в таблице).
- Нажмите Сохранить.
Чтобы понять все доступные типы данных и их свойства, обратитесь к подробной документации в разделе Поля.
Вставить тестовые данные
Чтобы мы могли протестировать экспорт PDF на следующих этапах, нам нужны реальные данные в системе.
- Нажмите кнопку Просмотр (в правом верхнем углу), чтобы вернуться в Backoffice для использования приложения.
- Откройте недавно созданное меню Клиент в боковой панели.
- Используйте кнопку + Добавить, чтобы зарегистрировать несколько тестовых клиентов в системе.
- Нажмите Сохранить.
Запрос к базе данных
Netuno предлагает встроенный инструмент, позволяющий выполнять SQL-команды напрямую в базе данных вашего приложения. Он становится незаменимым для быстрых запросов, проверки информации или гибкого управления данными системы.
Чтобы открыть интерфейс запросов и выполнить команды, выполните следующие шаги:
- В основном интерфейсе откройте область разработки, нажав кнопку Сборка.
- В боковом меню навигации найдите раздел Управление.
- Нажмите Query, чтобы открыть консоль базы данных.
- В текстовом редакторе, который появится на экране, введите SQL-команду, которую хотите выполнить.
- Подтвердите выполнение команды.
Выполните команду ниже, чтобы запросить зарегистрированных клиентов:
SELECT * FROM klient
Когда закончите запросы и захотите вернуться в пользовательский интерфейс системы (backoffice), просто нажмите кнопку Просмотр.
Добавить кнопки с помощью React
На этом этапе мы настроим основной файл панели дашборда, чтобы отобразить две новые кнопки.
В архитектуре интерфейса мы используем концепцию контейнеров для определения обширных областей системы, которые охватывают более крупные функциональности и группируют несколько меньших компонентов.
-
В редакторе кода перейдите в папку контейнеров
📂 ui/src/containers. -
Найдите и откройте основной файл дашборда:
📂 DashboardContainer/index.jsx. -
Вставьте код импорта и рендеринга компонентов, как в примере ниже.
import { Space } from 'antd';
import KnopkaKlientModal from '../../components/KnopkaKlientModal';
import KnopkaPDF from '../../components/KnopkaPDF';
import "./index.less";
function DashboardContainer() {
return (
<div className="moi-dashboard">
<Space>
<KnopkaKlientModal />
<KnopkaPDF />
</Space>
</div>
);
}
export default DashboardContainer;
Обратите внимание, что этих файлов кнопок ещё физически нет в вашем проекте. Поскольку это меньшие и переиспользуемые компоненты, мы создадим их в папке специализированных компонентов.
Всегда разделяйте контейнеры (области широкого охвата, такие как целые страницы или дашборды) и компоненты (изолированные элементы интерфейса, такие как кнопки и модальные окна). Это делает ваш код в Netuno намного чище, проще в поддержке и масштабируемым.
Кнопка для формы
Перейдите в папку ui/src/components/ и создайте новую папку KnopkaKlientModal.
Внутри папки KnopkaKlientModal создайте основной файл компонента с именем index.jsx.
📂 ui/src/components/KnopkaKlientModal/index.jsx
Откройте файл и вставьте код ниже:
import { Button } from 'antd';
function KnopkaKlientModal() {
const onClick = () => {
netuno.modal.create({
name: 'klient',
callback: function (okno) {
let forma = okno.find('[netuno-form]');
forma.on('netuno:new', () => {
console.log('Создание нового клиента.');
});
forma.on('netuno:save', () => {
netuno.modal.hide(okno)
console.log('Клиент сохранён.');
});
forma.on('netuno:delete', () => {
netuno.modal.hide(okno)
console.log('Клиент удалён');
});
forma.on('netuno:back', () => {
console.log('Нажата кнопка "Назад"');
});
netuno.loadForm(forma);
netuno.modal.show(okno);
}
});
};
return (
<div>
<Button type="primary" onClick={ onClick }>
Открыть форму клиента
</Button>
</div>
);
}
export default KnopkaKlientModal;
Разбираем код
Магия этого компонента происходит внутри функции onClick, которая использует глобальные инструменты интерфейса Netuno:
-
netuno.modal.create(): этот метод создаёт модальное окно на экране и привязывает к нему нужную форму (в данном случае форму с именем
klient). -
События формы (
forma.on): блок callback позволяет нам «слушать» действия пользователя. Мы можем запускать пользовательские действия, когда пользователь создаёт запись (netuno:new), сохраняет (netuno:save), удаляет (netuno:delete) или нажимает «Назад» (netuno:back). -
netuno.modal.hide() / show(): методы, используемые для скрытия модального окна после успешного действия или его показа после загрузки формы.
Теперь, когда компонент KnopkaKlientModal успешно создан, импорт, который мы сделали ранее в вашем DashboardContainer, начнёт работать без ошибок, и кнопка уже должна отображаться на экране!
Кнопка для экспорта PDF
На этом этапе мы создадим вторую кнопку дашборда: кнопку экспорта PDF.
Основная функция этого компонента в интерфейсе — быть триггером: при нажатии он отправит запрос в backend-сервис, который обработает данные системы и сгенерирует PDF-файл со списком зарегистрированных клиентов.
-
Перейдите в папку
ui/src/components/и создайте новую папку KnopkaPDF. -
Создайте в этой папке файл index.jsx.
ui/src/components/KnopkaPDF/index.jsx
Откройте файл и вставьте код ниже:
import { Button } from 'antd';
function KnopkaPDF() {
return (
<div>
<Button
type="primary"
href="/services/klient/eksport-pdf"
target="blank">
Экспортировать PDF
</Button>
</div>
);
}
export default KnopkaPDF;
После создания компонента KnopkaPDF обе кнопки, объявленные в вашем DashboardContainer, готовы.
Визуальная структура и компоненты готовы. Скомпилируйте фронтенд, чтобы протестировать отрисовку интерфейса.
Создание backend-сервиса, который фактически будет генерировать PDF, будет рассмотрено на следующем этапе.
Скомпилировать фронтенд
Веб-браузеры не понимают нативно код, написанный на React, файлы .jsx или .tsx и препроцессоры CSS, такие как .less. Чтобы ваш интерфейс работал корректно, необходимо пройти процесс компиляции (build). Этот процесс транслирует, упаковывает и оптимизирует весь ваш код в конечные статические файлы (обычные JavaScript и CSS), которые браузер может обрабатывать с максимальной эффективностью.
Предварительные требования
Перед началом компиляции убедитесь, что:
-
У вас открыт терминал или командная строка в среде разработки.
-
Менеджер пакетов
Bunкорректно установлен в вашей системе.
Примеры компиляции
Netuno предоставляет разные команды в зависимости от этапа разработки. Из корневой папки Netuno перейдите в папку ui вашего приложения.
Выполните команды внутри папки интерфейса вашего приложения: 📂 apps/moiapp/ui
Сборка для продакшена
Выполняет полную и оптимизированную компиляцию файлов. Это идеальная команда для случая, когда вы завершили разработку экрана или компонента и хотите сгенерировать лёгкие итоговые файлы с лучшей производительностью.
bun run build
Сборка для разработки
Команда watch выполняет быструю сборку и отслеживает папку. Каждый раз, когда вы сохраняете файл в редакторе, терминал автоматически запускает компиляцию.
bun run watch
Независимо от используемой команды — build или watch — изменения не появляются на экране пользователя мгновенно. Обновите страницу backoffice в браузере, чтобы загрузить новые сгенерированные файлы.
Во время разработки ошибки могут возникать на двух разных этапах. Знайте, где их искать:
-
Ошибки компиляции: синтаксические ошибки в коде React или необъявленные переменные будут отображаться прямо в терминале, где выполняется команда bun.
-
Ошибки выполнения: сбои, возникающие во время использования приложения, будут отображаться в консоли браузера. Всегда помните о необходимости инспектировать страницу, чтобы проверить наличие предупреждений или ошибок.
Интегрированная сборка
Функция интегрированной сборки позволяет автоматически выполнять команды терминала вместе с запуском сервера. Это оптимизирует рабочий процесс, объединяя все логи и мониторинг в одном центральном терминале.
Чтобы включить интегрированную сборку, необходимо изменить настройки разработки вашего приложения:
-
Перейдите в корневую папку вашего приложения.
-
Откройте файл конфигурации разработки:
_development.json. -
Найдите блок кода, относящийся к "commands".
-
Измените значение свойства "enabled" с false на true.
-
Сохраните файл.
Ваш файл _development.json должен иметь структуру, похожую на эту:
...
"commands": [{
"command": "bun run watch",
"enabled": true,
"install": "bun install",
"path": "ui"
}],
...
Чтобы Netuno прочитал обновлённый файл и применил новую конфигурацию, необходимо перезапустить сервер:
-
Перейдите в терминал, где выполняется сервер Netuno.
-
Завершите процесс, одновременно нажав клавиши CTRL + C.
-
Снова запустите сервер, указав имя вашего приложения:
./netuno server app=moiapp
После перезапуска сервера наблюдайте за логами в терминале. Вы заметите, что Netuno теперь автоматически выполняет команды сборки фронтенда bun run watch в фоне. С этого момента всё работает интегрированно в одном окне.
API-сервис для генерации PDF
На предыдущем этапе мы настроили кнопку Экспортировать PDF во фронтенде с атрибутом "href", указывающим на адрес services/klient/eksport-pdf. Однако если нажать на неё сейчас, ничего не произойдёт. Это происходит потому, что API-сервис, отвечающий за генерацию файла, ещё не существует.
Вся разработка API происходит внутри папки 📂 server.
В этом разделе мы создадим скрипт, который извлекает записи из базы данных и визуально строит PDF-документ.
Предварительные требования
- Созданный во фронтенде компонент KnopkaPDF, указывающий на правильный URL.
- Запущенный сервер Netuno.
Netuno автоматически маршрутизирует URL вашего API на основе структуры папок внутри server/services/. Чтобы создать сервис, выполните шаги:
-
Перейдите в папку сервисов бэкенда:
server/services/. Создайте папку klient. -
Внутри этой папки создайте файл
eksport-pdf.js.
Netuno — полиглот. В этом примере мы будем использовать JavaScript; используйте расширение, соответствующее предпочитаемому языку.
Откройте файл и вставьте код ниже, чтобы сгенерировать структуру вашего PDF:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
server/services/klient/eksport-pdf.js
server/services/klient/eksport-pdf.ts
server/services/klient/eksport-pdf.py
server/services/klient/eksport-pdf.rb
server/services/klient/eksport-pdf.kts
server/services/klient/eksport-pdf.groovy
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_header.contentType("pdf")
const pdfDokument = _pdf.newDocument(_pdf.pageSize("A5"))
pdfDokument.add(
_pdf.paragraph("Список клиентов:")
.setFontSize(16)
.setFontColor(_pdf.color("#1abc9c"))
)
const dbKlienty = _db.form("klient").all()
for (const dbKlient of dbKlienty) {
pdfDokument.add(
_pdf.paragraph(dbKlient.getString("imya"))
.setFontSize(12)
.setFontColor(_pdf.color("#748dae"))
)
}
pdfDokument.close()
_header.contentType("pdf")
const pdfDokument = _pdf.newDocument(_pdf.pageSize("A5"))
pdfDokument.add(
_pdf.paragraph("Список клиентов:")
.setFontSize(16)
.setFontColor(_pdf.color("#1abc9c"))
)
const dbKlienty = _db.form("klient").all()
for (const dbKlient of dbKlienty) {
pdfDokument.add(
_pdf.paragraph(dbKlient.getString("imya"))
.setFontSize(12)
.setFontColor(_pdf.color("#748dae"))
)
}
pdfDokument.close()
_header.contentType("pdf")
pdfDokument = _pdf.newDocument(_pdf.pageSize("A5"))
pdfDokument.add(
_pdf.paragraph("Список клиентов:")
.setFontSize(16)
.setFontColor(_pdf.color("#1abc9c"))
)
dbKlienty = _db.form("klient").all()
for dbKlient in dbKlienty:
pdfDokument.add(
_pdf.paragraph(dbKlient.getString("imya"))
.setFontSize(12)
.setFontColor(_pdf.color("#748dae"))
)
pdfDokument.close()
_header.contentType("pdf")
pdfDokument = _pdf.newDocument(_pdf.pageSize("A5"))
pdfDokument.add(
_pdf.paragraph("Список клиентов:")
.setFontSize(16)
.setFontColor(_pdf.color("#1abc9c"))
)
dbKlienty = _db.form("klient").all()
dbKlienty.each do |dbKlient|
pdfDokument.add(
_pdf.paragraph(dbKlient.getString("imya"))
.setFontSize(12)
.setFontColor(_pdf.color("#748dae"))
)
end
pdfDokument.close()
_header.contentType("pdf")
val pdfDokument = _pdf.newDocument(_pdf.pageSize("A5"))
pdfDokument.add(
_pdf.paragraph("Список клиентов:")
.setFontSize(16)
.setFontColor(_pdf.color("#1abc9c"))
)
val dbKlienty = _db.form("klient").all()
dbKlienty.forEach {
pdfDokument.add(
_pdf.paragraph(it.getString("imya"))
.setFontSize(12)
.setFontColor(_pdf.color("#748dae"))
)
}
pdfDokument.close()
_header.contentType("pdf")
def pdfDokument = _pdf.newDocument(_pdf.pageSize("A5"))
pdfDokument.add(
_pdf.paragraph("Список клиентов:")
.setFontSize(16)
.setFontColor(_pdf.color("#1abc9c"))
)
def dbKlienty = _db.form("klient").all()
for (dbKlient in dbKlienty) {
pdfDokument.add(
_pdf.paragraph(dbKlient.getString("imya"))
.setFontSize(12)
.setFontColor(_pdf.color("#748dae"))
)
}
pdfDokument.close()
Разбираем код
-
_header.contentType("pdf"): сообщает браузеру, что ответ на этот запрос — не обычный текст или JSON, а PDF-файл.
-
_pdf: встроенный ресурс Netuno для работы с PDF. С его помощью мы задаём размер страницы (A5), создаём абзацы, настраиваем размеры шрифта (
setFontSize) и цвета (setFontColor). -
_db.form("klient").all(): запрашивает базу данных и возвращает все записи, сохранённые в форме
klient. Цикл (for) проходит по каждому из этих клиентов и извлекает информацию из поляimyaдля вывода в документ. -
pdfDokument.close(): завершает построение документа и отправляет его в качестве ответа.
Проверка и тестирование
Не нужно нажимать кнопку на дашборде каждый раз, когда вы хотите протестировать свой сервис. Поскольку это простой запрос (GET), вы можете проверить выполнение, открыв URL API напрямую в браузере.
Для этого примера откройте следующий адрес: http://localhost:9000/services/klient/eksport-pdf
Если PDF-файл сгенерирован и отображён на экране со списком клиентов, сервис работает идеально! Соответственно, кнопка Экспортировать PDF на вашем дашборде начнёт работать автоматически.
Если страница остаётся пустой или возвращает сообщение об ошибке при доступе к URL, немедленно проверьте терминал, где работает сервер Netuno. В отличие от фронтенда, ошибки которого отображаются в консоли браузера, любой сбой выполнения в скриптах папки server будет подробно показан в терминале backend-сервера.
Заключение
В этом руководстве вы прошли практический путь fullstack-разработки с использованием Netuno.
Основная цель — показать, как платформа объединяет построение визуальных интерфейсов с надёжностью сервера, всегда делая акцент на высокой производительности.
Кратко повторим выполненные этапы:
-
Разработка фронтенда: вы настроили дашборд на React, создав компоненты интерфейса и интерактивные кнопки модульным образом.
-
Управление и структура данных: вы увидели, как быстро создавать формы и поля в панели для регистрации и обработки информации без необходимости писать сложные процедуры сохранения.
-
Прямые запросы: вы использовали инструмент Query для быстрого выполнения SQL-команд и тестирования базы данных.
-
Создание API на бэкенде: вы разработали сервис для генерации PDF и увидели одно из главных преимуществ Netuno — горячую перезагрузку (hot-reload). Вам не нужно перезапускать сервер при каждом изменении кода бэкенда, что значительно ускоряет программирование.
-
Оптимизированная среда: вы настроили интегрированную сборку, объединив процессы фронтенда и бэкенда в одном терминале, чтобы сохранять концентрацию и избегать отвлечений.
Платформа изначально спроектирована для оптимизации и ускорения разработки программного обеспечения. Теперь, когда вы понимаете базовый процесс интеграции между low-code и пользовательским кодом, вы готовы создавать гораздо более сложные и масштабируемые приложения.
Продолжайте изучать следующие разделы документации, чтобы освоить новые возможности.
Разработка становится намного проще, когда вы являетесь частью активного сообщества. Перейдите по ссылкам на социальные сети в нижнем колонтитуле этой страницы.