Skip to content

ESM bundle imports cosmjs-types without .js extension, fails under Node strict ESM resolution #30

@nikshepsvn

Description

@nikshepsvn

Description

The bundled ESM file at node/index.node.js (and browser/index.browser.js) contains imports like:

import { SignMode } from 'cosmjs-types/cosmos/tx/signing/v1beta1/signing';
import { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx';

These are missing the .js extension. Node ≥ 20 in strict ESM mode rejects them with ERR_MODULE_NOT_FOUND:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'cosmjs-types/cosmos/tx/signing/v1beta1/signing'
imported from node_modules/chainsig.js/node/index.node.js
Did you mean to import 'cosmjs-types/cosmos/tx/signing/v1beta1/signing.js'?

Reproduction

Node 20+ with strict ESM:

mkdir t && cd t && npm init -y -q && \
npm pkg set type=module && \
npm i chainsig.js@1.1.14 && \
node -e "import('chainsig.js').then(m => console.log(Object.keys(m)))"

Result: ERR_MODULE_NOT_FOUND on cosmjs-types/cosmos/tx/signing/v1beta1/signing.

Affected versions

1.1.14 (latest at time of report). Verified by inspecting the published bundle.

Workaround

Idempotent postinstall script that appends .js to extensionless cosmjs-types/... imports:

import { readFileSync, writeFileSync } from "node:fs";
const COSMJS_RE = /from\s*['"]cosmjs-types\/([^'"]+)['"]/g;
for (const path of ["node_modules/chainsig.js/node/index.node.js", "node_modules/chainsig.js/browser/index.browser.js"]) {
  const before = readFileSync(path, "utf8");
  const after = before.replace(COSMJS_RE, (_m, sub) =>
    /\.[a-z0-9]+$/i.test(sub) ? \`from'cosmjs-types/\${sub}'\` : \`from'cosmjs-types/\${sub}.js'\`,
  );
  if (after !== before) writeFileSync(path, after);
}

Suggested fix

Either:

  1. Configure the bundler (looks like tsup / tsdown / similar) to preserve full extension specifiers in ESM output.
  2. Switch to importing the specific submodules with explicit .js:
    import { SignMode } from 'cosmjs-types/cosmos/tx/signing/v1beta1/signing.js';

Found while building near-hydra — happy to send a PR if helpful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions