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

ESM and CJS outputs for packages #610

Open
davidfiala opened this issue Jun 6, 2024 · 2 comments
Open

ESM and CJS outputs for packages #610

davidfiala opened this issue Jun 6, 2024 · 2 comments

Comments

@davidfiala
Copy link
Contributor

I'd love to get a discussion going around build types (ESM, CJS, or hybrid) for the nice-grpc packages. ESM is the future, but not everyone has arrived yet. Part of arriving is getting ESM outputs everywhere. It seems that we can include both CJS and ESM builds in the same package.json when necessary.

I'm curious which packages need to support hybrid outputs, and which don't. For example, nice-grpc-web can probably be pure ESM as it's browser-based while the rest might benefit from having both outputs for the time being.

As for figuring out the module and target, I have some data and survey of related dependencies:

I think for the node case it's pretty clear we can use ES2023. Although grpc-js targets ES2017 (https://github.com/grpc/grpc-node/blob/a4c2106e63064070f3b9e580b2d1c74b0a9503a4/packages/grpc-js/tsconfig.json#L15) and that is "the" big heavy dependency. I'll say that in my own work I do custom build grpc-js on the server side to meet the same target as the rest of my software (above ES2017). I suspect others that care will do the same rather than take whatever is served on npm.

For the browser's nice-grpc-web case it is less clear. ES2020 is great and would bring some notable features. Sadly though the top web dependency is protobufjs, I think. And they compile to ES5 (https://github.com/protobufjs/protobuf.js). So our heaviest dep isn't itself compiled for the modern era: yuck. ES2020 also lacks BigInt support today (looking at you, long.js.. sigh). Though people have been bringing it up, citing similar stats as above(protobufjs/protobuf.js#1151). --- Emotionally at least, it would be nice to show solidarity in pushing the expectation of modern browser support and any potential performance benefits of not shipping ES polyfills.

So, I'd start the discussion with a proposal:

Hyrbridize all packages for ESM/CJS with ES2023 target, except nice-grpc-web. nice-grpc-web is ESM only targetting ES2020.

@davidfiala
Copy link
Contributor Author

Angular 18 showing its 💔 to grpc and proto....

▲ [WARNING] Module 'nice-grpc-web' used by '....' is not ESM

  CommonJS or AMD dependencies can cause optimization bailouts.
  For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies


▲ [WARNING] Module 'nice-grpc-common' used by '....' is not ESM

  CommonJS or AMD dependencies can cause optimization bailouts.
  For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies


▲ [WARNING] Module 'protobufjs/minimal' used by '....' is not ESM

  CommonJS or AMD dependencies can cause optimization bailouts.
  For more information see: https://angular.dev/tools/cli/build#configuring-commonjs-dependencies

@aikoven
Copy link
Contributor

aikoven commented Jun 6, 2024

I'm curious which packages need to support hybrid outputs, and which don't. For example, nice-grpc-web can probably be pure ESM as it's browser-based while the rest might benefit from having both outputs for the time being.

Actually, I have seen nice-grpc-web being used on NodeJS as well. Some service providers make client libraries based on it that are meant to be platform agnostic. So hybrid is needed for all the packages.

I think for the node case it's pretty clear we can use ES2023.

For the browser's nice-grpc-web case it is less clear. ES2020 is great and would bring some notable features.

Note that most of the other nice-grpc-* libraries are usable in both NodeJS and the browser.

Only nice-grpc, nice-grpc-prometheus, nice-grpc-server-* are NodeJS-only. All the others run on both platforms.


Considering targets, it's clear enough for me how to choose the target for NodeJS builds — just look at the NodeJS version support timeline. But for browsers, I've mostly followed the path of compiling to older targets to maximize browser support. However, this may be an outdated approach, because I've heard that people nowadays compile all of the node_modules code when they bundle their frontends. If that's the case, then we can disregard the browser support and just use the NodeJS baseline to select the target.

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

No branches or pull requests

2 participants