vite-plugin-split-pkg
v0.1.1
Published
A Vite plugin that auto-generates uni-app subPackages from page directories.
Downloads
17
Readme
vite-plugin-split-pkg
A Vite plugin that auto-maintains subPackages for uni-app + Vite projects.
It does not perform generic JS chunk splitting. Instead, it handles uni-app's route-level subpackaging: it scans page directories, generates a deterministically sorted subPackages array, and intercepts uni-app's reads of pages.json in memory during both dev and build — without rewriting the source src/pages.json.
简体中文 | English
Features
- Convention-based directory mode and explicit configuration mode
- Supports
.vueand.nvuepages - Preserves existing
pages,globalStyle,tabBar,easycom,conditionand other fields - Only appends auto-generated subpackages by default; never silently overwrites handwritten
subPackages - Detects page conflicts, duplicate roots, illegal paths, and missing directories with explicit errors
- Watches add / remove / rename in dev mode and triggers a refresh
- Supports
dryRun,debug,watch, andmergeStrategy - Ships with build artifacts and TypeScript declarations
Install
pnpm add vite-plugin-split-pkg -DQuick Start
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import { uniAutoSplitPkg } from 'vite-plugin-split-pkg'
export default defineConfig({
plugins: [
uni(),
uniAutoSplitPkg({
pagesJson: 'src/pages.json',
convention: {
enabled: true,
scanDir: 'src/subpackages'
},
packages: [
{
root: 'biz/order',
dir: 'src/modules/order/pages',
include: ['**/*.vue', '**/*.nvue'],
exclude: ['**/components/**']
},
{
root: 'biz/account',
dir: 'src/modules/account/pages',
independent: true
}
]
})
]
})You can also wrap the configuration with defineUniSplitPkgConfig to keep it in a separate module:
import { defineUniSplitPkgConfig, uniAutoSplitPkg } from 'vite-plugin-split-pkg'
const splitPkg = defineUniSplitPkgConfig({
debug: true,
packages: [{ root: 'biz/order', dir: 'src/modules/order/pages' }]
})
export default {
plugins: [uniAutoSplitPkg(splitPkg)]
}Directory Convention
Default convention:
- Main package pages live under
src/pages - Auto subpackage pages live under
src/subpackages/<packageRoot> - Both
.vueand.nvueare supported components,partials,__tests__,__mocks__, and any file or folder starting with_are ignored by default
For example:
src/subpackages/user/profile/index.vueis converted to:
{
"root": "subpackages/user",
"pages": [
{ "path": "profile/index" }
]
}Explicit Configuration
Explicit configuration is useful when mapping arbitrary directories to specific subpackages by business module:
uniAutoSplitPkg({
packages: [
{
root: 'biz/order',
dir: 'src/modules/order/pages',
include: ['**/*.vue', '**/*.nvue'],
exclude: ['**/components/**'],
independent: false
},
{
root: 'biz/account',
dir: 'src/modules/account/pages',
independent: true
}
]
})Rules:
rootis therootwritten intosubPackagesdiris the actual scanning directoryincludeandexcludeaccept glob patternsindependentis forwarded to the corresponding subpackage- A page cannot match multiple subpackages at the same time — conflicts throw immediately
API
defineUniSplitPkgConfig(options?: UniSplitPkgOptions): UniSplitPkgOptions
uniAutoSplitPkg(options?: UniSplitPkgOptions): Plugin
type UniSplitPkgMergeStrategy = 'append' | 'merge' | 'replace'
interface UniSplitPkgDebugOptions {
enabled?: boolean
logPages?: boolean
logWatchEvents?: boolean
prefix?: string
}
interface UniSplitPkgConventionOptions {
enabled?: boolean
scanDir?: string
include?: string[]
exclude?: string[]
pageExtensions?: string[]
rootSegmentCount?: number
}
interface UniSplitPkgPackageOptions {
root: string
dir: string
include?: string[]
exclude?: string[]
independent?: boolean
}
interface UniSplitPkgOptions {
pagesJson?: string
convention?: UniSplitPkgConventionOptions
packages?: UniSplitPkgPackageOptions[]
watch?: boolean
dryRun?: boolean
debug?: boolean | UniSplitPkgDebugOptions
mergeStrategy?: UniSplitPkgMergeStrategy
}Merge Strategies
append: default. Keeps handwrittensubPackagesand appends generated ones at the end. Throws if a generatedrootcollides with a handwritten one.merge: merges generated and handwritten entries that share the sameroot; pages are deduplicated bypathand stably sorted.replace: discards existingsubPackagesand uses only the generated result.
Logging & Debug
The plugin logs:
- The number of subpackages discovered
- The total number of pages
- The page count per subpackage
- Actionable errors for conflicts, illegal paths, missing directories, etc.
When debug is enabled, watch events and the final generated subPackages payload are logged as well:
uniAutoSplitPkg({
debug: {
enabled: true,
logPages: true,
logWatchEvents: true
}
})dryRun
dryRun is intended for previewing the result.
- Scanning, validation, and logging still run
- The generated payload is not injected into the final
pages.json.js - Use it to verify the route mapping before flipping the switch
uniAutoSplitPkg({
dryRun: true,
debug: true
})How It Works
The plugin does not write back to src/pages.json. Instead, it intercepts two read paths in parallel:
- The original
src/pages.jsonis parsed with JSONC, so comments and trailing commas are allowed - The plugin runs scan -> normalize -> validate -> generate -> merge
- For paths that go through Vite's module graph, it returns the in-memory
<src>/pages.json.js(the virtual module id exposed byvite-plugin-uni, which both H5 and mini-program dev rely on) - For build chains that read
src/pages.jsondirectly (mini programs), it intercepts the runtime read for the current project and returns the merged result
Implications:
- Source files stay clean
- Dev and build share the same generation logic
- If uni-app introduces a new entry point that reads
pages.json, the plugin may need to adapt
Playground
A working example project is included for end-to-end testing:
playground/uni-test/src/subpackages/user/profile/index.vueplayground/uni-test/src/modules/order/pages/list/index.vueplayground/uni-test/src/modules/account/pages/center/index.vue
The integration is wired up in playground/uni-test/vite.config.ts.
FAQ
Why not write back to src/pages.json directly?
pages.json is a core uni-app configuration file. Writing back is technically possible but is more likely to cause format drift, noisy diffs, and rollback issues. The current implementation prefers in-memory interception; even for mini-program build chains that read src/pages.json directly, it intercepts the runtime read instead of persisting changes back to the source.
Can I keep comments in pages.json?
Yes. The plugin uses a JSONC parser, so comments and trailing commas are supported.
Will my handwritten subPackages be overwritten?
Not by default. The default mergeStrategy is append, which only appends auto-generated entries. Only replace will discard the existing subPackages.
Are deleted pages removed from the result?
Yes. In dev mode the plugin watches add / remove / directory changes; rescanning keeps the result in sync.
Which paths are ignored?
By default:
**/components/****/partials/****/__tests__/****/__mocks__/**- Files or folders starting with
_
Development
pnpm install
pnpm test
pnpm buildStatus
- Convention-based directory mode implemented
- Explicit configuration mode implemented
- Conflict validation and stable sorting implemented
- Minimal unit tests in place
- Playground integration provided
