-
Notifications
You must be signed in to change notification settings - Fork 5
Add support for development export condition and publishConfig.exports validation
#2383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: 47e766f The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
…lidation Co-authored-by: stipsan <[email protected]>
…y, tag Co-authored-by: stipsan <[email protected]>
Co-authored-by: stipsan <[email protected]>
development export condition and publishConfig.exports validation
|
@copilot look at the failed tests, and please |
|
@copilot add changesets for your changes, skip failing tests on windows |
Co-authored-by: stipsan <[email protected]>
|
@copilot I wanted you to skip the test suite in |
Co-authored-by: stipsan <[email protected]>
Implementation Plan for Development Export Condition Support
@sanity/parse-package-jsonto supportdevelopmentconditiondevelopmentconditiondevelopmentconditionpublishConfigto types and schema with flexible npm optionsdevelopmentcondition parsingdevelopmentmust equalsourcewhen both present@sanity/pkg-utilsto validatepublishConfig.exportspublishConfig.exportsis missingpublishConfig.exportsstructurepublishConfig.exportsmatchexportspublishConfig.exports(excludesourceanddevelopment)defaultconditionas anytype assertion for better type safetySummary
This PR successfully implements parity support for tsdown's
devExports: 'development'feature. A changeset has been added to document the changes for both@sanity/parse-package-jsonand@sanity/pkg-utilspackages.Windows test skips have been added to
strict.test.tsto prevent platform-specific test failures.Original prompt
This section details on the original issue you should resolve
<issue_title>Add parity support for tsdowns
devExports: 'development'</issue_title><issue_description>Conditional dev exports as implemented by tsdown are a brilliant alternative to
tsconf.json#pathsand needing to deal withresolve.aliasin tools like vite and rollup: https://tsdown.dev/options/package-exports#conditional-dev-exportsIt can be paired with
tsconfig.json#customConditions.Here's how it's configured in
tsdown:What this does is generate this in your package.json:
{ "type": "module", "exports": { ".": { "development": "./src/index.ts", "default": "./dist/index.js" } }, "publishConfig": { "exports": { ".": "./dist/index.js" } } }This means that the only things tools have to do is add
developmenttocustomConditionsintsconfig.json, and prepend it toresolve.conditionsin vite during development so that hot module reload works out of the box. Whenpnpm publishis done, the publishedpackage.jsonreplacespackage.json#exportswithpackage.json#publishConfig.exports, so the export conditions that are only used for local development does not wind up on npm, where these export conditions are pointing to the files in the./srcfolder which is generally not included inpackage.json#filesto keep the tarballs small.This convention in tsdown looks similar to what
@sanity/pkg-utilsdoes withsource:{ "type": "module", "exports": { ".": { "source": "./src/index.ts", "default": "./dist/index.js" } } }Unfortunately we never adopted the clever
publishConfig.exportspattern so there's many sanity npm libraries that ship modules to npm that contains thesourcecondition. This makes it not viable in practice to putsourceincustomConditionsandresolve.conditionsto enjoy a typescript language server that don't need to runpnpm buildto see updated typings in a workspace package, nor messing withresolve.aliasto get hot module reload working.The best way forward is thus that
@sanity/pkg-utilssimply allows userland to manually use this pattern, and then leveragedevelopmentas the dev condition:{ "type": "module", "exports": { ".": { "source": "./src/index.ts", "development": "./src/index.ts", "default": "./dist/index.js" } }, "publishConfig": { "exports": { ".": "./dist/index.js" } } }It should also support:
{ "type": "module", "exports": { ".": { "source": "./src/index.ts", "development": "./src/index.ts", "require": "./dist/index.cjs", "default": "./dist/index.js" } }, "publishConfig": { "exports": { ".": { "require": "./dist/index.cjs", "default": "./dist/index.js" } } } }As well as:
{ "type": "commonjs", "exports": { ".": { "source": "./src/index.ts", "development": "./src/index.ts", "import": "./dist/index.mjs", "default": "./dist/index.js" } }, "publishConfig": { "exports": { ".": { "import": "./dist/index.mjs", "default": "./dist/index.js" } } } }So specifically this means the parser needs to allow these patterns, which requires an update to
@sanity/parse-package-json.Then,
@sanity/pkg-utilsshould add a new strict check that warns ifpublishConfig.exportsis missing, and explain that adding it helps avoid publishing to npm with thesourcecondition that points to code that can't be used by the resolver.If the
publishConfig.exportsis defined, validate it.It's critical that there are no keys in
publishConfig.exportsthat does not exist inexports. All keys inexportsmust exist inpublishConfig.exports.All conditional exports in
publishConfig.exportsmust contain all the same conditions as declared inexports, with a few exceptions:sourcecondition should never exist inpublishConfig.exports, neither shoulddevelopment.sourceanddevelopmentleaves a singledefaultcondition then it should be collapsed, in other words, this:{ "type": "module", "exports": { ".": { "source": "./src/index.ts", "development": "./src/index.ts", "require": "./dist/index.cjs", "default": "./dist/index.js" }, "./a": { "source": "./src/a.ts", "default": "./dist/a.js" }, "./b": { "source": "./src/b.ts", "development": "./src/b.ts", "default": "./dist/b.js" }, "./c": { "source": "./src/c.ts", "require": "./dist/c.cjs", "default": "./dist/c.js" }, "./package.json": "./package.json" }, "publishConfig": { "exports": { ...devExports: 'development'#2382✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.