Hacker News new | past | comments | ask | show | jobs | submit login
Babili: An ES6+ aware minifier based on Babel (babeljs.io)
94 points by hzoo on Aug 30, 2016 | hide | past | favorite | 44 comments



It may just be a paranoid delusion, but I'm worried that Babel is trying to become a more encompassing build tool ala Grunt/Gulp instead of just transpiling. I love Babel and plan to continue to use it in the future for my front-end development, but the "doing it all ourselves" is a little bit much.

I would much rather see a recommendation and efforts around Uglify than a brand new minimization tool, and I would rather see work on acorn[1] rather than around a new parser[2], because these things fragment the community rather than bring them together.

Edit: Yes, Uglify has taken a long time to get work done on ES2015, but note that the spec has changed a lot over that time. It does feel like they are dragging their feet or not getting much done in that front, but all the more reason to put one of the Babel devs who may have more free time on the project to get more things going.

1: https://github.com/marijnh/acorn

2: https://github.com/babel/babylon


We're not losing focus. Babel is as focused as ever on being a general purpose parser, transformer, and code generator. Babili is a set of Babel transforms.

Uglify has its own parser and transformer and generator, so arguably any work that goes into that is duplicate work because Babel already covers most of what it does.

Re parsers: we had to fork acorn because they were understandably skeptical of adding all the experimental and non-standard features (JSX and flow types) that Babel supports.

I started this project at Facebook and one of our aims (which is mentioned in the post) was to have access to the original source AST which may include Flow type annotations, JSX and early ES proposal features. Have I spent the time trying to get those into uglify, the majority of the work would've went into parsing and code generation. And I would imagine an uphill battle with the maintainers convincing them of adding non-standard features.


> Uglify has its own parser and transformer and generator, so arguably any work that goes into that is duplicate work because Babel already covers most of what it does.

That seems a little hubristic... Not everyone uses Babel, and working with the Uglify devs to get it ES2015+ compliant (through whatever means, including adding a different AST parser) would make the entire community better, not just Babel. Since not all browsers support ES2015, I have to use babel, but if I didn't need to use Babel, I wouldn't. But now I'm kind of forced to for uglification now until ES2015 support comes to Uglify.

> Re parsers: we had to fork acorn because they were understandably skeptical of adding all the experimental and non-standard features (JSX and flow types) that Babel supports.

JSX and Flow are not part of ES spec. I can understand those being in a different parser, but that's a flimsy argument for creating a whole new parser. If you had to create a brand new parser to handle this, it seems like a Babel issue, not a parser issue.


>That seems a little hubristic... Not everyone uses Babel, and working with the Uglify devs to get it ES2015+ compliant (through whatever means, including adding a different AST parser) would make the entire community better, not just Babel. Since not all browsers support ES2015, I have to use babel, but if I didn't need to use Babel, I wouldn't. But now I'm kind of forced to for uglification now until ES2015 support comes to Uglify.

Again, this project started at Facebook and we were scratching our own itch (and the React/Babel community's itch). So our target audience is already people using Babel.

You're committing the fallacy of thinking about this as an opportunity cost. But the upside for us in modernizing uglify while Babel exists is so little to make it worth it.

>but that's a flimsy argument for creating a whole new parser. If you had to create a brand new parser to handle this, it seems like a Babel issue, not a parser issue.

I'm going to go ahead and assume that you never worked on a parser before. Pluggable parsers is a really hard problem. And none of the existing parsers have support for it. At facebook we supported an esprima fork for years because they wouldn't accept our JSX/Flow patches. If I'm wrong then put your code where your mouth is and benefit the community by creating the first ever generalized pluggable parser.


Not sure why you're being down voted, your comment is fine I think.

What's worse than having specific parsers, transformers, and generators – I think – is not having an AST standard. If there was a common standard for ES ASTs, including extension points, then it becomes a lot easier to write tools that aren't specific to a tool chain but specific to a data structure. I could use the Babylon parser, but do transforms with Rollup and optimizations with Uglify (obviously provided those tools had APIs that take/return ASTs.)

As it stands, there's a varying degree of lock-in when using these tools, making them more difficult to compose. That's a shame I think.


You're right -- it would be nice to have a standard AST for ES, which is what you have in languages like Python, so that tools can be built around it more easily and without lock-in. This would also help accomplish my idea of helping the community rather than one tech specifically. I saw some other comment that mentioned ESTree but I guess that didn't go anywhere... sucks.


It's not a whole/brand new parser though. It's mostly acorn + JSX/Flow/everything experimental that wouldn't be in acorn anyway (until stage 4) for Babel.


Uglify has had many years to at least attempt to minify ES2015+. They just haven't—it's still an "experimental" branch in their repo: https://github.com/mishoo/UglifyJS2/issues/448

I agree with your comment, but at some point, devs will get impatient.


All the effort put into Babili could have gone into that branch though, either through feature implementation or polishing so it's production ready.

It's a wrong assumption to make that free software can only be developed centrally by a project owner.


This is one of the cases where starting from scratch is probably the better choice. Uglify probably hasn't come near a stable because of the codebase in the first place.


At least when it comes to parsers, it makes sense for Babel to want to be "in control" of their destiny here. Its really hard to draw a line between transpiling and parsing, especially when many of the features you are implementing require new syntax. Not having your own parser can make this more difficult (especially considering how unfortunately most "production ready" parsers end up being hand rolled so don't really easily allow "plugins" or "composition" to easily add new syntax). As babel may aim to implement experimental features that may never actually be added to JavaScript, it would be understandable that that may be considered a low priority for a standalone JavaScript parser project while high priority for a transpiling project.


But my point still stands -- why don't they just work with the acorn developers to get specific features rather than build their own?


I would like that too! I don't think there have been any features added since the last one with Babel 6 release.

Yeah there's multiple JavaScript parsers: esprima, acorn, shift, babylon (uglify has their own parser I think).

There was an effort to standardize as well in https://github.com/estree/estree.

EDIT:

However, in Babel 6 there were a few (nice) incompatible changes to the AST which was unfortunate for interop and other tools (https://github.com/babel/babel-eslint had to make a lot of changes).

I don't want to speak for him, but I think a lot of the decisions to fork (parser, etc) at the time were most likely made like mentioned above to move faster. And at the time, Sebastian was basically the only one working on it. Maybe more context from his post: https://medium.com/@sebmck/2015-in-review-51ac7035e272#.qcyz...


acorn is an ECMAScript parse library that emits a JSON parse tree. It does its job very well, but doesn't do anything else.


Yes, I hate it when projects do this. Along with senseless forking, trying to solve too many problems(especially ones that are already solved) is one of the worst things that can happen to a piece of software.


There is currently a discussion going on about changing the name back to babel-minify (you can vote)

https://github.com/babel/babili/issues/124


Competition is great. The more minifiers the better.

At a usability level, babili has a 33M install footprint and must be installed locally in the directory in which you intend to use it.

uglify-js can be installed globally and has a 1.9M install size.

And I've never understood how to configure babel's preset and plugin files. Why is it necessary for a minifier to do this? Surely this can be greatly simplified.


Long live Babel 5.8!

babel@5.8 is faster than babel 6+, can be installed globally and works out of the box. It just... you know, does what versions 1, 2, 3 & 4 did: compile ES2015 into ES5. So I just use that. Not every project is a "node" project that is already dumping megabytes of dependencies into the project directory. I don't want to have to buy into an entire ecosystem just to use one tool—a shim, at that.


I gave up and wrote my own babel cli front end (sudo npm install -g better-babel-cli) for that very reason.

babel --es2015 --babeli infile.js -o outfile.js.


I tried another ES6 to ES5 compiler - buble. But it's too buggy to use right now. I'll revisit it in a year.

https://gitlab.com/Rich-Harris/buble


The way the minifier is currently implemented is just as a babel preset. We figured users would want to use the tool standalone without babel and the simpliest thing we thought of was to wraps babel-cli and pass in the preset.

https://github.com/babel/babili/blob/master/packages/babili/...

I was thinking about using bundledDependencies or maybe just running webpack/rollup over the whole thing, feel free to make an issue.


> We figured users would want to use the tool standalone without babel and the simpliest thing we thought of was to wraps babel-cli and pass in the preset.

With all the other minifiers out there the only real draw here is you're already using babel so toss the minifier at it. If anyone, other than for the novelty of it being new, actually downloads babel ONLY to use the minifier I will eat my hat.


ES6 support is another reason why. And also, once we start doing advanced optimizations you might want to marinate that hat in some nice sauce.


> ES6 support is another reason why.

Most will be transpiling that ES6 into ES5 so support isn't that necessary.

> And also, once we start doing advanced optimizations you might want to marinate that hat in some nice sauce.

Better optimizations than Google Closure and / or Uglifier? Color me skeptical and good luck :)


`npm install babili` is 33M. Should users know or care what a babel preset is? They just want to minify code.


Maybe I didn't word that correctly. It was created as a set of babel plugins but because like you said users shouldn't know what a babel preset is we have the cli tool which acts the same as babel-cli so you don't need to do all of that.

Yes, it doesn't need to be 33M that's just a result of the way it was used (babel-cli is that big) and I'm saying that it's something that we can fix


Any plans to release minified versions of babili? It would probably shave 90% off the install size.


Having readable backtraces when something goes wrong is far more valuable to me than saving a couple dozen MB on a 512GB drive.


Edit: maybe there is some confusion. I'm talking about minifying the tooling, not end user code.


The tools should be minified to reduce their download size and make them run faster (quicker parsing).


Then no one would ever minify. Minify makes it faster to download and install (even in some cases it can make the code faster due to some optimizations though I wouldn't bank on it). You minify deployments and, if someone needs to debug, switch to a debug version of the code.


I had a lot of gotchas with babel too, until I realized one thing, that should be featured prominently in every bug-tracker having anything to do with babel:

Babel will look for a .babelrc in the current directory of the file being transpiled. If one does not exist, it will travel up the directory tree until it finds either a .babelrc, or a package.json with a "babel": {} hash within.

- https://babeljs.io/docs/usage/babelrc/

So if you have stray files lying around, they might break your build.


The preset situation has gotten a lot better now.. Most use cases are handled by a small .babelrc file with the latest preset applied (possibly also 'react' if you're doing that sort of thing).

Babili has a single preset too, so it's also really easy to add. And, because it's using the same parse tree from your transpilation step, it doesn't add a ton of overhead to run it.


Interesting, but the only 'Pro' I can actually see here is ES6 support when you were previously using uglify. I think using Closure Compiler on TypeScript output with the right JSDoc comments can yield much better results as there is much more information the minifier can work with.


One of our future plans is to use type annotations (Flow, but maybe typescript too) to do advanced optimozations.


Can this yield smaller bundles?


I've been seeing incredibly compressible output from Typescript, if that helps any. If what you mean by 'bundle' are these 'webpack' things that include css and images, and all that. Smaller bundle to me would be not to use one at all.

It doesn't seem like webpack's chief concern is file size or simplicity. So if yours is, just don't use it.


What has this to do with TypeScript?


Can babili or babel parse TS?


Babel can parse Flow, which is similar to Typescript. However, Babel doesn't have any built-in support for inferring or analyzing flow types. However, some of this type information might be useful in building a more advanced closure-like minifier.


You don't need Babel or a build process to minify ES6. Pretty Diff has supported this for years http://prettydiff.com/?m=minify


That doesn't appear to replace variable names with shorter versions, or remove dead code, which Uglify and other minifiers do.


Ah, are they going to make a minifier based on Bublé (https://buble.surge.sh/), too? Perhaps they could call it Bublili.





Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: