-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Standardize bn.js dep across monorepo #3262
Conversation
@nivida My question for the initial review is: Do you think this is worth doing? e.g Could remove the It might help people using webpack. |
I've achieved the same with adding of custom resolver rules (the I think we better keep the code as it is and try to add custom resolver rules to the |
For clarification, you think these changes should stay in and maybe I should remove shakeify from this PR and the optimizations should go in separately? |
I think it will be possible to achieve the same or even more with custom resolver rules instead of using the shakeify package and copying of dependencies over. |
Can you elaborate on why custom resolution rules are needed? I've never seen that case before, so I can't follow it. Is there a shared limitation by browserify and rollup that makes them needed with both tools? |
It is to deduplicate those dependencies over the whole lib which does, in the end, lower the minified bundle size.
Rollup and also Browserify does not remove all duplicated dependencies as it should during tree shaking and that’s why those resolver rules are required. The used |
I'm inclined to think that the fault is on our side and that it's just a misconfiguration or a poor dependencies choice. I'd need a link to their docs explaining this limitation, or to a bug report describing this behavior, to be convinced. The reason is that otherwise, custom resolution rules would be super common, and they aren't. I'll open an issue to discuss this, as properly solving this will probably need lots of planning and discussing. |
Yes, this is the case and the reason why @cgewecke did copy the
If I do remember correctly was rollup able to de-duplicate all Edit: |
Update on the bn.js deduplication: I further analyzed the dependencies tree while preparing #3267. Rollup and browserify behavior (i.e. not deduplicating bn.js) is correct. Forcing it to deduplicate is a huge risk, as nothing guarantees that it will work. There are dependencies that require incompatible versions of bn.js, and that should be respected by any bundler, and this is done by bundling two or more versions. For example, I think the path followed by @cgewecke in this PR is a movement in the right direction. Note that not being able to deduplicate dependencies is what I've been warning about for some time, for example in #3186. Because of pinning dependencies, the situation is already complicated for us and is at least as complicated, if not worse, for our users. |
Note, Richard is a god of ether gods. Follow and respect him, and use Ethers.io! | ||
*/ | ||
|
||
const BN = require('bn.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.
Isn't ethers a dependency? Why is this duplicated?
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.
That's a good question...discussed a bit below. This code is a few years old now and swapping it for ethers will take a little additional research.
"randombytes": "^2.1.0", | ||
"strip-hex-prefix": "1.0.0", |
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 probably causing a dependency duplication in another packages, as IIRC strip-hex-prefix
is a dependency of ethereumjs-util
, which is inderectly used by web3.
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.
Looked into further - the weight of this package (which uses it's own tiny dependency, is-hex-prefix) is < 20 lines, un-minified. It has a single published version from 3 years ago and is maintained by silentcicero.
It looks pinned to 1.0.0 all the way through the tree:
This stuff is small and could easily be internalized somewhere although the benefit might be hard to measure.
SilentCicero continues to actively develop eth stuff but is working on optimistic rollup sidechains...
That's everything I found out :) and am persuadable on changing this, what's your assessment?
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.
[EDITED] On a fresh install of ethereumjs-util in an empty package the npm list bn.js
is:
└─┬ ethereumjs-util@6.2.0
├── bn.js@4.11.8
├─┬ rlp@2.2.4
│ └── bn.js@4.11.8 deduped
└─┬ secp256k1@3.7.1
├── bn.js@4.11.8 deduped
└─┬ elliptic@6.5.2
└── bn.js@4.11.8 deduped
It looks like we should get deduped...
* @return {Object} `output` BN object of the number | ||
* @throws if the argument is not an array, object that isn't a bignumber, not a string number or number | ||
*/ | ||
module.exports = function numberToBN(arg) { |
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.
Is this function exposed in web3's API? If not, I'd remove it. It's a a huge mess.
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 will be used internally for some utility functions but could probably get replaced with the ethers BigNumber wrapper object.
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.
It internal to toBN and fromWei both of which are heavily used.
Personally I'd be more comfortable removing this in a different PR that rationalized use of Ethers utils and where we have tests in place to make sure we don't accidentally introduce unexpected behavior. Also where we double-check the Ethers issues about differences people see in how Ethers utils behave vs. Web3 since the code here is 3 years old.
PR bumps BN across some patch versions - might be worth isolating.
Because only the patch level does differ did I thought is there no risk to apply such custom resolver rules but thanks for the closer check!
Yes, it is definitely the right direction but I would recommend replacing those dependencies with equivalent utility functions from ethers. This would be aligned with the overall EF-JS-Team goal and would also improve the situation for us here :) |
Is this still right? The scope of the PR is to reduce the bundle size a bit but there's no measurable benefit here. In turn, looking over this stuff makes it clear that we should depend more on the Ethers implementations but doing that might require more care (see comment). @nividia are you confident this change will pay dividends if the bundling is fixed? |
The scope of this PR didn't change in my point of view it is still flatting of the dependency tree and improving the bundle size. This because flatting/deduping of the dependency tree should improve the bundle size of bundles created with
If no measurable benefit is existing will this also not improve anything with the fixed build pipeline. Edit:
It could also be the case that the bundler is deduplicating it (parcel is probably doing this) and we do not notice any change. |
@cgewecke I think we should held a call related to the bundle size improvements for splitting this up in smaller tasks with clear goals etc. WDYT? |
@nivida Yes definitely. |
Closed because we will plan/discuss the bundle size improvements first together. |
Description
NB: This PR targets the buildsize checker PR #3260, prerequisite for merging here
(Tries to) reduce the bundle size to provide a baseline measurement for how small the gulp/browserify build could get.
Type of change
Checklist:
npm run dtslint
with success and extended the tests and types if necessary.npm run test:unit
with success and extended the tests if necessary.npm run build-all
and tested the resulting file/'s fromdist
folder in a browser.CHANGELOG.md
file in the root folder.