Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert source code to using ESM instead of CommonJS #191

Open
wants to merge 11 commits into
base: typescript-definitions
Choose a base branch
from

Conversation

aron
Copy link
Contributor

@aron aron commented Jan 15, 2024

Fixes #187

Most ecosystems are moving towards ECMAScript modules as the primary way of writing code (see browser, , TypeScript, bun, deno etc). Even the node docs describe ESM as:

ECMAScript modules are the official standard format to package JavaScript code for reuse. Modules are defined using a variety of import and export statements.

Our commonjs source code can be consumed by nodejs programs as a first class module system and most of the above as a secondary (with the exception of the browser which would need transforming/bundling).

So this PR explores converting the codebase to use ESM modules instead of CommonJS (and providing a transpiled version of commonjs). I think this makes sense long term as we'll be able to use the ESM version in the browser, deno etc. and it supports default exports which allows us to cleanly extend the surface area of the library to export additional objects (like error types and helpers).

The code change here is pretty vast but it can be summarized:

  1. The bulk of it is updating the index.js and lib files to use ESM, this was done with the TypeScript LSP action.
  2. The only part that fails here is reading the package.json as there's no support for `import pkg from "package.json" assert { type: "json" } in older node versions. So instead we cludge it by writing out a new version.js file with the version at build time. By default we just have a hardcoded string for local development.
  3. For CommonJS we use the new build:commonjs script which will use the TypeScript compiler to output commonjs into the dist/commonjs directory. We then add a new exports field to the package.json to wire this up. A couple of caveats here:
    • We need to write a package.json with {"type": "commonjs"} into the dist/commonjs directory, otherwise it'll try and interpret the files as esm.
    • We need a root index.cjs file to do the initial require and take the default export, though we can generate this.

This means that in most cases everything works as expected and TypeScript projects no longer need to set the esModuleInterop flag for replicate.

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.

None yet

1 participant