Solid.js — это современный фреймворк для создания быстрых и реактивных пользовательских интерфейсов на JavaScript. Его ключевая особенность — высокая производительность, основанная на использовании детерминированных реактивных систем и минимизации перерасчёта DOM. Однако Solid.js можно использовать не только для создания клиентской логики, но и в качестве основы для полноценного full-stack приложения.
Full-stack разработка предполагает создание как клиентской, так и серверной части приложения. Для этого традиционно используется связка таких технологий, как фронтенд-фреймворки и серверные библиотеки или фреймворки для работы с базами данных, а также взаимодействие с API.
В контексте Solid.js клиентская часть может быть связана с сервером через различные механизмы: REST API, GraphQL, WebSocket или серверные рендеринги. С помощью Solid.js можно создать высокопроизводительные интерфейсы, а серверная часть может быть построена на популярных технологиях, таких как Node.js, Express, или Deno.
Создание full-stack приложения на Solid.js начинается с разработки клиентской части и настройки серверной.
Solid.js использует модель реактивности, схожую с реактивными фреймворками, такими как Vue или Svelte, но с отличием в том, как происходит обновление UI. В Solid.js изменения данных напрямую влияют на DOM, что минимизирует перерасчёты и обеспечивает невероятную скорость рендеринга.
На клиенте можно создавать компоненты, которые используют реактивные
примитивы, такие как createSignal,
createEffect, и createMemo. Эти примитивы
позволяют управлять состоянием и побочными эффектами.
import { createSignal, createEffect } from "solid-js";
function Counter() {
const [count, setCount] = createSignal(0);
createEffect(() => {
console.log(`Counter is now: ${count()}`);
});
return (
<div>
<p>{count()}</p>
<button onCl ick={() => setCount(count() + 1)}>Increment</button>
</div>
);
}
В этом примере createSignal создаёт реактивное состояние
count, а createEffect автоматически выполняет
побочный эффект при изменении этого состояния. Это позволяет создавать
динамичные и отзывчивые компоненты без дополнительных сложностей.
Для создания серверной части можно использовать Node.js с Express, который позволяет легко обрабатывать HTTP-запросы и работать с базами данных.
Пример простого API-сервера, который отдаёт данные для фронтенда:
import express from 'express';
const app = express();
const port = 3000;
app.get('/api/data', (req, res) => {
res.json({ message: 'Hello from server' });
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Этот сервер отправляет простой JSON-ответ на GET-запросы по пути
/api/data. Взаимодействие с таким сервером можно
организовать на клиентской части, используя стандартные механизмы
HTTP-запросов, такие как fetch.
Интеграция клиента на Solid.js с сервером может быть выполнена с помощью API-запросов. Рассмотрим пример компонента, который запрашивает данные с сервера и отображает их на странице.
import { createSignal, createEffect } from "solid-js";
function DataFetcher() {
const [data, setData] = createSignal(null);
createEffect(async () => {
const response = await fetch("/api/data");
const json = await response.json();
setData(json.message);
});
return <div>{data() ? data() : "Loading..."}</div>;
}
В этом примере создаётся сигнал для хранения данных
(data), и createEffect выполняет запрос к
серверу при монтировании компонента. После получения данных они
устанавливаются в состояние и отображаются на экране.
Для создания full-stack приложений, в которых Solid.js используется не только на клиенте, но и на сервере, можно задействовать серверный рендеринг. Этот подход позволяет предварительно генерировать HTML на сервере, что ускоряет загрузку страницы и улучшает SEO.
Использование серверного рендеринга в Solid.js можно организовать с
помощью библиотеки solid-start, которая предоставляет
механизмы для создания универсальных приложений.
Пример серверного рендеринга с использованием Solid.js:
import { renderToString } from 'solid-js/web';
import { createServer } from 'http';
const server = createServer((req, res) => {
if (req.url === '/') {
const app = renderToString(() => <App />);
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`<html><body>${app}</body></html>`);
}
});
server.listen(3000, () => {
console.log('Server is running at http://localhost:3000');
});
Здесь используется метод renderToString для рендеринга
компонента App в строку HTML, которая затем отправляется
клиенту. Это позволяет серверу генерировать полный HTML-код страницы и
отправлять его клиенту, где он будет сразу отображён.
Для полноценного full-stack приложения важно иметь возможность работать с данными. Один из популярных подходов — использование базы данных, например, MongoDB или PostgreSQL.
Для работы с базами данных можно использовать ORM (например, TypeORM
для SQL-баз данных) или стандартные библиотеки для работы с MongoDB
(например, mongodb).
Пример использования MongoDB на серверной части:
import express from 'express';
import { MongoClient } from 'mongodb';
const app = express();
const port = 3000;
const client = new MongoClient('mongodb://localhost:27017');
let db;
client.connect().then(() => {
db = client.db('mydb');
});
app.get('/api/users', async (req, res) => {
const users = await db.collection('users').find().toArray();
res.json(users);
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Этот сервер получает список пользователей из MongoDB и отправляет их в виде JSON на клиентскую сторону.
Объединив все элементы, можно создать полноценное full-stack приложение с клиентской частью на Solid.js и сервером на Express, который взаимодействует с базой данных.
Пример реализации:
Сервер:
import express from 'express';
import { MongoClient } from 'mongodb';
const app = express();
const port = 3000;
const client = new MongoClient('mongodb://localhost:27017');
let db;
client.connect().then(() => {
db = client.db('mydb');
});
app.get('/api/users', async (req, res) => {
const users = await db.collection('users').find().toArray();
res.json(users);
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Клиент:
import { createSignal, createEffect } from 'solid-js';
function UserList() {
const [users, setUsers] = createSignal([]);
createEffect(async () => {
const response = await fetch('/api/users');
const data = await response.json();
setUsers(data);
});
return (
<ul>
{users().map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
Такое приложение представляет собой минимальный, но полноценный full-stack проект с интеграцией клиентской и серверной логики, а также с хранением данных в базе данных.
Solid.js предоставляет мощные инструменты для создания высокопроизводительных клиентских приложений, которые легко интегрируются с серверной частью. С помощью серверного рендеринга, работы с базами данных и построения API можно создавать полностью функциональные full-stack приложения, которые имеют все необходимые элементы для современных веб-сервисов: быстрый интерфейс, серверную логику и хранение данных.