Use exports maps to enforce import contracts
The packages in this repo are being consumed elsewhere using non-contractual deep imports, effectively treating the fluid packages like file folders and not like APIs.
Example of consumers using these libraries:
import { checkUrl } from '@fluidframework/odsp-driver/lib/checkUrl';
import { OdspDriverUrlResolver } from '@fluidframework/odsp-driver/lib/odspDriverUrlResolver';
We've learned over the years that importing without explicit understanding of the api surfaces lead to incredibly fragile consumer/producer relationships.
These imports above should probably have been package-level imports. This practice can be enforced if you add exports entries to your package.json files. This will allow tooling to error when consumers import unsupported things, and will also allow automation to reflect on the api surface more easily.
To explicitly support package imports as well as deep imports like the ones above, you can add exports maps like so:
odsp-driver/package.json:
{
"exports": {
".": {
"types": "./lib/index.d.ts",
"import": "./lib/index.js"
},
"./lib/checkUrl": {
"types": "./lib/checkUrl.d.ts",
"import": "./lib/checkUrl.js"
},
"./lib/odspDriverUrlResolver": {
"types": "./lib/odspDriverUrlResolver.d.ts",
"import": "./lib/odspDriverUrlResolve.js"
}
}
Now as a producer, you're explicit about what can and can't be imported. Reducing your api surface is critical for preventing consumers from importing unexpected contracts.
I would recommend that you start this practice all throughout the repo:
- Add exports maps for everything
- Only export what you expect partners to import
- Don't support deep imports unless there is a valid reason to do so (usually if you need to do this, your package has too many things in it and needs to be broken into smaller chunks.)
@dzearing, we've started tracking our work using dev.azure.com: https://dev.azure.com/fluidframework/internal/_workitems/edit/1608 I'll keep you updated around its progress.
This PR has been automatically marked as stale because it has had no activity for 60 days. It will be closed if no further activity occurs within 8 days of this comment. Thank you for your contributions to Fluid Framework!