Description
The problem
vscode-json-languageservice
provides a UMD bundle as a main entry point. Additionally it has a faux ESM entry point using the "module"
field in package.json
.
This can cause various issues. For example, when bundling with esbuild
:
$ esbuild vscode-json-languageservice --bundle --platform=node --outfile=ls.js
ls.js 5.3kb
⚡ Done in 2ms
$ node ls.js
node:internal/modules/cjs/loader:1080
throw err;
^
Error: Cannot find module './services/jsonCompletion'
Require stack:
- ls.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)
at Module._load (node:internal/modules/cjs/loader:922:27)
at Module.require (node:internal/modules/cjs/loader:1143:19)
at require (node:internal/modules/cjs/helpers:110:18)
at /home/remco/Projects/mdx-analyzer/ls.js:30:26
at /home/remco/Projects/mdx-analyzer/ls.js:20:13
at Object.<anonymous> (ls.js:26:3)
at Module._compile (node:internal/modules/cjs/loader:1256:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
at Module.load (node:internal/modules/cjs/loader:1119:32) {
code: 'MODULE_NOT_FOUND',
requireStack: [ 'ls.js' ]
}
Node.js v18.17.0
The workaround is typically to resolve to the faux ESM files instead. So people need to write custom resolvers to use this package. As a result, you can’t really have vscode-json-languageservice
as a dependency. Having it as a dependency means that package’s users would have to deal with the issue. This means vscode-json-languageservice
must be bundled by consuming packages, which means it can’t be deduplicated.
Possible solutions
Switch to native ESM only
This simplifies the build process. It makes it straight-forward to consume the package. It’s supported out of the box by TypeScript. This means downstream projects also need to use ESM to use this project.
Dual publish as CJS + native ESM
Bundlers are typically pretty good at handling CJS (not UMD). Also tools properly support ESM nowadays. This means you’ll need relatively complex package.json
"exports"
in order to support both CJS and ESM. Also you need type definitions for both CJS and ESM.
This issue actually affects several packages, including but not limited to: