Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ await measure(`package.json → ./dist/package.json`, `created in`, async () =>
maintainers: Existing.maintainers,
license: Existing.license,
publishConfig: Existing.publishConfig,
export: Existing.export,
exports: Existing.exports,
main: Existing.main,
module: Existing.module,
typings: Existing.typings,
Expand Down
22 changes: 22 additions & 0 deletions validate_dist.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,25 @@ console.log();
try {
const publintResult = await $`pnpm publint ${pkgDir}`;
} catch (error) {}
Comment on lines 14 to 16

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe publint can actually do the work of checking exports for us. This generates a "suggestion" but is plenty informative to us.

pkg.module is used to output ESM, but pkg.exports is not defined. As NodeJS doesn't read pkg.module, the ESM output may be skipped. Consider adding pkg.exports to export the ESM output. pkg.module can usually be removed alongside too.

Would you be open to swapping the zx call for publint's Node API? Something similar to

const result = await publint({ pkgDir, strict: true }); // import from 'publint'
if (result.messages.length > 0) throw new Error(/* message */)

This would removing manual "exports" check in favor of a supported tool we already use, but didn't gate on.


// Guard against regressions in dist/package.json generation (see build.mjs):
// a missing `exports` field makes bundlers resolve the CJS build, which breaks
// the `@effector/reflect/scope` subpath and causes a dual-package hazard with
// effector-react (scope is lost inside `variant`/`reflect`).
{
const distPkg = JSON.parse(
await fs.readFile(resolve(pkgDir, 'package.json'), { encoding: 'utf-8' }),
);
const missing = [];
if (!distPkg.exports) missing.push('exports');
else {
if (!distPkg.exports['.']) missing.push("exports['.']");
if (!distPkg.exports['./scope']) missing.push("exports['./scope']");
}
if (missing.length > 0) {
throw new Error(
`dist/package.json is missing required field(s): ${missing.join(', ')}`,
);
}
console.log('✓ dist/package.json has valid "exports"');
}