Skip to content

generateRouter ​

Auto-generate router configuration and TypeScript type declarations from uni-app's pages.json.

Import Methods ​

typescript
// Submodule import (recommended)
import { generateRouter } from '@meng-xi/vite-plugin/plugins/generate/generate-router'

// Barrel import
import { generateRouter } from '@meng-xi/vite-plugin'

Quick Start ​

typescript
import { defineConfig } from 'vite'
import { generateRouter } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [generateRouter()]
})

Options ​

OptionTypeDefaultDescription
pagesJsonPathstring'src/pages.json'Path to pages.json
outputPathstring'src/router.config.ts'Output file path
nameStrategyNameStrategy'camelCase'Route naming strategy
includeSubPackagesbooleantrueInclude sub-package routes
dtsstring | booleanfalseRoute type declaration file output path
preserveRouteChangesbooleantruePreserve user modifications to route configs

Inherits BasePluginOptions: enabled, verbose, errorStrategy

Advanced Options ​

OptionTypeDefaultDescription
outputFormat'ts' | 'js''ts'Output format
customNameGenerator(path: string) => string-Custom name generator
watchbooleantrueWatch for changes
metaMappingRecord<string, string>See belowStyle to meta field mapping
exportTypesbooleantrueExport type definitions (TS)
headerTemplateboolean | stringfalseFile header comment template
customFieldsRecord<string, string>{}Custom field key-value pairs

name Property in pages.json ​

The name field in a page configuration object in pages.json is used directly as the route name, and takes priority over nameStrategy auto-generation.

json
{
  "pages": [
    {
      "path": "pages/user/profile",
      "name": "UserProfile",
      "style": { "navigationBarTitleText": "Profile" }
    }
  ]
}

In the above configuration, the route name is 'UserProfile' instead of the auto-generated 'pagesUserProfile' from nameStrategy.

Route Naming Strategies ​

StrategyDescriptionExample PathGenerated Name
camelCaseCamel case/pages/user/profilepagesUserProfile
pascalCasePascal case/pages/user/profilePagesUserProfile
pathPath underscore/pages/user/profilepages_user_profile
customCustom function--

meta Object in pages.json ​

The meta field in a page configuration object in pages.json is directly merged into the route's meta, and takes priority over metaMapping.

json
{
  "pages": [
    {
      "path": "pages/user/profile",
      "style": { "navigationBarTitleText": "Profile" },
      "meta": { "requireAuth": true, "customField": "value" }
    }
  ]
}

In the above configuration, meta.requireAuth and meta.customField are written directly to the route meta, while style.navigationBarTitleText is mapped to title via metaMapping. When both have the same field name, the meta object value takes priority.

Default metaMapping ​

typescript
{
  navigationBarTitleText: 'title',
  requireAuth: 'requireAuth'
}

preserveRouteChanges Route Modification Preservation ​

When enabled, the plugin reads the existing file during regeneration and merges user modifications, avoiding overwriting manually added content.

Merge Strategy:

FieldBehavior
pathAlways follows pages.json, cannot be overridden
nameAlways follows pages.json (pageConfig.name or nameStrategy auto-generation)
metaFields generated from pages.json always use new values, user custom fields are preserved
Non-standard propertiesUser-added custom properties like beforeEnter, component are fully preserved

Example: Suppose pages.json has updated the page title, and the user has added beforeEnter to an existing route:

typescript
// User-modified route config
export const routes: RouteConfig[] = [
  {
    path: '/pages/index/index',
    name: 'pagesIndexIndex',
    meta: { title: 'Custom Title', customField: 'value' },
    beforeEnter: (to, from, next) => { next() }  // User-added guard
  }
]

After regeneration (navigationBarTitleText in pages.json has been changed to "Home"):

typescript
export const routes: RouteConfig[] = [
  {
    path: '/pages/index/index',
    name: 'pagesIndexIndex',
    meta: { title: 'Home', isTab: true, customField: 'value' },  // title synced from pages.json, customField preserved
    beforeEnter: (to, from, next) => { next() }     // Custom property preserved
  },
  {
    path: '/pages/new/page',                         // New page auto-generated
    name: 'pagesNewPage',
    meta: { title: 'New Page' }
  }
]

