Для начала работы с TanStack Router в проекте на Webpack необходимо установить саму библиотеку и ее типы (если используется TypeScript):
npm install @tanstack/router
npm install -D @types/react
В случае использования TypeScript важно убедиться, что
tsconfig.json корректно настроен для поддержки JSX и
модулей ESNext:
{
"compilerOptions": {
"target": "ES6",
"module": "ESNext",
"moduleResolution": "node",
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
Основная задача — убедиться, что Webpack корректно обрабатывает
современные ES-модули и JSX. Пример минимальной конфигурации
webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
clean: true,
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript'
]
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
devtool: 'source-map',
devServer: {
static: path.join(__dirname, 'dist'),
port: 3000,
hot: true,
historyApiFallback: true
}
};
Ключевые моменты конфигурации:
resolve.extensions — позволяет Webpack автоматически
определять расширения файлов, что упрощает импорт компонентов.babel-loader с пресетами
@babel/preset-react и @babel/preset-typescript
обеспечивает корректную транспиляцию JSX и TypeScript.devServer.historyApiFallback: true критично для SPA с
TanStack Router, чтобы все маршруты обрабатывались на клиенте, а не
приводили к 404 при обновлении страницы.Создается основной маршрутизатор с определением корневого маршрута:
import { createRouter, createRouteConfig } from '@tanstack/router';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
const rootRoute = createRouteConfig()
.route('/', {
component: App,
children: [
{
path: '/',
component: HomePage,
},
{
path: '/about',
component: AboutPage,
},
],
});
const router = createRouter({
routeConfig: rootRoute,
});
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<React.StrictMode>
{router.render()}
</React.StrictMode>
);
Особенности:
createRouteConfig позволяет задавать вложенные маршруты
с компонентами.router.render() интегрирует маршрутизатор с React,
автоматически обрабатывая переходы между страницами.Для ускоренной разработки важно включить HMR, чтобы изменения в
компонентах маршрутов автоматически применялись без перезагрузки
страницы. В webpack.config.js уже включен параметр
hot: true, но для корректной работы с TanStack Router
требуется убедиться, что корневой компонент не теряет состояния при
обновлении:
if (module.hot) {
module.hot.accept('./App', () => {
const NextApp = require('./App').default;
root.render(
<React.StrictMode>
{router.render()}
</React.StrictMode>
);
});
}
Для production рекомендуется использовать код-сплиттинг для маршрутов:
import React, { lazy, Suspense } from 'react';
const HomePage = lazy(() => import('./pages/HomePage'));
const AboutPage = lazy(() => import('./pages/AboutPage'));
const rootRoute = createRouteConfig()
.route('/', {
component: App,
children: [
{ path: '/', component: () => <Suspense fallback={<div>Loading...</div>}><HomePage /></Suspense> },
{ path: '/about', component: () => <Suspense fallback={<div>Loading...</div>}><AboutPage /></Suspense> },
],
});
Преимущества:
Suspense позволяет отображать индикатор
загрузки до подгрузки компонентов.Для упрощения импортов компонентов и маршрутов в Webpack можно использовать alias:
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@pages': path.resolve(__dirname, 'src/pages'),
'@components': path.resolve(__dirname, 'src/components')
}
}
Это позволяет писать:
import HomePage from '@pages/HomePage';
import Header from '@components/Header';
вместо длинных относительных путей. TanStack Router отлично работает с такими alias, так как маршруты импортируются как обычные модули ES.
TanStack Router имеет встроенную поддержку типов, что позволяет безопасно работать с параметрами маршрутов:
const userRoute = rootRoute.addRoute({
path: '/user/:id',
component: UserPage,
});
type UserParams = typeof userRoute['__types']['params'];
function navigateToUser(id: UserParams['id']) {
router.navigate(`/user/${id}`);
}
Преимущества типизации: