HenrikJoreteg / moonboots

A set of conventions and tools for bundle and serving clientside apps with node.js
159 stars 20 forks source link

Predictable module ordering with browserify #11

Closed lukekarrys closed 10 years ago

lukekarrys commented 10 years ago

https://github.com/substack/node-browserify/issues/355

I think that if developmentMode is true, moonboots should make browserify use predictable module ordering. This helps with things like breakpoints staying on the same line when refreshing a page.

Now that I think about it, should moonboots always make browserify use predictable module ordering? Since moonboots creates a checkSum based on the contents, a rebuild could cause a different checkSum even if nothing has changed.

lukekarrys commented 10 years ago

So I played around with this here https://github.com/HenrikJoreteg/moonboots/commit/2038bd4b4f560874faf675c9fdbef4fe07522c45

This doesn't solve the breakpoint problem I mentioned above, but I think solves the more important issue of subsequent server starts of the same dependency tree having different hashes and therefore breaking the cache.

The issue I referenced above shows that this isn't currently possible without a patch to browserify. Rather than a patch, I used https://github.com/dominictarr/bundle-metadata to do a parallel module dependency traversal and then bundle-metadata orders the dependencies and gives back a predictable hash for that set of dependencies. Then I use that hash and the result.libs to do our final file checksum.

I did some benchmarks to see if this slowed down the total bundle time and this is what I got (using a project I'm working on which ends up with 1.7MB of unminified JS):

Without hash With hash
2558 3215
2655 2975
2705 3019
2638 3065
2614 3074
2658 3043
2724 3080
2664 3014
2761 2955
2672 3142
Avg
2664.9 3058.2
Difference
+393.3 + 14.7%

@HenrikJoreteg Any thoughts on this? I think it'd be nice if we can guarantee that multiple server restarts will keep the same hash.

And I'm gonna add some tests for this so I can make sure in other scenarios thats its doing what I say it is :)