dts Type Declarations ​

Control whether to generate route type declaration files (.d.ts), extending the RouteNameMap interface for the @meng-xi/uni-router module to enable type-safe route navigation.

ValueDescription
falseDon't generate type declaration file (default)
trueUse default path src/router.d.ts
stringGenerate type declaration file at specified path

Generated type declaration file example:

typescript
import '@meng-xi/uni-router'

declare module '@meng-xi/uni-router' {
	interface RouteNameMap {
		/** Home */
		pagesIndexIndex: { path: '/pages/index/index'; meta: { title: string; isTab: true } }
		/** Profile */
		pagesUserProfile: { path: '/pages/user/profile'; meta: { title: string; requireAuth: true } }
	}
}

Examples ​

Output JavaScript ​

typescript
generateRouter({
	outputFormat: 'js',
	outputPath: 'src/router.config.js'
})

Custom Route Names ​

typescript
generateRouter({
	nameStrategy: 'custom',
	customNameGenerator: path => `route_${path.replace(/\//g, '_')}`
})

Custom Meta Mapping ​

typescript
generateRouter({
	metaMapping: {
		navigationBarTitleText: 'title',
		requireAuth: 'requireAuth',
		customField: 'custom'
	}
})

Exclude Sub-packages ​

typescript
generateRouter({
	includeSubPackages: false
})

Generate Route Type Declarations ​

typescript
generateRouter({
	dts: true // Use default path src/router.d.ts
})

// Or custom path
generateRouter({
	dts: 'src/types/router.d.ts'
})

Add File Header Comment ​

Adds a JSDoc-style comment header at the top of the generated route config file. Each placeholder automatically maps to a JSDoc tag line; non-placeholder text between placeholders is discarded.

typescript
// Use default template ({name} {date} {version})
generateRouter({ headerTemplate: true })
// Generates:
/**
 * @plugin generate-router
 * @date 2026-06-23 14:30:00
 * @version 0.2.7
 */

// Custom date format
generateRouter({ headerTemplate: '{name} {date:YYYY-MM-DD} {version}' })
// Generates:
/**
 * @plugin generate-router
 * @date 2026-06-23
 * @version 0.2.7
 */

// Custom fields
generateRouter({
  headerTemplate: '{name} {custom:author} {date} {version}',
  customFields: { author: 'MengXi Studio' }
})
// Generates:
/**
 * @plugin generate-router
 * @author MengXi Studio
 * @date 2026-06-23 14:30:00
 * @version 0.2.7
 */

Placeholder to JSDoc Tag Mapping:

PlaceholderJSDoc TagReplacementExample
{name}@pluginPlugin namegenerate-router
{date}@dateGeneration datetime (default format YYYY-MM-DD HH:mm:ss)2026-06-23 14:30:00
{date:format}@dateDatetime in specified format{date:YYYY-MM-DD} → 2026-06-23
{version}@versionPlugin version0.2.7
{custom:key}@keyCustom field, value from customFields{custom:author} → MengXi Studio

TIP

If the template contains no placeholders, it is output as plain text (no tag conversion).

Output Example ​

typescript
export interface RouteMeta {
	title?: string
	isTab?: boolean
	requireAuth?: boolean
	[key: string]: any
}

export interface RouteConfig {
	path: string
	name?: string
	meta?: RouteMeta
}

export const routes: RouteConfig[] = [
	{
		path: '/pages/index/index',
		name: 'pagesIndexIndex',
		meta: { title: 'Home', isTab: true }
	},
	{
		path: '/pages/user/profile',
		name: 'pagesUserProfile',
		meta: { title: 'Profile', requireAuth: true }
	}
]

export default routes

Notes ​

  • customNameGenerator is required when nameStrategy is 'custom'
  • TabBar pages automatically get isTab: true
  • preserveRouteChanges: true preserves user modifications to routes array
  • Supports parsing pages.json with comments

Released under the MIT License.