babel / minify Goto Github PK
View Code? Open in Web Editor NEW:scissors: An ES6+ aware minifier based on the Babel toolchain (beta)
Home Page: https://babeljs.io/repl
License: MIT License
:scissors: An ES6+ aware minifier based on the Babel toolchain (beta)
Home Page: https://babeljs.io/repl
License: MIT License
As you can see in the REPL, running babili on
function outer() {
const inner = (d) => d.x;
return inner;
}
produces
"use strict";function outer(){return function(a)a.x}
Which causes an Unexpected identifier
error because of function(a)a.x
.
const outer = () => {
const inner = (d) => d.x;
return inner;
}
Change it back to babel-minify
? Ref #8
Given that it's just a preset + plugins it makes sense to just be babel-minify
so everyone understands what it is and we don't have issues trying to explain it or it's pronunciation.
And after talking with people about it (what's that?), I refer to it as the babel minifier anyway. Haven't met many people that liked the name ๐ .
cli: babili
preset: babel-preset-babili
cli: babel-minify
preset: babel-preset-minify
Message from @thejameskyle:
Since I can already tell this thread will blow up:
Please ensure that any comment you are making on this thread is actively contributing to the discussion of a name change. Please do not go on tangents, please be respectful of others (follow the Babel CoC), and don't just keep repeating something that has been said. Be aware of strawman arguments and other logical fallacies and don't do them. Dont assert your own opinions/experiences as the opinions and experiences of the entire community. Yada yada yada be constructive, be aware, don't be mean.
The following:
(function() {
for (let x in y) y[x];
f(() => { g() });
})();
function g() {}
mangles to:
function i() {}
function() {
for (var i in y) y[i];
f(function() {
i()
})
}()
The i
var is conflicting.
Seems like it should
Would be nice to have an online version available such as https://closure-compiler.appspot.com/
Every feature we add adds uncertainty and potential regressions. Therefore, in order to get to a beta release, we need to stop adding any more features and focus instead on testing.
Here are ways you can help:
When trying to use the CLI version:
node_modules\.bin\babili.cmd -d .
internal/child_process.js:298
throw errnoException(err, 'spawn');
^
Error: spawn UNKNOWN
at exports._errnoException (util.js:856:11)
at ChildProcess.spawn (internal/child_process.js:298:11)
at Object.exports.spawn (child_process.js:367:9)
at Object.<anonymous> (C:\temp\babilitest\node_modules\babili\lib\index.js:16:25)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
Windows 10, Node v5.7.1 (I should probably upgrade Node, guess)
As you can see in the REPL
function foo() {
function getX(o){ return o.x; }
const obj = {
getter: getX
};
return obj
}
is transformed to
"use strict";function foo(){return{getter:function getter(b){return b.x}}}
The returned function should retain its original name (getX
in this case) not take on the name of the property (getter
here).
This appears to work as expected outside of a function.
Since this function is pretty generic I'm wondering if we should just put it in babel-types
?
Some plugins have options already but they aren't documented in both the readme and the top level readme
babel-plugin-minify-dead-code-elimination
: optimizeRawSize
babel-plugin-minify-mangle-names
: mangleBlacklist
babel-plugin-minify-replace
: replacements
I'm starting to implement these things. Should this be in dce or simplify ?
a === b ? true : false
a < b ? false : true
a() ? false : true
b() ? true : false
a ? b : true
a ? b : false
// out:
x === y
!(a < b)
!a()
!!b()
!a || b
!!a && b
Looks like it's blocked by babel-generator?
There is a bug in babel in printing this. Disabling for now.
(function() {})() -> !function() {}()
๐ - getting this setup with a reasonably sized production React app using Flow. All our babel versions are up-to-date.
Ran into this error, which traces back to:
Error is thrown from the entry point of the app:
/* @flow */
import React, { Component } from 'react'
import { Provider } from 'react-redux'
import { IntlProvider } from 'react-intl'
import routes from './routes'
import store from './store'
export default class App extends Component {
static displayName = 'App';
render() {
return (
<IntlProvider locale="en">
<Provider store={store}>
{routes}
</Provider>
</IntlProvider>
)
}
}
Stacktrace:
ModuleBuildError: Module build failed: TypeError: /Users/brendan/src/app/src/app.js: Cannot read property 'scope' of undefined
at ReferencedIdentifier (/Users/brendan/src/app/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js:341:37)
at newFn (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/visitors.js:318:17)
at NodePath._call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:76:18)
at NodePath.call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:48:17)
at NodePath.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:105:12)
at TraversalContext.visitQueue (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitSingle (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:108:19)
at TraversalContext.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:192:19)
at Function.traverse.node (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:161:17)
at traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:83:12)
at NodePath.traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/index.js:144:25)
at /Users/brendan/src/app/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js:331:35
at _loop3 (/Users/brendan/src/app/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js:396:16)
at Object.enter (/Users/brendan/src/app/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js:404:23)
at Object.newFn (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/visitors.js:318:17)
at NodePath._call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:76:18)
at NodePath.call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:48:17)
at NodePath.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:105:12)
at TraversalContext.visitQueue (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitSingle (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:108:19)
at TraversalContext.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:192:19)
at Function.traverse.node (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:161:17)
at NodePath.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:115:19)
at TraversalContext.visitQueue (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitMultiple (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:103:17)
at TraversalContext.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:190:19)
at Function.traverse.node (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:161:17)
at traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:83:12)
at NodePath.traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/index.js:144:25)
at PluginPass.Program (/Users/brendan/src/app/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js:769:14)
at /Users/brendan/src/app/node_modules/webpack/lib/NormalModule.js:138:20
at /Users/brendan/src/app/node_modules/loader-runner/lib/LoaderRunner.js:328:11
at /Users/brendan/src/app/node_modules/loader-runner/lib/LoaderRunner.js:201:18
at runSyncOrAsync (/Users/brendan/src/app/node_modules/loader-runner/lib/LoaderRunner.js:114:3)
at iterateNormalLoaders (/Users/brendan/src/app/node_modules/loader-runner/lib/LoaderRunner.js:200:2)
at /Users/brendan/src/app/node_modules/loader-runner/lib/LoaderRunner.js:173:4
at Storage.finished (/Users/brendan/src/app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:39:16)
at /Users/brendan/src/app/node_modules/graceful-fs/graceful-fs.js:78:16
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:404:3)
.babelrc
:
{
"presets": ["es2015", "react"],
"plugins": [
"array-includes",
"syntax-class-properties",
"transform-class-properties",
"transform-flow-strip-types",
"transform-object-rest-spread",
"transform-react-inline-elements",
"transform-react-pure-class-to-function",
"transform-react-remove-prop-types"
],
"env": {
"production": {
"presets": ["babili"],
"plugins": [
"transform-runtime"
]
},
"development": {
"plugins": [
"transform-runtime",
["react-transform", {
"transforms": [{
"transform": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}, {
"transform": "react-transform-catch-errors",
"imports": ["react", "redbox-react"]
}]
}]
]
},
"test": {
"plugins": [
["transform-runtime", { "polyfill": false }]
]
}
}
}
Possibly related to these warnings, which only appear with babili turned on:
You or one of the Babel plugins you are using are using Flow declarations as bindings.
Support for this will be removed in version 6.8. To find out the caller, grep for this
message and change it to a `console.trace()`.
Ran with console.trace()
:
ModuleBuildError: Module build failed: TypeError: /Users/brendan/src/app/src/app.js: Cannot read property 'scope' of undefined
at ReferencedIdentifier (/Users/brendan/src/app/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js:341:37)
at newFn (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/visitors.js:318:17)
at NodePath._call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:76:18)
at NodePath.call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:48:17)
at NodePath.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:105:12)
at TraversalContext.visitQueue (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitSingle (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:108:19)
at TraversalContext.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:192:19)
at Function.traverse.node (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:161:17)
at traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:83:12)
at NodePath.traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/index.js:144:25)
at /Users/brendan/src/app/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js:331:35
at _loop3 (/Users/brendan/src/app/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js:396:16)
at Object.enter (/Users/brendan/src/app/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js:404:23)
at Object.newFn (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/visitors.js:318:17)
at NodePath._call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:76:18)
at NodePath.call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:48:17)
at NodePath.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:105:12)
at TraversalContext.visitQueue (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitSingle (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:108:19)
at TraversalContext.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:192:19)
at Function.traverse.node (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:161:17)
at NodePath.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:115:19)
at TraversalContext.visitQueue (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitMultiple (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:103:17)
at TraversalContext.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:190:19)
at Function.traverse.node (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:161:17)
at traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:83:12)
at NodePath.traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/index.js:144:25)
at PluginPass.Program (/Users/brendan/src/app/node_modules/babel-plugin-minify-dead-code-elimination/lib/index.js:769:14)
I tried implementing each plugin one-by-one, I get a similar error for babel-plugin-minify-constant-folding
:
ModuleBuildError: Module build failed: TypeError: /Users/brendan/src/app/src/app.js: Cannot read property 'node' of undefined
at Mangler.renameNew (/Users/brendan/src/app/node_modules/babel-plugin-minify-mangle-names/lib/index.js:188:26)
at /Users/brendan/src/app/node_modules/babel-plugin-minify-mangle-names/lib/index.js:143:23
at Array.map (native)
at Scopable (/Users/brendan/src/app/node_modules/babel-plugin-minify-mangle-names/lib/index.js:135:16)
at NodePath._call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:76:18)
at NodePath.call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:48:17)
at NodePath.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:105:12)
at TraversalContext.visitQueue (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitSingle (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:108:19)
at TraversalContext.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:192:19)
at Function.traverse.node (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:161:17)
at NodePath.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:115:19)
at TraversalContext.visitQueue (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitMultiple (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:103:17)
at TraversalContext.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:190:19)
at Function.traverse.node (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:161:17)
at traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:83:12)
at NodePath.traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/index.js:144:25)
at Mangler.mangle (/Users/brendan/src/app/node_modules/babel-plugin-minify-mangle-names/lib/index.js:100:22)
at Mangler.run (/Users/brendan/src/app/node_modules/babel-plugin-minify-mangle-names/lib/index.js:45:14)
at PluginPass.Program (/Users/brendan/src/app/node_modules/babel-plugin-minify-mangle-names/lib/index.js:263:17)
at newFn (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/visitors.js:276:21)
at NodePath._call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:76:18)
at NodePath.call (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:48:17)
at NodePath.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:105:12)
at TraversalContext.visitQueue (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitSingle (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:108:19)
at TraversalContext.visit (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/context.js:192:19)
at Function.traverse.node (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:161:17)
at traverse (/Users/brendan/src/app/node_modules/babel-core/node_modules/babel-traverse/lib/index.js:83:12)
at /Users/brendan/src/app/node_modules/webpack/lib/NormalModule.js:138:20
at /Users/brendan/src/app/node_modules/loader-runner/lib/LoaderRunner.js:328:11
at /Users/brendan/src/app/node_modules/loader-runner/lib/LoaderRunner.js:201:18
at runSyncOrAsync (/Users/brendan/src/app/node_modules/loader-runner/lib/LoaderRunner.js:114:3)
at iterateNormalLoaders (/Users/brendan/src/app/node_modules/loader-runner/lib/LoaderRunner.js:200:2)
at /Users/brendan/src/app/node_modules/loader-runner/lib/LoaderRunner.js:173:4
at Storage.finished (/Users/brendan/src/app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:39:16)
at /Users/brendan/src/app/node_modules/graceful-fs/graceful-fs.js:78:16
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:404:3)
But with the following config (the preset minus the two plugins that cause issues), everything works well:
"plugins": [
"transform-runtime",
"babel-plugin-transform-undefined-to-void",
"babel-plugin-transform-simplify-comparison-operators",
"babel-plugin-transform-property-literals",
"babel-plugin-transform-minify-booleans",
"babel-plugin-transform-merge-sibling-variables",
"babel-plugin-transform-member-expression-literals",
"babel-plugin-minify-type-constructors",
"babel-plugin-minify-simplify",
"babel-plugin-minify-replace",
"babel-plugin-minify-infinity",
"babel-plugin-minify-guarded-expressions",
"babel-plugin-minify-flip-comparisons",
"babel-plugin-minify-constant-folding"
]
Would be great to fix right pronunciation of 'babili' at the beginning.
So, seems like it's esperanto word (chat), in this case stress on the second syllable. Like in Spanish: https://translate.google.ru/?source=osdd#es/en/babili
If the babili's Makers have their own version, talk now please! :)
INPUT:
(function() {
var B = class A {
constructor(x) {
console.log(x);
}
}
self.addEventListener(function (event) {
new B(event);
})
})();
OUTPUT
"use strict";
(function () {
var B = void 0;
self.addEventListener(function (event) {
new B(event);
});
})();
I think if we aren't going to split each little thing into a plugin (overkill), we can just setup options for the smaller stuff in the packages?
We could also separate those out into different sections or files although maybe being in the same file is good too?
Oh I see we have a few options in some of the plugins already
bar
in function foo(bar) { }
)return
when possible (e.g. return [1,2,3]
โ return[1,2,3]
)var result = expression(); foo.bar = result;
โ foo.bar = expression()
var b = () => {
var x = 14;
var y = 7 - x / 2;
return y * (28 / x + 2);
};
var a = () => {
var a = 14;
return (7 - a / 2) * (28 / a + 2);
};
Input:
function isTextInputElement(elem) {
if (!elem) {
return false;
}
if (elem.nodeName === 'INPUT') {
return !!supportedInputTypes[elem.type];
}
if (elem.nodeName === 'TEXTAREA') {
return true;
}
return false;
}
GCC Output:
function(a){return a?"INPUT"===a.nodeName?!!supportedInputTypes[a.type]:"TEXTAREA"===a.nodeName?!0:!1:!1}
Two things to be noted:
if (a === b) { return true; } return false;
is outputted as a === b ? !0 : !1
which can be simplified as a === b
, no need to do the condition.return !(a?"INPUT"===a.nodeName?!supportedInputTypes[a.type]:"TEXTAREA"===a.nodeName?0:1:1)
Since it is a preset, there won't be any options passed to the minifier.
for example,
!==
to !=
, >=
to <
etc...
How to support these as options to be passed to the minifier - when used as a CLI or a Preset?
Are we planning on keeping the babel-minify
name? Might be better to have a distinct name for it so it can be marketed better. Being separate from the Babel brand, regardless of if it's in the org might be better too since Babel has historically had the stigma of trying to be everything at once.
The preset or cli or node api when used with previous versions of babel, due to the rename bugs and evaluate bugs, we will be introducing bugs in user code that will be hard to grok that it is a bug with babel. We need to either fix this somehow for mangle and evaluate in the minifier or set hard dependency that it bails out for older versions of babel.
INPUT
(function (require, module, exports) {
var Hub = function Hub(file, options) {
(0, _classCallCheck3.default)(this, Hub);
};
module.exports = Hub;
})(require, module, exports);
OUTPUT
(function (require, module, exports) {
module.exports = function (file, options) {
(0, _classCallCheck3.default)(this, Hub);
};
})(require, module, exports);
There's a lot of one-off transformations inside the simplify plugin that don't necessarily need to be grouped together.
If they were split up into a bunch of separate plugins, each individual transformation would likely be much easier to follow and would make contributions easier.
Found this bug when I tried minifying babel with babel-minify.
Difference between actual function and minified one: https://jsbin.com/nepoya/1/edit?js,console
Ref #33 (comment)
The benchmarks are cool, but we could reduce the size and find out we are breaking the functionality (especially for the dead code elimination plugin).
So we could be running the unit tests of the project on the minified code?
As the title says, is it worth it? Could my app become smaller if I minify twice?
I'm seeing the above error when I have lots of nested if/else's with the occasional empty block.
Stack trace if it's useful
Error: test.js: Unexpected UnaryExpression. Expected an Identifier
at Mangler.renameNew (foo/node_modules/babel-plugin-minify-mangle-names/lib/index.js:193:19)
at foo/node_modules/babel-plugin-minify-mangle-names/lib/index.js:143:23
at Array.map (native)
at Scopable (foo/node_modules/babel-plugin-minify-mangle-names/lib/index.js:135:16)
at NodePath._call (foo/node_modules/babel-traverse/lib/path/context.js:76:18)
at NodePath.call (foo/node_modules/babel-traverse/lib/path/context.js:48:17)
at NodePath.visit (foo/node_modules/babel-traverse/lib/path/context.js:105:12)
at TraversalContext.visitQueue (foo/node_modules/babel-traverse/lib/context.js:150:16)
at TraversalContext.visitMultiple (foo/node_modules/babel-traverse/lib/context.js:103:17)
at TraversalContext.visit (foo/node_modules/babel-traverse/lib/context.js:190:19)
Minimum example I could come up with (repl)
function foo() {
var a, b, c;
if (a) {
if (b) {
if (c) {}
}
} else {
if (b) {
} else {
if (c) {}
}
}
}
Seems to be coming from the interaction of minify-dead-code-elimination
and minify-mangle-names
(both seem fine individually but fail when used together)
Error's being thrown here which suggests it might be an upstream Babel bug?
I have errors like these when building with babel-preset-babili
:
ERROR in ./src/redux/sagas/landing-menu.js
Module build failed: SyntaxError: The keyword 'yield' is reserved (1:2367)
at Parser.pp.raise (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:1745:13)
at Parser.pp.parseIdent (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:1464:240)
at Parser.pp.parseExprAtom (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:1090:21)
at Parser.pp.parseExprSubscripts (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:1023:19)
at Parser.pp.parseMaybeUnary (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:1004:19)
at Parser.pp.parseExprOps (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:948:19)
at Parser.pp.parseMaybeConditional (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:930:19)
at Parser.pp.parseMaybeAssign (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:908:19)
at Parser.pp.parseVar (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:2743:24)
at Parser.pp.parseVarStatement (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:2637:8)
at Parser.pp.parseStatement (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:2437:19)
at Parser.pp.parseBlock (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:2692:21)
at Parser.pp.parseFunctionBody (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:1413:22)
at Parser.pp.parseFunction (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:2770:8)
at Parser.pp.parseFunctionStatement (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:2540:15)
at Parser.pp.parseStatement (PROJECT_FOLDER/node_modules/acorn/dist/acorn.js:2420:19)
@ ./src/redux/sagas/index.js 1:285-310
My .babelrc
:
{
"presets": [ "es2015", "stage-1", "react" ],
"plugins": [
"transform-runtime",
"transform-decorators-legacy"
],
"env": {
"production": {
"presets": ["babili"],
"plugins": [
"transform-react-inline-elements",
"transform-react-constant-elements"
]
}
}
}
It's weird that the style is single quote but then in babel/babylon/lerna it's double quote (among other things)
I am using react-markdown which uses commonmark. When compiling the code with babili it breaks in some crazy way. It leads to an endless loop for both NodeJS and Chrome.
I am still investigating to narrow this down a little more.
Just wondering: Is there some special utf-8/unicode related functionality in babili?
Why is foo(emptyFunction('how long', '?'));
minified to foo(false)
?
Is this test not final/functional? https://github.com/amasad/babel-minify/blob/0a37687f01fefeacace653d7537e132b386b79f3/packages/babel-plugin-minify-empty-function/__tests__/empty-function-test.js#L12
And where does this emptyFunction
come from? It looks like it's noop
inserted by other plugins, but its usage might be confusing for direct users.
can't we just make the
babel-minify
executable achild.process
that calls out to thebabel
CLI just with a--presets minify
argument appended?
After
The README has an implicit requirement of only targeting new-enough browsers, but doesn't explicitly say what those browsers are (or what features are needed).
When it's possible to only target browsers that support newer ES features, code sizes can be smaller because you don't have to transpile and then minify.
I looked through some of the rules and only found a single mention of IE8 being unsupported.
What people actually care about w.r.t. build times is usually the end-to-end time. Talking with @skevy, we were saying a typical production build pipeline will transpile and minify, which previously entailed running Babel (ex: with es2015 preset) and then Uglify. But now a pipeline could run just Babel (ex: with es2015 + babili).
The perf benchmarks currently make Uglify look way better than Babili to people who prefer 1.5-2x faster build times for roughly the same end result, but if the actual end-to-end build times that comprise transpilation and minification are faster, that'd change a lot of minds.
function method() {
var removeListeners = function removeListeners() {
log(removeListeners);
};
removeListeners();
}
becomes
function method(){(function(){log(removeListeners)})()}
It's this assignment: https://github.com/amasad/babel-minify/blob/892bfbad125fd2d90324e5a5c0c1f59224eb6110/packages/babel-plugin-minify-dead-code-elimination/src/index.js#L556
It should probably be isFunctionDeclaration
but we'll want to verify.
Just making a list of things that could be helpful to have.
C.f.: facebook/react#7323
We need to check that the npm packages are available.
I checked babel-preset-minify and it's not available: https://www.npmjs.com/package/babel-preset-minify but I think @jonathanong would probably agree to transfer.
Unpad produces different levels of pads on different systems.
Fails on travis - passes on osx - 34b4529
https://travis-ci.com/amasad/babel-minify/jobs/46515378#L231
Passes on travis - fails on osx - 1bfb693
var symbol = Symbol();
String(symbol);
// โ 'Symbol()'
var symbol = Symbol();
symbol+"";
// โ throws TypeError: Cannot convert a Symbol value to a string
if ( 0 ) {
var x = foo();
}
// or
if (0) var x = bar();
out:
var x;
This can either be done by hoisting vars for all functions before IfStatement is reached, or by analysing the pathToBeRemoved for var declarations.
I tried the latter approach here - https://github.com/boopathi/babel-minify/blob/0fbb45d18b13df53dd225dbd36ef0af88c7190ea/packages/babel-plugin-transform-conditionals/src/replace-with.js#L65-L88
It seems like comments: false
cannot passed from the preset nor the cli ๐
My installed packages:
"devDependencies": {
"babel-core": "^6.13.2",
"babel-loader": "^6.2.5",
"babel-plugin-transform-es2015-modules-commonjs": "^6.14.0",
"babel-preset-babili": "0.0.1",
"babili": "0.0.3",
"browserify-versionify": "^1.0.6",
"ify-loader": "^1.0.3",
"shader-loader": "^1.2.1",
"webpack": "^1.13.2",
"webpack-dev-server": "^1.14.1"
}
My babel loader config:
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: `babel`,
query: {
presets: [`babili`],
plugins: [`transform-es2015-modules-commonjs`]
}
}
Error upon running webpack-dev-server --inline --colors
:
ERROR in ./script.js
Module build failed: Error: Cannot find module 'babel-types'
at Function.Module._resolveFilename (module.js:325:15)
at Function.Module._load (module.js:276:25)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (/home/ubuntu/workspace/node_modules/babel-preset-babili/node_modules/babel-plugin-minify-mangle-names/lib/renamer.js:14:9)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
@ multi main
I explicitly installed babel-types, and now get this error upon re-running:
ERROR in ./script.js
Module build failed: Error: Plugin 0 specified in "foreign" provided an invalid property of "name"
at Plugin.init (/home/ubuntu/workspace/node_modules/babel-core/lib/transformation/plugin.js:138:13)
at Function.normalisePlugin (/home/ubuntu/workspace/node_modules/babel-core/lib/transformation/file/options/option-manager.js:147:12)
at /home/ubuntu/workspace/node_modules/babel-core/lib/transformation/file/options/option-manager.js:181:30
at Array.map (native)
at Function.normalisePlugins (/home/ubuntu/workspace/node_modules/babel-core/lib/transformation/file/options/option-manager.js:153:20)
at OptionManager.mergeOptions (/home/ubuntu/workspace/node_modules/babel-core/lib/transformation/file/options/option-manager.js:245:36)
at /home/ubuntu/workspace/node_modules/babel-core/lib/transformation/file/options/option-manager.js:289:14
at /home/ubuntu/workspace/node_modules/babel-core/lib/transformation/file/options/option-manager.js:342:20
at Array.map (native)
at OptionManager.resolvePresets (/home/ubuntu/workspace/node_modules/babel-core/lib/transformation/file/options/option-manager.js:305:20)
@ multi main
Might be a little less setup?
Something like (maybe need to split up or move arguments around):
Basically always unpad, trim
const babel = require("babel-core");
const unpad = require("utils/unpad");
export function transform(source, plugin, options) {
return babel.transform(unpad(source), {
plugins: [[plugin, options]],
}).code.trim();
}
export function expectTransform(source, expected, plugin, options = {}) {
return expect(transform(source, plugin, options)).toBe(unpad(expected));
}
This preset already seems to do a ton of what other toolchains offer in terms of DCE, mangling, etc. What about taking that last step and having it support merging a whole graph of ES Modules dependencies into a single closure? (Prior art here being perhaps Rollup)
TLDR:
(traverse + block-scoping) โ AST โ traverse.clearCache() โ (traverseFromAST + mangle) results in a naming conflict :)
The following code:
const babel = require('babel-core');
const traverse = require('babel-traverse').default;
const mangle = require('./packages/babel-plugin-minify-mangle-names/lib/index.js');
const srcTxt = `
function f(x) {
for (let i = 0; i; i++) {
let n;
if (n) return;
g(() => n);
}
}
`;
const ast = babel.transform(srcTxt, {
code: false,
plugins: ['transform-es2015-block-scoping'],
}).ast;
traverse.clearCache();
const code = babel.transformFromAst(ast, null, {
plugins: [mangle],
}).code;
console.log(code);
produces this output:
function f(a) {
var b = function (c) {
var b = void 0;
if (b) return {
v: void 0
};
g(() => b);
};
for (var c = 0; c; c++) {
var a = b(c);
if (typeof a === "object") return a.v;
}
}
Notice conflict between a
in arguments and a
in a loop block. Removing clearCache
fixes it BUT then mangling is incomplete:
function f(a) {
var _loop = function (b) {
var b = void 0;
if (b) return {
v: void 0
};
g(() => b);
};
for (var b = 0; b; b++) {
var _ret = _loop(b);
if (typeof _ret === "object") return _ret.v;
}
}
Are there situations that we might need multiple passes for better minification ?
For example, one plugin might transform
if (a) foo (x) : foo (y);
//to
a ? foo (x) : foo (y)
and another plugin might transform
//to
foo (a ? x : y);
// or even,
x ? foo(a) : foo(b)
//to
foo (x ? a : b)
and another one could remove this as pure expression statement. or modify it differently. I'm not able to think about it.
So the order of plugins in the preset will matter, and we say (with plugins- a and b) the order is a, b
, and another particular transformation might require the order to be b, a
. So, should we explore multiple passes. I'm not sure if this is a problem. Just asking if there are situations that you faced like this.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.