-
Notifications
You must be signed in to change notification settings - Fork 140
Open
Labels
Description
Context
Helpful understanding:
TLDR
- ESM modules can import CJS modules.
- CJS modules cannot import ESM modules.
- MarkBind is built as a CJS module.
- We cannot use modern ESM-only dependencies. If existing packages migrate to esm, we cannot update dependencies. If we want to integrate new esm-only packages, we also can't do so.
- Many popular packages (like node-fetch v3, chalk v5, unified, remark) have already dropped CJS support. If you stay on CJS, you are locked into old versions forever.
- Only by migrating, will allow usage of both old CJS and new ESM packages. Hence, for future compatibility + usage of modern JavaScript features, it is a necessary infrastructure change.
Implementation Plan
- Migrate both
coreand clito Typescript. Useimport/export` syntax. - Continue emitting CJS initially for both packages.
- Verify that it is working (imports, dynamic loading)
- Migrate
coreandclito ESM together.
Describe the Enhancement
MarkBind's TypeScript configuration currently outputs CommonJS ("module": "commonjs"), a legacy module system. At some point, we should do a rewrite to migrate to a modern ESM-based output ("module": "NodeNext") to align with the evolving JavaScript ecosystem, unlock performance benefits, and ensure future compatibility.
- Ecosystem Shift: The JavaScript/Node.js ecosystem is standardizing on ES Modules (ESM).
- Performance & Features: ESM enables advanced optimizations like superior tree-shaking and supports modern language features like Top-Level await, which are impossible with CommonJS output.
- Forward Compatibility: Using "NodeNext" ensures the project correctly interoperates with both ESM and CJS packages according to Node.js's own modern rules, making it resilient to future ecosystem changes.
- Newer versions of critical dependencies (e.g., markdown-it@14.0.0 (?)) may become pure ESM, causing integration issues to only become more frequent, especially as conduct maintainence and pdate dependencies.
- Newer packages that we might want to integrate in the future may not support CJS
require, and only support being used as a ESM module via import. (Case in point:pagefind). As future batches work to enhance MarkBind, this will be a significant roadblock if not resolved, and workarounds will only add to tech debt.
- Official Guidance: The TypeScript documentation now explicitly discourages "commonjs" for new projects, recommending "node16"/"nodenext" for Node.js environments.
Proposed Changes
- Update tsconfig.json:
- Change "module": "commonjs" to "module": "NodeNext" or as appropriate.
- Change "moduleResolution": "node" to "moduleResolution": "NodeNext".
- Migrate Legacy JavaScript Files: Convert remaining .js files using require/module.exports (e.g., in src/patches/) to use ESM import/export syntax.
- Update package.json: Ensure "type": "module" is set appropriately for the project to be recognized as ESM by Node.js.
Others
- Searched existing issues.
- Possibly related Issues / PRs: Adopt TypeScript for core package #1877 , Package.json / Package-lock.json dependency Issue #2613
- Environment: Win 11
- MarkBind version: 6.0.2
- It is a major breaking change
Also, don't get confused:
- Even tho right now in the
tsfiles, we are usingimportetc. (which isesmsyntax), because of the ultimate output ascjsthat in the end converts everything torequire, we can't useesmonly modules.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Discussion