npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

w2b-vite-filebased-routing

v1.1.0

Published

🚀 Простой и мощный плагин для Vite с file-based routing

Readme

Vite File-Based Router

🚀 Простой и мощный плагин для Vite с file-based routing

Этот плагин предоставляет систему file-based routing для Vite приложений, вдохновленную Next.js. Он поддерживает страницы, лейауты, динамические маршруты, HMR, SEO оптимизацию и TypeScript.

✨ Особенности

  • 🗂️ File-based routing - автоматическое создание маршрутов на основе файловой структуры
  • 🏗️ Layout система - поддержка вложенных лейаутов
  • 🔄 Hot Module Replacement - мгновенное обновление при изменении файлов
  • 🎯 Динамические маршруты - поддержка [id].tsx, [...slug].tsx
  • Production оптимизация - code splitting, manifest генерация
  • 🔧 TypeScript поддержка - полная типизация и автогенерация типов
  • 📱 SEO оптимизация - автоматическая генерация метаданных, sitemap, robots.txt
  • 🎨 JSX/TSX поддержка - работает с React компонентами

📦 Установка

npm install w2b-vite-filebased-routing
# или
pnpm add w2b-vite-filebased-routing
# или
yarn add w2b-vite-filebased-routing

🚀 Быстрый старт

1. Настройка Vite

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { w2bViteFileBasedRouting } from 'w2b-vite-filebased-routing/core'

export default defineConfig({
	plugins: [react(), w2bViteFileBasedRouting()],
})

2. Создание структуры файлов

src/
├── pages/
│   ├── page.tsx           # / (главная страница)
│   ├── about/
│   │   └── page.tsx       # /about
│   ├── blog/
│   │   ├── page.tsx       # /blog
│   │   ├── [id]/
│   │   │   └── page.tsx   # /blog/[id]
│   │   └── [...slug]/
│   │       └── page.tsx   # /blog/[...slug]
│   ├── layout.tsx         # Root layout
│   └── (auth)/
│       ├── layout.tsx     # Auth layout
│       └── login/
│           └── page.tsx   # /login

3. Создание страниц

// src/pages/page.tsx
/**
 * @title Главная страница
 * @description Добро пожаловать на наш сайт
 * @keywords главная, добро пожаловать, сайт
 * @changefreq daily
 * @priority 1.0
 */
export default function HomePage() {
	return (
		<div>
			<h1>Добро пожаловать!</h1>
			<p>Это главная страница</p>
		</div>
	)
}

// Или через экспорт метаданных
export const metadata = {
	title: 'Главная страница',
	description: 'Добро пожаловать на наш сайт',
	keywords: ['главная', 'добро пожаловать', 'сайт'],
	changefreq: 'daily' as const,
	priority: 1.0,
}

4. Создание лейаутов

// src/pages/layout.tsx
interface LayoutProps {
	children: React.ReactNode
}

export default function RootLayout({ children }: LayoutProps) {
	return (
		<div>
			<header>
				<nav>
					<a href='/'>Главная</a>
					<a href='/about'>О нас</a>
				</nav>
			</header>
			<main>{children}</main>
			<footer>
				<p>&copy; 2025 Мой сайт</p>
			</footer>
		</div>
	)
}

5. Динамические маршруты

// src/pages/blog/[id]/page.tsx
import { useParams } from 'react-router-dom'

export default function BlogPost() {
	const { id } = useParams<{ id: string }>()

	return (
		<div>
			<h1>Пост блога #{id}</h1>
			<p>Содержимое поста...</p>
		</div>
	)
}

// Catch-all маршрут
// src/pages/docs/[...slug]/page.tsx
export default function DocsPage() {
	const { slug } = useParams<{ slug: string[] }>()

	return (
		<div>
			<h1>Документация: {slug?.join('/')}</h1>
		</div>
	)
}

6. Подключение роутера в приложение

// src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { RouterProvider } from 'w2b-vite-filebased-routing/react'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
	<React.StrictMode>
		<RouterProvider />
	</React.StrictMode>
)

⚙️ Конфигурация

import { w2bViteFileBasedRouting } from 'w2b-vite-filebased-routing/core'

export default defineConfig({
	plugins: [
		w2bViteFileBasedRouting({
			// 📁 Директория со страницами
			pagesDir: 'src/pages',

			// 📄 Имя файла страницы
			pageFileName: 'page',

			// 🏗️ Имя файла лейаута
			layoutFileName: 'layout',

			// 🎯 Расширения файлов для обработки
			extensions: ['tsx', 'jsx'],

			// 🌐 Базовый URL для SEO
			baseUrl: 'https://example.com',

			// 📍 Базовый путь для маршрутизации
			// Используется для работы нескольких фронтендов на одном домене
			basePath: '/', // '/' для основного сайта, '/admin' для админки

			// 🚫 Пути для исключения из sitemap
			disallowPaths: ['/admin', '/api', '/_internal'],

			// 🔧 Генерировать TypeScript типы
			generateTypes: true,

			// 📱 Включить SEO оптимизацию
			enableSEO: true,
		}),
	],
})

🎯 Использование RouterProvider

import { RouterProvider } from 'w2b-vite-filebased-routing/react'

function App() {
	return (
		<RouterProvider preloader={<div>Загрузка...</div>}>
			{/* Ваш контент */}
		</RouterProvider>
	)
}

Переопределение basePath через пропсы

Вы можете переопределить basePath из конфигурации через пропсы:

import { RouterProvider } from 'w2b-vite-filebased-routing/react'

function App() {
	return (
		<RouterProvider basePath='/admin'>
			{/* Админка будет работать на /admin/* */}
		</RouterProvider>
	)
}

🌐 Работа нескольких фронтендов на одном домене

Плагин поддерживает работу нескольких фронтендов на одном домене с разными базовыми путями. Это полезно, когда у вас есть:

  • Основной сайт на /
  • Админка на /admin/
  • Другое приложение на /app/

Пример настройки для основного сайта

// vite.config.ts (основной сайт)
import { w2bViteFileBasedRouting } from 'w2b-vite-filebased-routing'

export default defineConfig({
	plugins: [
		w2bViteFileBasedRouting({
			pagesDir: 'src/pages',
			basePath: '/', // Основной сайт
		}),
	],
})

Структура файлов:

src/pages/
├── page.tsx          # https://domain.com/
├── about/
│   └── page.tsx     # https://domain.com/about
└── map/
    └── page.tsx      # https://domain.com/map

Пример настройки для админки

// vite.config.ts (админка)
import { w2bViteFileBasedRouting } from 'w2b-vite-filebased-routing'

export default defineConfig({
	plugins: [
		w2bViteFileBasedRouting({
			pagesDir: 'src/admin/pages',
			basePath: '/admin', // Админка на /admin/*
		}),
	],
})

Структура файлов:

src/admin/pages/
├── page.tsx          # https://domain.com/admin/
├── users/
│   └── page.tsx      # https://domain.com/admin/users
└── map/
    └── page.tsx      # https://domain.com/admin/map

Использование в приложении

// src/main.tsx (основной сайт)
import { RouterProvider } from 'w2b-vite-filebased-routing/react'

ReactDOM.createRoot(document.getElementById('root')!).render(
	<React.StrictMode>
		<RouterProvider />
	</React.StrictMode>
)
// src/admin/main.tsx (админка)
import { RouterProvider } from 'w2b-vite-filebased-routing/react'

ReactDOM.createRoot(document.getElementById('admin-root')!).render(
	<React.StrictMode>
		<RouterProvider basePath='/admin' />
	</React.StrictMode>
)

Важные замечания

  1. Разные директории страниц - каждый фронтенд должен иметь свою директорию pagesDir
  2. Разные точки входа - создайте отдельные main.tsx файлы для каждого фронтенда
  3. Настройка Vite base - если используете Vite base опцию, убедитесь, что она совместима с basePath
  4. Навигация - используйте относительные пути или учитывайте basePath при навигации

🔄 HMR (Hot Module Replacement)

Плагин автоматически поддерживает HMR:

  • ✅ Изменение страниц
  • ✅ Изменение лейаутов
  • ✅ Добавление новых маршрутов
  • ✅ Удаление маршрутов
  • ✅ Обновление виртуального модуля

⚡ Production оптимизация

Code Splitting (Разделение кода на чанки)

Плагин автоматически разделяет код на отдельные чанки для каждого маршрута и лейаута. Это означает:

  • Каждая страница загружается отдельно - код страницы загружается только при переходе на соответствующий маршрут
  • Лейауты загружаются независимо - каждый layout загружается как отдельный чанк
  • Оптимизация размера бандла - пользователь загружает только необходимый код
  • Автоматическая ленивая загрузка - используется React.lazy() и динамические импорты import()

Как это работает:

  1. Динамические импорты - каждый маршрут генерируется с динамическим импортом:

    loader: () => import('./pages/about/page.tsx')
  2. React.lazy() - компоненты оборачиваются в React.lazy() для ленивой загрузки:

    const Page = React.lazy(async () => {
    	const module = await loader()
    	return module
    })
  3. React.Suspense - используется для отображения fallback во время загрузки:

    <React.Suspense fallback={<div>Loading...</div>}>
    	<Routes>{renderManifestAsRoutes(manifest)}</Routes>
    </React.Suspense>
  4. Vite автоматически создает чанки - при сборке Vite создает отдельные файлы для каждого динамического импорта:

    dist/
    ├── assets/
    │   ├── index-[hash].js        # Основной бандл
    │   ├── about-[hash].js        # Чанк для /about
    │   ├── blog-[hash].js         # Чанк для /blog
    │   └── blog-id-[hash].js      # Чанк для /blog/[id]

Автоматические оптимизации

  • Code splitting - автоматическое разделение кода по маршрутам
  • Route manifest - манифест маршрутов для отладки
  • TypeScript типы - автогенерация типов маршрутов

Генерируемые файлы

dist/
├── routes-manifest.js    # Манифест маршрутов (для отладки)
├── sitemap.xml           # Карта сайта
├── robots.txt            # Robots.txt
└── types/
    ├── routes.d.ts       # TypeScript типы маршрутов
    └── metadata.d.ts     # TypeScript типы метаданных

📱 SEO оптимизация

Автоматическая генерация метаданных

Плагин автоматически извлекает метаданные из:

  1. JSDoc комментариев:
/**
 * @title О нашей компании
 * @description Узнайте больше о нашей компании
 * @keywords компания, о нас, история
 * @author Команда разработки
 * @changefreq monthly
 * @priority 0.8
 */
export default function AboutPage() {
	return <h1>О нас</h1>
}
  1. Экспорта метаданных:
export const metadata = {
	title: 'О нас',
	description: 'Узнайте больше о нашей компании',
	keywords: ['компания', 'о нас', 'история'],
	changefreq: 'monthly',
	priority: 0.8,
}

Генерируемые SEO файлы

  • sitemap.xml - карта сайта для поисковых систем
  • robots.txt - инструкции для поисковых роботов
  • Метаданные - автоматическое извлечение из страниц

🔧 TypeScript поддержка

Автогенерация типов

Плагин автоматически генерирует TypeScript типы:

// dist/types/routes.d.ts
export type RoutePath =
	| '/'
	| '/about'
	| '/blog'
	| '/blog/[id]'
	| '/docs/[...slug]'

export type RouteParams = {
	'/blog/[id]': { id: string }
	'/docs/[...slug]': { slug: string[] }
}

export type PageProps<T extends RoutePath = RoutePath> = {
	params: RouteParams[T]
	searchParams?: Record<string, string>
}

// Утилиты для навигации
export function navigate<T extends RoutePath>(
	path: T,
	params?: RouteParams[T]
): void

export function useParams<T extends RoutePath>(): RouteParams[T]

Типы метаданных

// dist/types/metadata.d.ts
export interface PageMetadata {
	title?: string
	description?: string
	keywords?: string[]
	author?: string
	changefreq?:
		| 'always'
		| 'hourly'
		| 'daily'
		| 'weekly'
		| 'monthly'
		| 'yearly'
		| 'never'
	priority?: number
}

🧪 Тестирование функций

Проверка работы плагина

  1. Запуск dev сервера:

    npm run dev
  2. Проверка маршрутов:

    • Откройте браузер
    • Перейдите по маршрутам
    • Проверьте, что страницы загружаются
  3. Проверка HMR:

    • Измените файл страницы
    • Убедитесь, что изменения отображаются без перезагрузки

Проверка production сборки

  1. Сборка проекта:

    npm run build
  2. Проверка генерируемых файлов:

    ls dist/
    # Должны быть: routes-manifest.js, sitemap.xml, robots.txt
  3. Запуск preview:

    npm run preview
  4. Проверка маршрутов в production:

    • Откройте браузер
    • Перейдите по маршрутам
    • Убедитесь, что все работает

Проверка SEO файлов

  1. Проверка sitemap.xml:

    cat dist/sitemap.xml
  2. Проверка robots.txt:

    cat dist/robots.txt
  3. Проверка в браузере:

    • Откройте http://localhost:4173/sitemap.xml
    • Откройте http://localhost:4173/robots.txt

Проверка TypeScript типов

  1. Проверка сгенерированных типов:

    ls dist/types/
    # Должны быть: routes.d.ts, metadata.d.ts
  2. Проверка в IDE:

    • Откройте файл с импортом типов
    • Убедитесь, что автодополнение работает

🐛 Решение проблем

Маршруты не создаются

  • Проверьте pagesDir в конфигурации
  • Убедитесь, что файлы имеют правильные расширения
  • Проверьте консоль на ошибки

HMR не работает

  • Убедитесь, что файлы находятся в pagesDir
  • Проверьте, что файлы имеют поддерживаемые расширения
  • Перезапустите dev сервер

TypeScript ошибки

  • Установите типы: npm install @types/react @types/react-dom
  • Проверьте tsconfig.json
  • Убедитесь, что импортируете типы правильно

📊 Производительность

Оптимизации

  • Ленивая загрузка компонентов - компоненты загружаются только при необходимости
  • Code splitting по маршрутам - автоматическое разделение кода по маршрутам
  • Кэширование парсинга файлов - ускорение повторного сканирования
  • Виртуальные модули - быстрая загрузка манифеста маршрутов
  • HMR оптимизация - мгновенное обновление при изменении файлов
  • Production manifest - предварительно сгенерированный манифест для production

Лицензия

MIT © da-b1rmuda

Создано с ❤️ для Web2Bizz