You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Importingimport{thing}from'./file.js'// Note the .js!// Exportingexportconstthing={}
The key difference here is that ESM requires explicit file extensions (.js) in import paths, while CommonJS doesn't. This is part of the ESM specification and helps with performance and reliability.
Root Cause
Our package has several issues that combine to create this bug:
Package declares "type": "module" making it ESM-first
ESM spec requires explicit file extensions in import paths
In other words: we're telling JavaScript "use the new ESM system" (type: "module"), but our build process is creating import statements that only work with the old system.
Impact
Breaks in all ESM environments (Vite, webpack w/ESM, Node.js w/ESM)
Affects downstream packages using native ESM
Type definitions also lack extensions, causing TS errors
This setup attempts to support both CJS and ESM (called "dual package support"), but the ESM output isn't spec-compliant because of the missing extensions.
Proposed Solution: Migrate to tsup
Instead of managing all this complexity ourselves, we should switch to tsup. Think of tsup as a smart bundler that knows how to handle all these module format issues automatically - it's become the standard tool for building modern TypeScript libraries.
Bug Description
@near-js/client fails in ESM environments due to missing
.js
extensions in import paths. Current build output:Error in Vite/other ESM environments:
Technical Context
To understand this bug, it helps to know that JavaScript has two different ways of importing/exporting code between files:
The key difference here is that ESM requires explicit file extensions (
.js
) in import paths, while CommonJS doesn't. This is part of the ESM specification and helps with performance and reliability.Root Cause
Our package has several issues that combine to create this bug:
"type": "module"
making it ESM-firstmoduleResolution: "node"
outputs extension-less importsIn other words: we're telling JavaScript "use the new ESM system" (
type: "module"
), but our build process is creating import statements that only work with the old system.Impact
Current Setup
Here's our current build configuration:
This setup attempts to support both CJS and ESM (called "dual package support"), but the ESM output isn't spec-compliant because of the missing extensions.
Proposed Solution: Migrate to tsup
Instead of managing all this complexity ourselves, we should switch to tsup. Think of tsup as a smart bundler that knows how to handle all these module format issues automatically - it's become the standard tool for building modern TypeScript libraries.
Implementation
Even though tsup handles the build output, we still need a proper tsconfig.json for:
Our current tsconfig:
With tsup, we have two options:
A. Keep using
moduleResolution: "node"
since tsup will handle the ESM output:B. Switch to modern module resolution to catch ESM issues during development:
Option B is recommended as it helps catch ESM compatibility issues earlier in the development process rather than at build time.
Benefits of tsup
Alternative Solutions
While tsup is recommended, there are other approaches we could take:
Add
.js
extensions manually in our TypeScript codeSwitch back to
"type": "commonjs"
Add a post-processing step
Next Steps
Let me know if you'd like me to create a PR with these changes or if you have any questions about the solution!
The text was updated successfully, but these errors were encountered: