Page.js — это легковесная клиентская библиотека для маршрутизации в одностраничных приложениях (SPA). Одной из важных задач при разработке сложных приложений является отладка промежуточных состояний, когда пользователь перемещается между маршрутами, но компонентные состояния и данные могут находиться в промежуточном, неполном или неконсистентном состоянии.
Page.js использует функцию page(path, callback) для
регистрации маршрутов. Каждый маршрут получает объект ctx,
который содержит информацию о текущем пути и параметрах:
page('/user/:id', ctx => {
console.log('Параметр id:', ctx.params.id);
renderUser(ctx.params.id);
});
ctx включает следующие ключевые свойства:
ctx.path — текущий путь запроса.ctx.params — параметры маршрута (например,
:id в примере выше).ctx.querystring — строка запроса после
?.ctx.state — объект состояния, который можно передавать
между маршрутами.Использование ctx.state позволяет
сохранять промежуточные данные, например, пользовательский ввод или
состояние формы, между навигациями.
Иногда переход между маршрутами происходит асинхронно, например, при загрузке данных с сервера. Чтобы отладить такие состояния, Page.js предоставляет методы для контроля потока маршрутов:
next()next() используется внутри middleware для передачи
управления следующему обработчику маршрута. Если его забыть вызвать,
дальнейшие обработчики не сработают:
page('/profile', ctx, next => {
console.log('Промежуточное состояние до загрузки данных');
next();
});
Это позволяет вставлять промежуточные точки, где можно:
ctx.state перед рендером
компонента.page.redirect()Для корректного управления промежуточными маршрутами часто используют редиректы:
if (!ctx.state.userLoggedIn) {
page.redirect('/login');
}
В сочетании с ctx.state редирект позволяет безопасно
обрабатывать переходы без потери промежуточного состояния.
Page.js поддерживает цепочки middleware, что делает возможным создание отладочного слоя, который фиксирует все изменения состояния:
function debugMiddleware(ctx, next) {
console.group('Debug Route');
console.log('Path:', ctx.path);
console.log('Params:', ctx.params);
console.log('State before next:', ctx.state);
next();
console.log('State after next:', ctx.state);
console.groupEnd();
}
page('*', debugMiddleware);
ctx.state до вызова next() — текущее
состояние перед обработкой маршрута.ctx.state после next() — состояние после
всех обработчиков маршрута.console.group позволяют структурировать вывод
для удобного анализа сложных переходов.Для SPA с асинхронной загрузкой данных важно фиксировать момент начала и окончания загрузки:
page('/dashboard', async ctx => {
ctx.state.loading = true;
renderLoading();
try {
const data = await fetchDashboardData();
ctx.state.data = data;
renderDashboard(data);
} catch (error) {
ctx.state.error = error;
renderError(error);
} finally {
ctx.state.loading = false;
}
});
ctx.state.loading позволяет отследить состояние
загрузки.ctx.state.data сохраняются промежуточные
результаты.ctx.state.error для
последующей отладки.Для сложных SPA удобно визуализировать переходы и промежуточные состояния:
debugMiddleware.window.__ROUTE_STATE__ = ctx.state, чтобы отслеживать
текущее состояние в консоли браузера.const routeHistory = [];
page('*', ctx => {
routeHistory.push({ path: ctx.path, state: { ...ctx.state } });
});
Особенно важен дебаг при динамических маршрутах с параметрами:
page('/post/:postId/comment/:commentId', ctx => {
console.log('Текущий пост:', ctx.params.postId);
console.log('Текущий комментарий:', ctx.params.commentId);
});
ctx.params помогает отслеживать, какой именно элемент
данных загружается.ctx.state позволяет хранить промежуточные результаты,
например, текст комментария перед сохранением.ctx.state напрямую без
необходимости — для отладки полезно видеть «чистое»
состояние.Page.js предоставляет минимальный, но мощный инструмент для контроля
состояния маршрутов. Корректное использование ctx.state,
next(), middleware и редиректов позволяет точно
отслеживать промежуточные состояния и предотвращать неконсистентность
данных в одностраничных приложениях.