Skip to content

cjs vs esm import compatibility issue #47

Description

@maerzhase

There's an incompatibility between the cjs and esm versions of this package that causes issues for projects using named imports.

problem

The current esm version only provides a default export:

'use strict';
import { sha256 } from '@noble/hashes/sha256';
import bs58checkBase from './base.js';
// SHA256(SHA256(buffer))
function sha256x2(buffer) {
return sha256(sha256(buffer));
}
export default bs58checkBase(sha256x2);

But existing projects may be using named imports that work with the cjs version:

import { encode } from 'bs58check';
// or
import * as bs58check from 'bs58check';
bs58check.encode(...);

why It works in cjs but not esm?

In the cjs version, the package does essentially the same thing:

// index.cjs (CommonJS)
var sha256_1 = require("@noble/hashes/sha256");
var base_js_1 = __importDefault(require("./base.cjs"));

function sha256x2(buffer) {
    return (0, sha256_1.sha256)((0, sha256_1.sha256)(buffer));
}

exports.default = (0, base_js_1.default)(sha256x2);

however, cjs modules are consumed differently:

  1. when using require('bs58check'), you get the entire exports object
  2. many bundlers and node have special handling for cjs modules that allows property access forwarding
  3. typescript interoperability helpers (__importDefault and Object.defineProperty(exports, "__esModule", { value: true })) help bridge the gap

In the esm world, imports are strictly enforced. when you do import { encode } from 'bs58check', it's specifically looking for a named export called encode, which doesn't exist in the esm version.

proposed solution

To maintain compatibility with existing code, the esm version should export both the default object and its methods as named exports:

import { sha256 } from '@noble/hashes/sha256';
import bs58checkBase from './base.js';

function sha256x2(buffer) {
    return sha256(sha256(buffer));
}

const bs58check = bs58checkBase(sha256x2);
export const { encode, decode, decodeUnsafe } = bs58check;
export default bs58check;

This would ensure that both import styles work consistently across cjs and esm environments, avoiding breaking changes for users migrating to esm or using packages that have migrated to ESM.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions