Normalize Modules
Normalize exports, main, type, browser, and imports fields in workspace package.json files.
Summary
The normalize-modules recipe ensures that module resolution fields in each workspace's package.json follow the official Node.js module specification conventions.
It handles exports map structure, main entry point, module type declaration, browser field, and import maps.
Why Use This Command?
- Keeps Node.js entry points aligned with the module fields each workspace role supports.
- Normalizes shorthand exports into one predictable object shape and keeps explicit conditions reachable.
- Removes inapplicable module fields before they advertise entry points that should not exist.
Requirements
- Node.js runtime — Use a supported Node.js LTS release with the Nova CLI available.
- Project config — Register the workspace and enable
recipes.package-json.<workspace>.normalize-modulesinnova.config.json. - Workspace manifest — The configured workspace must contain a readable
package.jsonfile.
Behavior
For each eligible workspace, the recipe inspects module resolution fields and applies the following rules. See Workspace Rules for how tags are determined.
exports(Conditional) — Removed if the workspace role is notconfig,package, ortool. For allowed roles, a string value is normalized into{ ".": { "default": value } }, and a string atexports['.']becomes{ "default": value }. If an explicitexports['.']condition map putsdefaultbefore other conditions, the recipe movesdefaultlast so those conditions remain reachable. It never inventsrequireorbrowserconditions; declare them explicitly when the package actually provides those entry points.main(Conditional) — Removed if the workspace role is notconfig,app,package, ortool. Otherwise preserved independently:mainis a legacy fallback entry point for either module format, not a synonym forexports['.'].require. Whenexportsis defined, Node.js uses it in preference tomainfor supported imports.type(Conditional) — Removed if the workspace role is notconfig,app,package, ortool.browser(Conditional) — Removed if the workspace role is notpackage. Otherwise preserved independently of any explicitexports['.'].browsercondition.imports(Conditional) — Removed if the workspace role is notconfig,app,package, ortool.
Usage
Options
| Flag | Description |
|---|---|
-d, --dry-run | Run without writing any files. |
-r, --replace-file | Overwrite the original file instead of creating a .nova-backup copy. |