-
-
Notifications
You must be signed in to change notification settings - Fork 167
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
Very large bundle size #249
Comments
[rate-limiter-flexible](https://npmjs.com/package/rate-limiter-flexible) is a CJS module with a single export of all it's various implementations. This defeats tree shaking resulting in the addition of 42KB to the bundle size. animir/node-rate-limiter-flexible#249 This PR brings the source & tests for the in-memory rate limiter into `@libp2p/utils` which reduces the bundle size increase to a few KBs.
[rate-limiter-flexible](https://npmjs.com/package/rate-limiter-flexible) is a CJS module with a single export of all it's various implementations. This defeats tree shaking resulting in the addition of 42KB to the bundle size. animir/node-rate-limiter-flexible#249 This PR brings the source & tests for the in-memory rate limiter into `@libp2p/utils` which reduces the bundle size increase to a few KBs.
[rate-limiter-flexible](https://npmjs.com/package/rate-limiter-flexible) is a CJS module with a single export of all it's various implementations. This defeats tree shaking resulting in the addition of 42KB to the bundle size. animir/node-rate-limiter-flexible#249 This PR brings the source & tests for the in-memory rate limiter into `@libp2p/utils` which reduces the bundle size increase to a few KBs. --------- Co-authored-by: chad <[email protected]>
Not sure how much of a drop-in replacement this would be, but |
@achingbrain The question about ESM is interesting. |
@LGmatrix13 Thanks, it looks promising. |
There are a few caveats around shipping both - the same authored class imported by a CJS file and a ESM file is treated as a separate class by the js runtime (since the classes were loaded from different locations) so were you to pass the instance between them Tools like rollup will create CJS/ESM versions and you can let the runtime select them with an "exports" entry in the project's {
"exports": {
".": {
"types": "./path/to/index.d.ts",
"require": "./path/to/index.cjs.js",
"import": "./path/to/index.esm.js"
}
}
} From my experience the short term pain of going ESM-only is preferable to the long-term pain of supporting both CJS and ESM exports. |
@achingbrain Thank you for your valuable input. I think, it is better to go clean ESM since Node.js natively supports it. |
This issue is really a shortcoming of the bundler/treeshaker used by OP and not of Since OP is using ESM, they can deep import files from the package, circumventing import RateLimiterMemory from "rate-limiter-flexible/lib/RateLimiterMemory.js";
console.log(typeof RateLimiterMemory);
// => function That means that we don't need to convert this codebase to ESM just yet or in a hurry, but can take our time and do it without introducing new problems for users. |
the words "clean" and "ESM" are antonyms. Please don't convert this repo. |
@djMax Could you tell more about your concern on ESM? |
Converting to ESM is a really good idea. Node.js has natively supported it for a long time, and browsers also support it. For CJS (CommonJS) node executions, developers can use "async import()" (dynamic import) |
I think the only sane solution here is dual output packages - CJS and ESM. ESM causes no end of pain with complex environments - jest, webpack, nextjs, they all have their own solutions to this pain and they often fight each other. As a library developer, the nice thing to do is output both and let the particular use case choose based on the environment. https://www.sensedeep.com/blog/posts/2021/how-to-create-single-source-npm-module.html |
@djMax Hi, thank you for sharing the link. Since ESM is now natively supported by Node.js should we all use ESM and abandon CJS? |
No, because it is just not that simple. Node is one environment, but webpack, jest, vitest, typescript - they are all different and all have varying levels of support. And ESM is like a poison that once it puts a drop in your bucket, no other package can do anything but ESM. Whereas CJS works just fine in either ESM or CJS. So dual bundles are require to get flexibility on the backend and tree shaking on the front end. |
My environment is browser and typescript and all I need is the memory rate limiter. I wonder if there is any new guidance? |
@northsea4 Hi. The same is true for your case. You can import the memory limiter directly. import RateLimiterMemory from "rate-limiter-flexible/lib/RateLimiterMemory.js"; |
I use typescript. Simply |
@northsea4 Thank you for sharing this. You could create another file with types declared for RateLimiterMemory only and import it to your project. |
When using the in-memory rate limiter in browsers it results in a bundle addition of 42KB:
If I pull just the depended on files out of this module it's more like 4KB:
I think this is because this module is CJS and exports all the various implementations in one blob which makes tree shaking impossible.
Could this module be updated to be ESM with only named exports?
The text was updated successfully, but these errors were encountered: