We treat the technologies we use as shopping on the Yandex Market. We look at the specification, read the reviews and, if the project received a lot of stars on the githaba, it passes according to the specification, and also introduction is inexpensive, we have it we buy install. Such an approach sometimes beats the rake very hard on the head, and then you still have to figure out what is happening.
In an article by one of the authors of the rollup , two optimizations are considered, one is called dead code elimination , and the second is tree-shaking . The author shows that tree-shaking has a lot more code compression capabilities. And as proof, he gives several considerations about the recipes of the cake and the broken eggs. Oh, those metaphors!
This idea (about tree-shaking, not about cake and eggs) was picked up by the webpack development team and from version 2.0 it began to officially support.
I would not write if the technology on real projects brought at least some result. In practice, the dimensions of the final assembly either do not decrease at all or are reduced by the size of the statistical error.
Some, of course, guess about the trick and even write articles on Habr . But lovers to speculate about the benefits of tree-shaking over the dead code illumination in a webpack around do not get less, at least among conference visitors and among my colleagues.
The idea is as simple as a tank .
... /* unused harmony export square */ function square(x) { return x * x;} ...
Suppose we have everything in the documentation. Two files index.js and module.js
// index.js import {cube} from './module' console.log(cube(x))
// module.js export function square(x) { return x * x; } export function cube(x) { return x * x * x; }
If we now launch the webpack in optimization and minimization mode, then everything will work as expected. ( code )
webpack --optimize-minimize index.js out.js
But if only any, even the smallest export class with a babel-loader is added to the module file, write to it. The class will fall into the final assembly as a function that the babel spat out. ( code )
//module.js export function square(x) { return x * x; } export function cube(x) { return x * x * x; } export class MyClass { print(){ console.log('find me'); } }
The thing is that UglifyJS is afraid to throw out something extra. It is understandable: let it be better for a couple of hundred bytes more, if only it would not break.
And so, imagine that UglifyJS receives the following code as input:
/* unused harmony export MyClass */ var MyClass = function () { function MyClass() { babelHelpers.classCallCheck(this, MyClass); } MyClass.prototype.turn = function print() { console.log('find me'); }; return MyClass; }();
MyClass, after compiling babel, somehow got out of recognizing itself as a class. And in general, UglifyJS knows little about how the babel team sees the implementation of classes on ES5. So he succumbs, leaving this unknown unthinkable disgrace in your final assembly.
There is even a bug in the webpack repository, and the guys promise to fix everything in version 4 .
Rollup, by the way, not so long ago also worked only on examples with mathematics, but in recent versions the guys fixed a bug. ( broken example , working example ).
So, having bought a webpack, including for tree-shaking, I got a near-zero benefit in this direction. And the word tree-shaking now makes me nervous laugh, hiccups and uncontrollable sarcasm.
To begin with, drop the webpack and use my fundamentally new assembler , which is devoid of both these flaws and many others. In addition to the classic assembly, he brews craft beer and prepares burgers on ciabatta.
Sorry, could not resist.
But seriously, there is a very simple way to fix the situation:
you need the webpack to add a special directive /*#__PURE__*/
, which would tell UglifyJS that this unknown monster as a function can be cut to itself.
Oh, these crutches.
And it looks something like this:
/* unused harmony export MyClass */ var MyClass = /*#__PURE__*/ function () { function MyClass() { babelHelpers.classCallCheck(this, MyClass); } MyClass.prototype.turn = function print() { console.log('find me'); }; return MyClass; }();
Just a couple of iterations and we will invent static typing;)
By the way, the new version of babel 7 is already doing this. Unfortunately, it is still in beta, which seems to hint at the impossibility of use right now. But if you are brave and decisive, you can try to upgrade.
Looking ahead, I will say that there are several solutions that are working right now. I will tell about them in the following article. Perhaps someone will save their nerves and time. And we have to go to the conclusions.
PS Write in the comments if you, too, came across the tricks of marketers and chose fashionable technology instead of solving problems.
Source: https://habr.com/ru/post/342686/
All Articles