Giter Club home page Giter Club logo

minify's Issues

Name change to babel-minify

Ok it's changed (pkgs should be updated as of 0.2.0)

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:

A couple notes before you comment in this thread

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.

Variable name collision in mangler

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.

Feature freeze / testing

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:

  • Try to integrate the minifier in your project
  • Find bugs and reduce them to test cases for a given package and send a PR
  • (If you can fix the bug with your PR but a test case is better than nothing)
  • Look at existing PRs and issues and either fix or add related test cases

"Error: spawn UNKNOWN"

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)

Incorrect function name for methods

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.

Finish documenting Plugin Options

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

Conditional Operator

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

ModuleBuildError: Module build failed: TypeError: Cannot read property 'scope' of undefined

๐Ÿ‘‹ - 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:

https://github.com/babel/babili/blob/master/packages/babel-plugin-minify-dead-code-elimination/src/index.js#L212

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"
      ]

[dce] named class expressions to void 0

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);
  });
})();

Plugin Options

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

More optimizations

  • Remove unused args (e.g. bar in function foo(bar) { })
  • Remove space after return when possible (e.g. return [1,2,3] โ†’ return[1,2,3])
  • var result = expression(); foo.bar = result; โ†’ foo.bar = expression()
  • Better constant propagation (looks like it is in the dead-code-elimination plugin, but its a combination of both)
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);
};

Sub-optimal boolean returns

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.
  • all the return values have ! in common, it is possible to factor it out. return !(a?"INPUT"===a.nodeName?!supportedInputTypes[a.type]:"TEXTAREA"===a.nodeName?0:1:1)

Minify options

Since it is a preset, there won't be any options passed to the minifier.

for example,

  • mangle topLevel names
  • mangle eval accessible bindings - don't deopt because of the presense of eval
  • apply unsafe optimizations like - !== to !=, >= to <
  • drop debugger & console statements or just one of them
  • preserve fn args and fn name for code depending on fn.length & fn.name

etc...

How to support these as options to be passed to the minifier - when used as a CLI or a Preset?

Name

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.

Set hard dependency on babel.version

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.

[dce] removes Fn name when it's used within the function

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);

Should simplify plugin be split into many plugins?

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.

Integration Tests

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?

Unexpected UnaryExpression. Expected an Identifier

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?

Failing build because of `yield` keyword

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"
      ]
    }
  }
}

eslint preset

It's weird that the style is single quote but then in babel/babylon/lerna it's double quote (among other things)

Compression breaks commonmark npm package

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?

Incorrect minify-empty-function?

Why is foo(emptyFunction('how long', '?')); minified to foo(false)?

https://github.com/amasad/babel-minify/blob/0a37687f01fefeacace653d7537e132b386b79f3/packages/babel-plugin-minify-empty-function/__tests__/empty-function-test.js#L37

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.

Before Alpha Release

  • move minification plugins out of babe/babel #33
  • wrap babel-cli #49
  • guide/how to use it #50
    • as a babel preset/plugin
    • using the cli standalone

can't we just make the babel-minify executable a child.process that calls out to the babel CLI just with a --presets minify argument appended?

  • reasoning, and how it works (explanation about how babel is a compiler and optimization is just another thing that it can do just like converting es2015, it should be faster since it's the same tool and can be run as part of your babel build)

  • make sure the names aren't taken: #8 #46
  • remove minify plugins from babel/babel babel/babel#3621 and transfer any updates #75
  • publish all packages as alpha, ask for testers/help
  • transfer repo to babel org, make public
  • Online demo/try it out: #28 (would be nice to turn on/off plugins individually, time to minify)

After

  • transfer relevant PRs to move to minify
  • add greenkeeper #74

Minimum browser support is unclear

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.

Add benchmarks that show transpilation + minification times

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.

Update Readme

Just making a list of things that could be helpful to have.

  • how to run tests, benchmarks
  • travis + build badge
  • maybe an example for each plugin - #5

Webpack Issues

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

Move some testing helpers into a module

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));
}

Thought: Module Inlining?

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)

Naming collision in mangle plugin when using `transformFromAST`

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;
  }
}

Multiple passes?

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.