Как создать сайт без PHP: Node.js, JAMstack, Python и другие варианты
Выбор технологии для сайта без PHP
Node.js с Express.js и шаблонизатором EJS
Как создать полнофункциональный динамический сайт без PHP на основе JavaScript?
Node.js позволяет использовать JavaScript на сервере, что упрощает разработку для фронтенд-разработчиков. Связка Express.js и шаблонизатора EJS даёт возможность генерировать HTML на сервере, обрабатывать формы и работать с базами данных.
Пример базового сервера
const express = require('express');
const app = express();
const port = 3000;
app.set('view engine', 'ejs');
app.get('/', (req, res) => {
res.render('index', { title: 'Главная', message: 'Привет, мир без PHP!' });
});
app.listen(port, () => {
console.log(`Сервер запущен на http://localhost:${port}`);
});
Пояснение: Устанавливаем Express, настраиваем EJS как шаблонизатор. Маршрут '/' отдаёт страницу index.ejs с переменными. Для запуска требуется npm init и установка зависимостей.
Шаблон EJS (views/index.ejs)
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= message %></h1>
<p>Страница создана без использования PHP.</p>
</body>
</html>
Возможные проблемы и решения
Проблема: Ошибка при запуске require is not defined если не использовать CommonJS или не настроить package.json.
Решение: Убедитесь, что файл package.json содержит "type": "commonjs" или используйте синтаксис ES Modules с флагом --experimental-modules.
Проблема: Шаблоны не обновляются после изменений.
Решение: Установите nodemon для автоматического перезапуска сервера при изменениях.
Цели и случаи использования: Node.js подходит для создания REST API, блогов, интернет-магазинов и любых сайтов, где требуется серверная логика.
Статический сайт с JavaScript и облачной базой данных (Firebase)
Как сделать динамический сайт без серверного кода на PHP, используя только клиентский JavaScript?
С помощью Firebase Firestore можно организовать чтение и запись данных прямо из браузера. Это подходит для одностраничных приложений и прототипов.
Пример чтения данных
import { initializeApp } from "firebase/app";
import { getFirestore, collection, getDocs } from "firebase/firestore";
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
// остальные настройки
};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
async function getPosts() {
const querySnapshot = await getDocs(collection(db, "posts"));
querySnapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
});
}
getPosts();
Пояснение: Подключаем Firebase, получаем данные из коллекции posts. Все запросы выполняются на стороне клиента.
Проблема: Данные видны в коде страницы, правила безопасности Firebase должны быть настроены строго.
Решение: Используйте Firebase Security Rules для ограничения доступа.
Проблема: SEO для динамического контента затруднено.
Решение: Используйте SSR (серверный рендеринг) или предварительный рендеринг через Netlify/Webs.
Статический генератор Hugo с формами через Netlify Forms
Как создать блог или сайт-визитку с контактной формой без PHP и без серверной обработки?
Hugo генерирует HTML из Markdown. Интерактивные формы обрабатываются бесплатным сервисом Netlify Forms.
Пример формы в HTML
<form name="contact" netlify>
<p>
<label>Имя: <input type="text" name="name" /></label>
</p>
<p>
<label>Email: <input type="email" name="email" /></label>
</p>
<p>
<button type="submit">Отправить</button>
</p>
</form>
Пояснение: Атрибут netlify автоматически включает обработку на стороне Netlify. Результаты приходят на указанную почту.
Проблема: Netlify Forms не подходят для сложной валидации.
Решение: Добавьте клиентскую валидацию на JavaScript или используйте Zapier для дополнительной обработки.
Python Flask вместо PHP
Как использовать Python для веб-разработки, если не хотите PHP?
Flask - легковесный микрофреймворк, идеален для небольших проектов и API.
Пример минимального приложения Flask
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html', message='Привет от Flask!')
if __name__ == '__main__':
app.run(debug=True)
Пояснение: Установка Flask через pip, шаблоны Jinja2. Аналог PHP-фреймворков.
Проблема: Производительность Flask ниже, чем у асинхронных фреймворков.
Решение: Для продакшена используйте Gunicorn + Nginx.
Бессерверные функции (Netlify Functions)
Как обрабатывать запросы без выделенного сервера, используя только статический хостинг?
Netlify Functions позволяют запускать серверный код (Node.js) без управления инфраструктурой.
Пример функции для отправки email
exports.handler = async (event) => {
const { name, email } = JSON.parse(event.body);
// логика отправки
return {
statusCode: 200,
body: JSON.stringify({ message: `Спасибо, ${name}!` })
};
};
Пояснение: Функция размещается в папке netlify/functions. Вызывается через POST запрос.
Проблема: Ограничение по времени выполнения (10 секунд).
Решение: Разбивайте длительные задачи на несколько вызовов.
Расширенные примеры и команды
Полный проект на Node.js с Express и MongoDB
Создайте папку проекта, выполните npm init -y и установите пакеты: npm i express mongoose ejs dotenv.
Пример подключения к MongoDB и отображения списка записей:
// app.js
const express = require('express');
const mongoose = require('mongoose');
const app = express();
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true });
const itemSchema = new mongoose.Schema({ name: String });
const Item = mongoose.model('Item', itemSchema);
app.get('/', async (req, res) => {
const items = await Item.find();
res.render('index', { items });
});
app.listen(3000);
Результат: на главной странице отобразятся все элементы из коллекции items.
Деплой статического сайта с Hugo на Netlify
Установите Hugo, создайте новый сайт: hugo new site mysite. Добавьте тему: git submodule add ... themes/ananke. Настройте конфиг. Запустите локально: hugo server. Для деплоя на Netlify подключите репозиторий GitHub и укажите команду сборки hugo и папку public.
API на Flask для мобильного приложения
Пример REST API для списка задач:
from flask import Flask, jsonify, request
app = Flask(__name__)
tasks = []
@app.route('/tasks', methods=['GET'])
def get_tasks():
return jsonify(tasks)
@app.route('/tasks', methods=['POST'])
def add_task():
data = request.get_json()
tasks.append(data)
return jsonify(data), 201
if __name__ == '__main__':
app.run()
Тестирование через curl:
curl http://localhost:5000/tasks -X POST -H "Content-Type: application/json" -d '{"title":"купить молоко"}'
Ответ: 201 Created
Бессерверная обработка изображений с Sharp и Netlify Functions
Функция изменяет размер загруженного изображения:
const sharp = require('sharp');
exports.handler = async (event) => {
const imageBuffer = Buffer.from(event.body, 'base64');
const resized = await sharp(imageBuffer).resize(200, 200).toBuffer();
return {
statusCode: 200,
headers: { 'Content-Type': 'image/jpeg' },
body: resized.toString('base64'),
isBase64Encoded: true
};
};
Вызов функции с передачей base64 изображения вернёт уменьшенную копию.