Derive the Layout manifest instead of asking for it twice - #3
Conversation
`layouts.library.json` required an `exports` array naming every public component. That list is the same information as the package's own entry files, written a second time by hand, so it could only ever drift from them. It did, and silently. A library renamed eleven components across its source, its recipes and its barrel, rebuilt from a wiped `dist`, and the manifest still carried the old names, because nothing had told the list. The application compiler validates against that manifest, so consumers would have been told the new names were not components while the old ones, which no longer existed, resolved fine. The same list had also never heard about two components added that morning. The names now come from the package's own `exports` map: each target under the output directory maps back to its source entry, and the exported value names are read from there. Source rather than built output, because the manifest is emitted alongside a build rather than after one. Types are excluded, because a type is not a component, and SCREAMING_SNAKE is excluded, because a package that exports `FLAVORS` beside `Flavor` is exporting a value rather than a component. On the library this was found in: 173 hand-declared, 187 derived, every declared name present and the fourteen extras all genuinely exported.
|
Wrong approach, closing rather than iterating on it. This patched the escape hatch to guess component names by parsing the barrel with a regex, when the documented design is that the compiler discovers them from the source. What I produced instead was 187 names of Reopening against the real question: why the consuming library is on |
layouts.library.jsonrequired anexportsarray naming every public component. That list is the same information as the package's own entry files, written a second time by hand, so it could only ever drift from them.It did, and silently.
A library renamed eleven components across its source, its recipes and its barrel, rebuilt from a wiped
dist, and the manifest still carried the old names, because nothing had told the list. The application compiler validates against that manifest, so consumers would have been told<Alert>was not a component while<Callout>, which no longer existed, resolved fine. The same list had also never heard about two components added that morning.The failure has no signal. Everything typechecks, the library builds, the manifest is written, and the wrong names are in it.
What it does now
The names come from the package's own
exportsmap. Each target under the output directory maps back to its source entry, and the exported value names are read from there. Source rather than built output, because the manifest is emitted alongside a build rather than after one, so a bundler that has not run yet leaves nothing to parse. The built file is the fallback for a package laid out differently.Excluded: types, because a type is not a component, and SCREAMING_SNAKE, because a package exporting
FLAVORSbesideFlavoris exporting a value rather than a component.Measured against the library that hit this
The fourteen extras are all genuinely exported and were simply missing from the list, including the two components added that morning.
Consumers delete the
exportsarray. The rest of the config,mode,source,outputandlint, is unaffected.Suites: library 8, application 14, runtime 145, transform crate 58, all passing.