Skip to content

feat: add CJS build output#8

Merged
Royal-lobster merged 1 commit intomainfrom
feat/cjs-support
Apr 6, 2026
Merged

feat: add CJS build output#8
Royal-lobster merged 1 commit intomainfrom
feat/cjs-support

Conversation

@Royal-lobster
Copy link
Copy Markdown
Member

@Royal-lobster Royal-lobster commented Apr 6, 2026

Summary

  • Add CJS format to tsup build alongside ESM
  • Add require, main, module, types fields to package.json exports
  • Enables projects using moduleResolution: "node" to resolve imports without manual tsconfig paths workarounds

Test plan

  • pnpm build produces both .js (ESM) and .cjs (CJS) output
  • All 126 tests pass
  • DTS files generated for both formats

🤖 Generated with Claude Code

Closes #15

Projects using moduleResolution: "node" cannot resolve package exports
maps, requiring manual tsconfig paths workarounds. Adding CJS format
to tsup and require/main/types fields to package.json lets these
projects resolve imports natively.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Royal-lobster Royal-lobster merged commit 0746d58 into main Apr 6, 2026
3 checks passed
@github-actions github-actions Bot mentioned this pull request Apr 6, 2026
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces CommonJS build output alongside ESM to improve compatibility with projects using legacy module resolution. The changes include updating the build configuration and expanding the package.json exports and entry points. Feedback suggests addressing subpath resolution issues for legacy environments using typesVersions or proxy directories and warns about the 'Dual Package Hazard' which could result in multiple singleton instances if both module formats are loaded.

Comment thread package.json
Comment on lines 24 to 43
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
"require": "./dist/index.cjs"
},
"./nestjs": {
"types": "./dist/integrations/nestjs/index.d.ts",
"import": "./dist/integrations/nestjs/index.js",
"types": "./dist/integrations/nestjs/index.d.ts"
"require": "./dist/integrations/nestjs/index.cjs"
},
"./nextjs": {
"node": {
"types": "./dist/integrations/nextjs/index.d.ts",
"import": "./dist/integrations/nextjs/index.js",
"types": "./dist/integrations/nextjs/index.d.ts"
"require": "./dist/integrations/nextjs/index.cjs"
},
"default": null
}
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The PR description mentions that this change enables projects using moduleResolution: "node" to resolve imports. While the addition of the top-level main field fixes the root import, subpaths like @iqai/alert-logger/nestjs will still fail to resolve under the legacy node resolution strategy because it does not support the exports field.

To support subpath resolution in legacy environments, you should add a typesVersions mapping for TypeScript and consider using the "proxy directory" pattern (placing a package.json in a nestjs/ folder at the root) for Node.js resolution.

Comment thread package.json
Comment on lines +44 to +46
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Adding CommonJS support alongside ESM introduces the Dual Package Hazard. Since AlertLogger appears to be a singleton (based on getInstance() calls in the Next.js integration), a project that accidentally loads both the ESM and CJS versions (e.g., through different dependencies) will end up with two separate instances of the logger. This means configuration applied to one instance will not be reflected in the other.

Consider ensuring the singleton state is shared across both formats by using a Symbol.for() on the global object within the AlertLogger implementation, or by making the CJS build a thin wrapper around the ESM build (though the latter is difficult in pure Node.js).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build out @iqai/alert-logger — health policy, CJS compat, description field, fingerprint dedup

1 participant