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

Switched from browserify to pure-cjs bundler. #1234

Merged
merged 4 commits into from
Mar 18, 2014

Conversation

RReverser
Copy link
Contributor

Rebase of #1002.

Optimizations and fix for JSXTransformer build.
Dropped dependency on emulation of Node.js native modules.
Added deamdify step for JSXTransformer build.
@zpao
Copy link
Member

zpao commented Mar 10, 2014

I didn't really get to give this a close look last time around so a couple things:

  • Minification step (grunt build:min) takes forever and a day. Any idea why? To the point where grunt build is unusable for actual work.
  • We should really rename these files from browserify if we aren't using it (you mentioned last time it wasn't the interesting part, but once we get this ready 2nd commit to move them would be nice).
  • What do we need deamdify for? I don't think we have anything with the AMD prelude.
  • Will this have stable sorting? One problem with browserify early on was that require path building was async and resulting in the build file being nondeterministic, which was a non-trivial pain.
  • Your UMD is slightly different from the one browserify uses (https://github.com/ForbesLindesay/umd/blob/master/template.js), namely the part where yours doesn't check for other globals, only window. Any foreseeable problems?
  • All of the intermediate license headers are getting stripped out. That should be fine but we'll want to stop using simpleBannerify But I ask because I wanted to know the reasoning.

And to bring in the table you had last time:

orig orig.gz diff diff.gz filename diff % diff.gz %
392755 78327 -26789 -20464 JSXTransformer.js -7% -26%
602322 123001 -4635 -1843 react-with-addons.js -1% -1%
121441 33430 -17999 -3576 react-with-addons.min.js -15% -11%
549027 112014 -2098 -1096 react.js -4% -1%
112340 31015 -16826 -3389 react.min.js -15% -11%

@RReverser
Copy link
Contributor Author

  • Minification step (grunt build:min) takes forever and a day. Any idea why? To the point where grunt build is unusable for actual work.

    Ugh, again... Sorry, was already discussed with @benjamn and fixed previous time but lost in merge conflicts after rebase. Fixed it back. And added pure-cjs@1.9.0 which gives even better build speed by not caring about original formatting and comments.

  • We should really rename these files from browserify if we aren't using it (you mentioned last time it wasn't the interesting part, but once we get this ready 2nd commit to move them would be nice).

    Done.

  • What do we need deamdify for? I don't think we have anything with the AMD prelude.

    That was needed for JSXTransformer which uses source-map which uses AMD Simplified CommonJS Wrapper with amdefine for the inner structuring and ability to be used in browser (you may want to look at, for example, https://github.com/mozilla/source-map/blob/master/lib/source-map/binary-search.js). This caused amdefine to be included into the bundle and used instead of using native CommonJS form which IS actually already used inside define callback, so I decided to add this transformation step.

  • Will this have stable sorting? One problem with browserify early on was that require path building was async and resulting in the build file being nondeterministic, which was a non-trivial pain.

    Sorry, I don't really get the question.

  • Your UMD is slightly different from the one browserify uses (https://github.com/ForbesLindesay/umd/blob/master/template.js), namely the part where yours doesn't check for other globals, only window. Any foreseeable problems?

    I don't see, do you? My UMD is pretty similar to https://github.com/umdjs/umd/blob/master/returnExportsGlobal.js, except that it does not use any external dependencies (yet) so could be simplified. The only global we should care about when AMD and CommonJS are not available is browser's window, so I don't see any problems on how it should be referrred. However, this inside anonymous function in any JS engine refers to global object, so this should be fine in any case.

  • All of the intermediate license headers are getting stripped out. That should be fine but we'll want to stop using simpleBannerify But I ask because I wanted to know the reasoning.

    pure-cjs uses AST manipulations for advanced optimizations instead of strings transformations, so comments, formatting and so on are not preserved since they are obviously not part of AST.

// Our own browserify-based tasks to build a single JS file build
grunt.registerMultiTask('browserify', browserifyTask);
// Our own commonjs-based tasks to build a single JS file build
grunt.registerMultiTask('commonjs', commonjsTask);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to call this task bundle instead of commonjs, because we're bundling CommonJS modules together, and bundle is a generic term that makes sense regardless of which particular bundling tool we use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I can change that easily.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 3f3187c.

benjamn added a commit that referenced this pull request Mar 18, 2014
Switched from browserify to pure-cjs bundler.
@benjamn benjamn merged commit 7987e6a into facebook:master Mar 18, 2014
@zpao
Copy link
Member

zpao commented Mar 18, 2014

we'll want to stop using simpleBannerify

This never happened. I'll fix it.

I'm going to live with this for a bit. I'm shipping 0.10 very soon so this will go out there. The file size wins are nice, but I'm actually not happy with the code that's generated. Stripping out comments from the dev build might actually be a deal breaker (especially as we encourage people to use their debugger and step through code).

@zpao
Copy link
Member

zpao commented Mar 18, 2014

Oh and the license header says "undefined" :/

@RReverser
Copy link
Contributor Author

Let me look into license header problem. Regarding comments - we could use recast for saving them in dev version, but ideally I rather want to work on enabling source maps through entire build process (they are lost now due to few plugins that don't support them).

@RReverser
Copy link
Contributor Author

License header fixed by #1267.
And let me know what you think about [built dev version with comments] vs [source maps to real original files].

@zpao
Copy link
Member

zpao commented Mar 18, 2014

That solves part of the problem. We can't ship a file without a license header and the non-min builds don't include the apache stuff. I will fix this.

BUT The other big concern and is actually a dealbreaker - grunt build run twice in a row creates different files. The size compare shows random +/- (not consistently the same files). I can't have this in releases. If I checkout a release branch with the same versions of all files, I should be able to generate the exact same build.

That's what I meant when I said this:

One problem with browserify early on was that require path building was async and resulting in the build file being nondeterministic

@RReverser
Copy link
Contributor Author

That solves part of the problem. We can't ship a file without a license header and the non-min builds don't include the apache stuff. I will fix this.

For me changing license texts to different ones just didn't seem to be part of scope of this task.

That's what I meant when I said this

Got it. But could you reproduce it with pure-cjs? I'm actually persisting ids exactly for saving order in https://github.com/RReverser/pure-cjs/blob/master/lib/replacerMap.js#L15-L22, ideally random reordering should never happen here (and I can't reproduce it locally, at least sizes are always the same).

@zpao
Copy link
Member

zpao commented Mar 18, 2014

Ah, well when you removed the license header from all of the parts, we need to add it to the whole.

I'm reproducing with master right now. This is a diff between 2 runs. https://gist.github.com/zpao/9625952

@RReverser
Copy link
Contributor Author

Ah, well when you removed the license header from all of the parts, we need to add it to the whole.

Ah, so you were talking about Apache headers... missed that in previous comment. That's right. From other point, it might be even better when you have one license comment for bundled file instead of a lot duplicates for every module function.

I'm reproducing with master right now. This is a diff between 2 runs.

Nice. (not really)

Should be easy to fix in dirty way, but just wondering - why is that critical for you? I mean, modules are working in the same way in any case.

@zpao
Copy link
Member

zpao commented Mar 18, 2014

If I checkout a release branch with the same versions of all files, I should be able to generate the exact same build.

@zpao
Copy link
Member

zpao commented Mar 18, 2014

I'm backing this out until the problem can be resolved. Sorry

@RReverser
Copy link
Contributor Author

If I checkout a release branch with the same versions of all files, I should be able to generate the exact same build.

Yeah, and that's what I'm wondering about - why is it critical to generate exactly same bundled file if it doesn't change any logic, only order of elements in array?

@zpao
Copy link
Member

zpao commented Mar 18, 2014

Because I want my life to be simple. When I build in a branch and get a different version of a file, is it because a change was introduced? Or did my build system change the way it worked? I don't want to diff and figure that out.

The other part of this (but building on simple) is ensuring that all files we distribute are identical. The file that ends up on bower, on the cdn, on cdnjs, in our starter kit, etc. If I build once and generate most of that and then happen to run the build again, I've just made a bunch of work for myself.

If somebody else checks out the branch and builds him/herself, and needs to track down a line number from an error but it's different from other people's, that's annoying.

So maybe that sounds silly to you but deterministic builds are currently a requirement for me.

@RReverser
Copy link
Contributor Author

So maybe that sounds silly to you

Now it doesn't. Don't worry, I just needed some explanations since head doesn't work that good in the evening :P

Working on that right now. Could you please not to revert it for now so I wouldn't have to do one more rebase tomorrow?

zpao added a commit that referenced this pull request Mar 18, 2014
This reverts commit 7987e6a, reversing
changes made to d88d479.
@zpao
Copy link
Member

zpao commented Mar 18, 2014

I'm shipping 0.10rc today so no. But you can do a fancy unrevert and we'll see what we can do for 0.11

@RReverser
Copy link
Contributor Author

Fixed in RReverser/react@b6519dd + RReverser/pure-cjs@5a1fe63. Are you still interested?

@RReverser RReverser deleted the pure-cjs branch March 19, 2014 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants