Babili: An ES6+ aware minifier based on Babel
babeljs.io
babeljs.io
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.
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.
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.
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.
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.
I agree with your comment, but at some point, devs will get impatient.
It's a wrong assumption to make that free software can only be developed centrally by a project owner.
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...
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.
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.
babel --es2015 --babeli infile.js -o outfile.js.
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.
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.
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 :)
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
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.
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.
It doesn't seem like webpack's chief concern is file size or simplicity. So if yours is, just don't use it.