-
Notifications
You must be signed in to change notification settings - Fork 75
chore(build): build a universal ESM and CommonJS package #371
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
base: main
Are you sure you want to change the base?
Conversation
scripts/update-package-info.ts
Outdated
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8")) as PackageJson; | ||
|
||
// Define the packageInfo.ts content | ||
const packageInfoContent = `// This file was generated by scripts/update-package-info.ts - Do not edit it manually. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no good way to have __dirname
/ import.meta.dirname
as explored in https://evertpot.com/universal-commonjs-esm-typescript-packages/ and I couldn't think of anything better either. so instead we'll generate the file on-demand. This is similar to how it is done in github.com/mongodb-js/mongosh/
Pull Request Test Coverage Report for Build 16320816887Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
package.json
Outdated
"scripts": { | ||
"prepare": "npm run build", | ||
"build:clean": "rm -rf dist", | ||
"build:compile": "tsc --project tsconfig.build.json", | ||
"build:update-package-info": "tsx scripts/update-package-info.ts", | ||
"build:esm": "tsc --project tsconfig.esm.json && echo '{\"type\":\"module\"}' > dist/package.json", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Source: As you can also see that both our cjs and esm packages get a 1-line package.json file with a type property.
This is required because Node needs to know wether files with a .js extensions should be interpreted as CommonJS or ESM. It can’t figure it out after opening it.
Node will look at the nearest package.json to see if the type property was specified.
@@ -55,4 +55,4 @@ jobs: | |||
rm -rf node_modules | |||
npm pkg set scripts.prepare="exit 0" | |||
npm install --omit=dev | |||
- run: npx -y @modelcontextprotocol/inspector --cli --method tools/list -- node dist/index.js --connectionString "mongodb://localhost" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm setting to ESM to keep the changes minimal. Doing cjs default won't change our issues with the oidc-plugin
, I think the only way to deal with that is to make some changes on the plugin itself to not depend on the require
of an ESM module which is a higher Node version feature.
Generally worth checking if we're going to have any problems with dist/index.js
going away.
I'd expect the worst being our dev environment configurations no longer being correct.
Otherwise we can also create a index.js alias to point to esm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is solved, now that you have dist/index.js pointing to esm.
@@ -0,0 +1,4 @@ | |||
export { Server, type ServerOptions } from "./server.js"; | |||
export { Telemetry } from "./telemetry/telemetry.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can consider exporting a single class which would make the setup easier but I'll leave that to future followups
|
||
// Create a dist/index.js file that imports the ESM index.js file | ||
// To minimize breaking changes from pre-universal package time. | ||
const indexPath = resolve(distDir, "index.js"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just out of precaution in case some of our deployments end up looking for dist/index.js
... can be removed though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally think its fine to have it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks perfect. Tested it locally with vscode and works as expected 🚀
Totally unrelated but you might wanna cherry-pick the changes in this commit because currently we are shipping some unnecessary files in our final dist.
@@ -55,4 +55,4 @@ jobs: | |||
rm -rf node_modules | |||
npm pkg set scripts.prepare="exit 0" | |||
npm install --omit=dev | |||
- run: npx -y @modelcontextprotocol/inspector --cli --method tools/list -- node dist/index.js --connectionString "mongodb://localhost" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is solved, now that you have dist/index.js pointing to esm.
} | ||
} | ||
}, | ||
"main": "./dist/cjs/lib.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should add the types
as well pointing to "./dist/cjs/lib.d.ts"
considering that the main
is for older tooling?
|
||
// Create a dist/index.js file that imports the ESM index.js file | ||
// To minimize breaking changes from pre-universal package time. | ||
const indexPath = resolve(distDir, "index.js"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally think its fine to have it.
Adds ESM and CommonJS-based exports to the package.
The motivation is largely to add support for VSCode to use the library.
Possible Alternatives
cjs
and use gen-esm-wrapper - might be simpler in a sense and more consistent with how we deal with it in i.e. mongosh and other packages. But because we were distributing an ESM package until now, the potential breaking change is a bit worrying.Inspired by #325
Relevant reading: