Skip to content

cjs vs esm import compatibility issue #47

@maerzhase

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.

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