-
Notifications
You must be signed in to change notification settings - Fork 522
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
Add NodeJSSourcesInfo provider to allow for better layering in docker rules. #283
Add NodeJSSourcesInfo provider to allow for better layering in docker rules. #283
Conversation
This is the PR in rules_docker: bazelbuild/rules_docker#487 Also this is complaining about exporting |
Nice work! We were experience slow builds when using the docker images as well! Hope this gets merged! Thanks 👍 |
@alexeagle any thoughts on this? This PR is blocking the merge/finalisation of the PR in rules_docker: bazelbuild/rules_docker#487 |
sorry it got overlooked, I'll TAL today |
a6142cf
to
3380dd7
Compare
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 PR is missing some test coverage which proves the new provider does the thing it's supposed to
internal/node/node_repositories.bzl
Outdated
@@ -239,21 +239,10 @@ alias(name = "npm", actual = "{npm}") | |||
alias(name = "yarn", actual = "{yarn}") | |||
filegroup( | |||
name = "node_runfiles", |
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.
in your change, you introduced a new minimal_node_runfiles
but then I believe the existing one became unreferenced.
It's possible that users downstream referenced @npm//:node_runfiles
and rely on the old content, we should figure that out by vetting this PR on downstream repos.
internal/node/node.bzl
Outdated
@@ -35,6 +35,11 @@ def _trim_package_node_modules(package_name): | |||
segments += [n] | |||
return "/".join(segments) | |||
|
|||
NodeJSSourcesInfo = provider( | |||
doc = """Minimal files needed to run a NodeJS program, without npm packages""", |
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 started a doc string here but it needs to answer more questions
- how is this intended to be used?
- where do the npm packages come from in the consuming end?
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.
Good point about "where do the npm packages come from" - in the new way of having the fine-grained node modules we indeed need to provide these here in the provider also. I updated that.
Not sure what exactly you mean with " * how is this intended to be used", but I did add a sentence for it.
Thanks for the comments I will have some time to go over it tomorrow. |
@Globegitter any updates here? is there anything I can do to help out? |
@Toxicable Sorry I just have not had any time since there was quite a delay since PR opening and the review. My hope is to get around to this before the end of the year. |
@Globegitter it looks like this work needs to be rebased. |
Just brought this up-to-date with latest master and responded to the comments. I will update bazelbuild/rules_docker#487 next but hopefully this is in a state now it can get merged, or at least very close to it. |
I just updated bazelbuild/rules_docker#487 @Toxicable and @tmc so if anyone wants to test this it is ready :) |
@Globegitter Awesome! thanks man, I'll give it a try tomorrow and see how much of a difference it makes |
Just gave this a shot and this was the result:
After:
I cant actually run the container since it throws this error on mac:
But I was getting that error beforehand so it's not related to this PR. Im a little confused as to where the node_modules layer is though. |
// *.pyc files are generated during node-gyp compilation and include | ||
// absolute paths, making them non-hermetic. | ||
// See https://github.com/bazelbuild/rules_nodejs/issues/347 | ||
const excludedFiles = ['.md', '.html', '.pyc']; |
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.
where did this code go? Don't we still need to exclude these non-hermetic inputs?
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 bringing the changes that you did here: 3380dd7#diff-67b0f7c2b38c3bbb6dd40c85eb923174L242 up-to-date with the new code. Basically node_runfiles
includes a whole load of extra stuff like yarn and everything else that node ships with but imo that seems unnecessary, as if someone e.g. needs yarn they should just add it as a dependency explicitly rather than everyone having to pay the cost for this. And our own internal app is still working fine after this change and all tests here are still passing so it seems to me these files are not needed for a nodejs_binary
and they add quite a bit of weight to the resulting docker image.
@Toxicable that might be because you are running on on a mac, but yes now there will be 5 layers (which in theory could be optimised into 3 layers I am just not sure how right now), 3 are layers which just have node specific stuff and should not change on most rebuilds.Yes ideally these would be merged into one layer but I think it is an acceptable first step for now. Then the fourth layer should have your node_modules. You can do And part of the reason that the image is significantly smaller is that a lot of auxiliary data is gone now, like yarn was packaged into the image before as well. And maybe you where still passing in the whole of node_modules before? |
@Globegitter Im inspecting the container but cant find any node_modules for this application.
I can see we have about 10k files from node_modules so even if my manual investigation cant find them in the container we can see that none of the sizes I stated above 10.24kb, 39.91mb, 2.806mb could container that many files For context this is our docker macro
and this is our target
After inspecting the Looking at the files produced by
|
@Toxicable, ah I got the issue. You are still passing a node_modules into nodejs_image. Remove the attribute entirely and try again. |
@Globegitter Ah! progress, ok now we're seeing more reasonable numbers:
Although it isn't quite working just yet. example:
When i boot the image I get the runtime error that it cant find the It worked before with this setup - having out npm deps stread out acrross the libs that actually use them |
Ah good catch, thanks for sharing that. Should be able to fix that. |
Nit but thee seems to be a typo in pr title: SorucesInfo |
This is looking good. Thanks for updating @Globegitter. My only concern is the node runfiles on Windows. I'll do some testing today and have a closer look. |
@gregmagolan, yep I still need to look into the new issue discovered. Should get to it in the next few days. And I'll see about adding a test for this also. |
@Toxicable I just tried to reproduce and as far as I can see neither the native |
@Globegitter Just tried running |
@Toxicable Hmm strange, I added a repro repository here: https://github.com/Globegitter/ts_nodejs_binary_repro Is your behaviour different to that? Am I doing something wrong? Are we using different versions of rules_nodejs? Either way I will also add a PR here to test that case as we do not have that. |
@Globegitter Ok this is super weird. From your reproduction: add another module, such as If this is a bug; I do hope we don't have to redeclare npm deps that a lib used in the future. Example:
|
@Toxicable Ahh very interesting, that does sound like a bug to me indeed. I will open up a PR to add a test for both behaviours. |
@Toxicable I added tests here: #612 funnily enough I am not getting transitive deps loading working at all there for the |
So you wern't able to reproduce it? |
@Toxicable Sorry for not being clear, I do get it to work as you said in the commit you linked. But I have different behaviour here in the repo. Well either way I will investigate. |
#675 has landed which adds transitive npm deps support via the NodeModuleSources provider |
@Globegitter Hey man, any chance you got some ttime to polish this off now it's unblocked? |
Replaced this now by #863 |
Right now the
nodejs_image
packs unnecessary weight, it seems about an extra 20-30MB in total, and about 60MB in the top layer which allows for quite poor incremental builds.One thing was the
@nodejs//:node_runfiles
which includes yarn and npm and a few other things. I am not quite sure why that is necessary to be in the runfiles of each nodejs binary, so I created aminimal_node_runfiles
, which excludes those extra files. The next point was, that it currently does not seem to be possible to get access to just the sources of the binary, which is needed to get better layering, so I included a new provider whichrules_docker
is going to make use of. I am not sure if that is the best way of doing it, but the only one I could get to work.Incremental builds are really fast now and in the
rules_docker
example a change in the app now just has a 60KB top layer to be updated compared to 60+MB before. In one of our apps it is reducing the top/app layer size from ~223MB to ~28MB and reduces the layer rebuild time from ~9/10 to ~3s.Also from what I could figure out, returning
transitive_files
,files
andcollect_data
inDefaultInfo
is redundant so I removed it and all still seems fine.