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 for consumers and tools.
- 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, if the value is a string it is normalized into{ ".": { "default": value } }.main(Conditional) — Removed if the workspace role is notconfig,app,package, ortool. For allowed roles, the recipe cross-referencesmainwithexports['.'].require:- If both exist and differ — a warning is logged and no changes are applied.
- If
mainexists butexports['.'].requiredoes not —exports['.'].requireis set frommain. - If
exports['.'].requireexists butmaindoes not —mainis set fromexports['.'].require. - If
mainexists andexports['.']is a string —exports['.']is normalized into{ "default": exports['.'], "require": main }.
type(Conditional) — Removed if the workspace role is notconfig,app,package, ortool.browser(Conditional) — Removed if the workspace role is notpackage. For packages, the same cross-reference logic asmainis applied usingexports['.'].browser.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. |