跪拜 Guibai
← All articles
Frontend · Uni-app

vite-plugin-uni-manifest 0.7: Generate manifest.json Before uni-app Reads It

By 狗鸽 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

The timing fix means uni-app builds start from a correct manifest.json, eliminating an entire class of stale-config bugs that previously required external tooling or hand-rolled scripts. The breaking changes also force a deliberate cleanup that prevents silent overwrites of hand-written configuration, removes an API that let users reach into the plugin's logger, and prevents resource exhaustion on macOS builds.

Summary

Version 0.7 of vite-plugin-uni-manifest reworks when manifest.json gets written. A new prepare() method runs the full generation before Vite loads the config, so uni-app reads an up-to-date manifest on the first pass. That removes the workaround that previously forced developers to use @uni-helper/unh or custom scripts to fill the timing gap. The plugin also picks up .env files through Vite's own loadEnv when dotenv is enabled, and replaceArrays switches array merging from concatenation to full replacement, letting a single permissions list override the defaults instead of appending to them.

The release carries four breaking changes. writeManifestJson now takes a pre-resolved OutputSpec instead of raw options; relative outDir is resolved against the cwd option, not process.cwd(); when no config file exists the plugin skips writing instead of replacing a hand-written manifest.json with defaults; and three exports went away: ensureManifestJsonExists, ManifestContext, and the top-level debug. The EMFILE issue from an unnecessary chokidar watcher on one-off builds is fixed, and watch builds no longer close their watcher on buildEnd, restoring hot reload of manifest changes. Tests grew from 46 to 64, with real c12, .env, and temporary-directory coverage now in place.

Takeaways
— 0.7 adds a prepare() method that runs full manifest generation before Vite loads the config, so uni-app reads an up-to-date manifest.json on the first pass.
— writeManifestJson now takes a resolved OutputSpec from resolveOutputSpec() instead of raw options; minify is folded into indent: 0.
— Relative outDir is now resolved against the cwd option, not process.cwd(), which matters in monorepos.
— When no manifest.config.* file exists, the plugin skips writing instead of overwriting a hand-written manifest.json with defaults.
— Three exports were removed: ensureManifestJsonExists(), ManifestContext, and the top-level debug; ManifestContext has a replacement in createManifestWatcher().
— A new dotenv option loads .env files via Vite's loadEnv, with the same file precedence and no VITE_ prefix requirement.
— A new replaceArrays option makes arrays replace defaults entirely instead of concatenating with them.
— One-off builds no longer create a chokidar watcher, fixing EMFILE on macOS; watch builds no longer close their watcher on buildEnd, fixing lost reactions to manifest.config.ts changes.
— Node runtime must be at least 22.22.2 or 24.15.0.
— Tests increased from 46 to 64, adding load-config.test.ts and prepare.test.ts that exercise the real loading flow with actual c12 and .env files.
Conclusions

Moving generation to before Vite loads config is the architectural payoff: it collapses a whole class of workarounds into a single method that the plugin itself can maintain, rather than leaving each user to script around the timing gap.

The removal of the top-level debug export is a sensible API cleanup: exposing the internal logger gave users a backdoor to mutate plugin internals, and killing that surface reduces accidental breakage.

The watch-build fix shows a subtle but important distinction: buildEnd fires on every rebuild, so closing the watcher there was harmful; handing cleanup to process exit is the right model for long-lived Vite processes.

Source: juejin.cn ↗ Google Translate ↗ Backup ↗