Приклад програми
Після теорії давайте застосуємо отримані дані на практиці і створимо простий додаток на express.
Фреймворк Express представляє свій генератор додатків
https://expressjs.com/en/starter/generator.html.
Генератор орієнтується на MVC
архітектуру додатків і має таку
структуру каталогів
├── app.js
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── users.js
└── views
├── error.pug
├── index.pug
└── layout.pug
Установку можна зробити наступною командою
npx express-generator --view=ejs simple-express
npx
- утиліта, яка вже є у вас у системі якщо ви встановили Node.js
версії вище 8.x
, вона дозволяє виконувати команди інших утиліт не встановлюючи
їх глобально у системі. Далі ми вказуємо, що хочемо використати шаблон ejs
параметром --view=ejs
та останнім параметром вказуємо ім'я програми
simple-express
Програма знаходиться у файлі app.js
, перше, що ми маємо зробити це
змінити var
на const
у всьому додатку. Після цього файл app.js повинен
виглядати так:
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Спочатку підключено всі сторонні пакети, які потрібні для функціонування програми. Після ми підключаємо роути, надалі ми їх змінимо та внесемо додатковий функціонал.
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
Після створюється екземпляр програми та підключаємо шаблони
const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
Після цього йде блок підключення проміжного ПЗ
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
Підключається логер, обробка JSON
і даних форм, і в кінці модуль для
роботи з cookie
.
Далі встановлюємо обробку статичних ресурсів
app.use(express.static(path.join(__dirname, 'public')));
Після йде підключення роутерів до програми
app.use('/', indexRouter);
app.use('/users', usersRouter);
Пам'ятайте, що порядок проміжного ПЗ має значення. В кінці
програми йде обробка помилок. Спочатку відбувається обробка неіснуючого
роуту чи помилка 404
app.use(function (req, res, next) {
next(createError(404));
});
По суті відсутність обробника на роутер, що запитується у сервера, це не помилка і ми створюємо помилку та прокидаємо її далі для обробки.
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
Тут і відбувається обробка помилки. Ми прокидаємо змінні message
та
error
у шаблон error.ejs
і виконуємо його рендер
Усередині папки з нашим додатком необхідно встановити пакети
npm i
Тепер для режиму розробки ми встановимо пакет nodemon
. Він дозволяє
виконувати live reload сервера під час розробки. Додамо необхідну залежність
npm i nodemon -D
Після у файлі package.json
для запуску програми в режимі розробки додамо
скрипт start:dev
"scripts": {
"start": "node ./bin/www",
"start:dev": "nodemon ./bin/www"
},
І запуск програми в режимі розробки буде наступним
npm run start:dev
Після запуску, програма виглядатиме так:
Програма виконує рендер одного шаблону. Сам рендер виконується у файлі
роутингу routes/index.js
router.get('/', (req, res, next) => {
res.render('index', { title: 'Express' });
});
Настав час змінити нашу програму - додамо форму, щоб ми могли прийняти
дані. Файл index.ejs
має виглядати так:
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel="stylesheet" href="/stylesheets/style.css" />
</head>
<body>
<form action="/login" method="POST">
<label for="email">Email</label>
<input type="text" name="email" id="email" />
<label for="password">Пароль</label>
<input type="password" name="password" id="password" />
<button type="submit">Відправити</button>
</form>
</body>
</html>
Для кращого сприйняття додамо наступні стилі у файл
public/stylesheets/style.css
form {
display: flex;
flex-direction: column;
width: 400px;
}
input,
button {
margin-bottom: 15px;
}
Нам потрібний обробник для шляху /login
на який приходитимуть дані від
форми. Давайте додамо його. Але спочатку давайте додамо новий шаблон
response.ejs
куди ми виводитимемо дані форми.
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<p>Email: <%= email %></p>
<p>Password: <%= password %></p>
<a href='/'>Повернутися на головну</a>
</body>
</html>
Тепер у файл роутингу додамо обробник маршруту
router.post('/login', (req, res, next) => {
const { email, password } = req.body;
res.render('response', { title: 'Simple express app', email, password });
});
Він досить спрощений, ми приймаємо дві змінні та передаємо їх для рендеру
шаблону response.ejs
, щоб показати, що дані отримано. Якщо все зроблено
правильно то при відправленні форми ми будемо просто бачити, що ми відправили на
сервер
Цей приклад показує передачу даних від фронтенд частини використовуючи форми.
Тепер у файл роутингу user.js
додамо наступний об'єкт з контактами та
виглядати він має так:
const express = require('express');
const router = express.Router();
const contacts = [
{ id: '1', username: 'Felix', surname: 'Brown', email: 'felix@test.com' },
{ id: '2', username: 'Sonya', surname: 'Redhead', email: 'sonya@test.com' },
{ id: '3', username: 'Conan', surname: 'Barbarian', email: 'conan@test.com' },
];
/* GET users listing. */
router.get('/', function (req, res, next) {
res.json(contacts);
});
module.exports = router;
І якщо ми звернемося за маршрутом
/users сервер надішле нам
JSON
Для гарного виводу JSON
у браузері можна використовувати наступну програму:
https://github.com/callumlocke/json-formatter
у нього також є розширення для Chrome. Встановіть його і ви завжди будете
бачити JSON
дані у читаному вигляді.
Давайте додамо обробник для отримання унікального користувача за його ідентифікатором
router.get('/:id', function (req, res, next) {
const { id } = req.params;
const contact = contacts.filter(el => el.id === id);
res.json(contact);
});
Тепер за зверненням до урлу /users/2 ми отримуємо дані Рудої Соні
[
{
"id": "2",
"username": "Sonya",
"surname": "Redhead",
"email": "sonya@test.com"
}
]
Такий підхід передачі даних ми використовуватимемо найчастіше для редагування та видалення конкретної сутності за її унікальним ідентифікатором.
З повним кодом вказаного прикладу можна ознайомитись тут:
А ми підемо далі і розглянемо більш просунуті теми.