A Vite Plugin Now Generates uni-app's pages.json from Vue Files, Eliminating Manual Config
Manually synchronizing a central `pages.json` with a growing set of page files is a persistent source of errors and merge conflicts in uni-app projects. Automating its generation from the pages themselves removes that friction and keeps configuration co-located with the code it describes.
Version 1.2.0 of the `@meng-xi/vite-plugin` suite adds a `generatePages` plugin that reverses the typical uni-app workflow. Instead of manually maintaining a central `pages.json` file and then generating routes from it, the plugin scans the project's Vue files and a custom `<route-config>` block within each page to build the configuration automatically. It handles main package pages, sub-packages, and tab bar assembly, while preserving non-page fields like `globalStyle`.
Page-level configuration—titles, meta fields, and tab bar icons—is declared directly inside the Vue file it affects. A stable sorting algorithm and an `entryPage` option prevent the startup page from drifting alphabetically. The plugin also watches for file changes during development, regenerating `pages.json` through a serial queue to avoid race conditions.
Combined with the existing `generateRouter` plugin, the toolchain now forms a complete automated pipeline: Vue files produce `pages.json`, which in turn produces typed route configurations. The upgrade is non-breaking for all 1.x users and expands Vite peer dependency compatibility up to version 8.
Co-locating page configuration inside the Vue file itself, rather than in a separate JSON manifest, mirrors the shift in modern frameworks toward file-system-based routing and reduces the surface for configuration drift.
The explicit `entryPage` option addresses a real-world footgun in uni-app where relying on alphabetical path order can silently change the startup page as a project grows.
Using a serial queue for watch-mode regeneration is a pragmatic defense against race conditions that many file-watching tools overlook, especially when multiple file events fire in quick succession.
Compared to the <route-config> configuration, a more elegant approach would be to declare a definePage in the page, for example: definePage({ name: 'mine', meta: { needLogin: false }, style: { navigationBarTitleText: '我的' } }) Also, files that don't declare route-config or definePage in the Vue page won't be generated into page.json, right?
Files that don't declare route-config or definePage in the Vue page won't be generated into page.json.
Yeah, that's what we expect. Adding a definePage would be perfect. One more question: definePage({ name: 'mine', meta: { needLogin: false }, style: { navigationBarTitleText: '我的' } }) In a case like this, where I haven't defined a title but have set navigationBarTitleText in style, will the final generation still preserve my style: { navigationBarTitleText: '我的' } and not fall back to a default strategy for a missing title?