[api-extractor] Fix ExtractorConfig failing when bundled into ESM output - #5924
[api-extractor] Fix ExtractorConfig failing when bundled into ESM output#5924Phạm Mạnh Lực (MLuc24) wants to merge 1 commit into
Conversation
ExtractorConfig loaded its default config at module initialization from a __dirname-relative path. __dirname does not exist in ESM, and the replacement bundlers inject resolves to the bundle's own output folder, so the schema file was never found. The defaults are now imported statically, the same way the sibling api-extractor.schema.json already is, which lets bundlers inline them and removes the runtime filesystem read. The four comments in the defaults file were dropped so that it parses as strict JSON; the note they carried is now stated where the import is consumed.
|
Phạm Mạnh Lực (@MLuc24) please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
1 similar comment
|
Phạm Mạnh Lực (@MLuc24) please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
Summary
Fixes #5864
@microsoft/api-extractorthrows at import time when it is bundled into ESM output:ExtractorConfigread its default config from a__dirname-relative path while the module was initializing.__dirnamedoes not exist in ESM, so bundlers substitute a replacement (rolldown, for instance, recommends defining it asimport.meta.dirname), and that resolves to the bundle's output folder rather than the api-extractor package folder. The file is never found there.Details
The defaults are now imported statically, exactly the way the sibling
api-extractor.schema.jsonis already imported a few lines above in the same file. Bundlers inline a static JSON import, so the runtime filesystem read disappears and the package works whether it is consumed directly or bundled.Two details worth calling out, since neither is obvious from the issue:
The suggested fix in the issue cannot be applied as written.
api-extractor-defaults.jsonis JSONC, not JSON — it carries four// ("x" is required)notes, which is why the code usedJsonFile.loadrather than an import in the first place.JSON.parserejects the file as it stands, soresolveJsonModule(or animport ... with { type: 'json' }) would fail to build. This PR removes those four comments so the file is strict JSON. What they documented is now stated at the point where the import is consumed.The cast has to go through
unknown. The defaults deliberately omit fields that become required once a section is used (apiReport.enabled,docModel.enabled,dtsRollup.enabled), so the imported object does not structurally overlapPartial<IConfigFile>and a direct assertion is aTS2352error.JsonFile.loadreturned untyped data, so this is the same looseness as before, now spelled out.Not completely solved:
ExtractorConfig._tsdocBaseFilePathstill resolves../../extends/tsdoc-base.jsonthrough__dirname. That one names a file that has to exist on disk, so it cannot simply be inlined, and it does not throw at import time. I left it alone rather than widen this PR; happy to follow up if you'd like it addressed.No public API changes, and no behavior change outside of bundled ESM consumption.
How it was tested
Reproduced against the published
@microsoft/api-extractor7.58.12, bundled with esbuild to ESM the way the issue describes:Applying this change to the package's compiled output — the defaults inlined instead of read — and rebundling identically:
Also confirmed that the edited defaults file now passes a strict
JSON.parse, and type-checked the assertion against a reduced model ofIConfigFilewithstrictandresolveJsonModuleenabled: the direct cast reportsTS2352onapiReport, while the cast throughunknowncompiles clean.I was not able to run the monorepo's own build or unit tests locally, so
rush build/rush testforapi-extractoris worth a look in CI.