question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Anonymous functions sometimes given conflicting names, breaking code.

See original GitHub issue

Input Code

index.js:

#!/usr/bin/node
'use strict';

const babel = require('babel-core');

console.log(babel.transform(`
	'use strict';
	(() => {
		const con = console;
		const obj = {
			a() {
				con.log('Hi.');
			}
		};
		obj.a.log = str => {
			con.log('OUCH, should never get here! Should be "' + str + '".');
		};
		obj.a();
	})();
`, {presets: ['minify', 'env']}).code);

package.json:

{
  "name": "babelbug",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "",
  "private": true,
  "dependencies": {
    "babel-core": "^6.26.3",
    "babel-preset-env": "^1.6.1",
    "babel-preset-minify": "^0.4.0"
  }
}

Actual Output

'use strict';(function(){var a=console,b={a:function a(){a.log('Hi.')}};b.a.log=function(b){
a.log('OUCH, should never get here! Should be "'+b+'".')},b.a()})();

Prints ‘OUCH, should never get here! Should be “Hi.”.’.

Expected Output

'use strict';(function(){var a=console,b={a:function(){a.log('Hi.')}};b.a.log=function(b){
a.log('OUCH, should never get here! Should be "'+b+'".')},b.a()})();

Prints ‘Hi.’.

Details

Note the incorrect function a() instead of function(), leading to the con variable being clobbered.

Same thing if using babel-preset-es2015 with babel-preset-minify.

Can’t make a direct link to reproduce online – not sure why. But following this link, clicking on ‘Plugins’, on ‘Only official plugins’, typing ‘mangle’ and selecting minify-mangle-names reproduces it: https://babeljs.io/repl/#?babili=false&browsers=&build=&builtIns=false&code_lz=JAcgrgzgpgBBAuAnAlgY3iA3AKGACjwEoYBeAPhgG9dhUB7AOwRnodKoBs6BzALhgAepCgEMOURPDwDCAXxzBajZnQBGAK3bVFwEUSo1FrAHRdueEAAlkxkIQWLZNeTTXrjI0z3YJEwgzomZhYA8gCqAMKWADRwABZ0YBwAJjAMUABuEjDcUPAwcRJQAIQwAMoJSamqsABEIDAA1HBITTAgtbb2zg5uHkQKsoQD2EA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=true&fileSize=false&lineWrap=false&presets=es2015&prettier=false&targets=&version=6.26.0&envVersion=

Not sure whether this is a minify bug or a babel bug. Can’t reproduce if running ‘env’ on the output of ‘minify’ or when running ‘minify’ on the output of ‘env’, only if doing both in the same step.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
Cypcommented, May 3, 2018

Somehow, when doing { a: function () {} }, a.name is still "a", at least in chromium and node. Seems doing anything more complicated than just putting brackets around the function makes it drop the .name, though.

functiontest

I don’t think the minifier normally tries to preserve function names, since functions get renamed when minifying. Although there does seem to be some sort of weird (failed) attempt at preserving .name here:

http://babeljs.io/repl/#?babili=true&browsers=&build=&builtIns=false&code_lz=MYewdgzgLgBCBGArGBeGBvAUDGBDANgKYBOUAFAJQbY55GlkAGAEgJYA0MAkgOQC2MYAXyswAcxgAiACToCJKADowuPoQC-kmADNiIATPQJEi-aWWqNkxYwoBuGuszqHx0_XL3MQA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=true&fileSize=false&lineWrap=false&presets=es2015%2Clatest%2Cbabili&prettier=true&targets=&version=6.26.0&envVersion=

const obj = {
  alert() {
    alert(`Hi, I'm calling "${alert.name}" from "${obj.alert.name}".`);
  }
};
obj.alert();  // Hi, I'm calling "alert" from "alert".

becomes

"use strict";
var obj = {
  alert: (function(a) {
    function b() {
      return a.apply(this, arguments);
    }
    return (
      (b.toString = function() {
        return a.toString();
      }),
      b
    );
  })(function() {
    alert(
      "Hi, I'm calling \"" + alert.name + '" from "' + obj.alert.name + '".'
    );
  })
};
obj.alert();  // Hi, I'm calling "alert" from "b".

when minified.

0reactions
boopathicommented, May 14, 2018

The t.NOT_LOCAL_BINDING symbol used in plugin-function-name (https://github.com/babel/babel/blob/bd98041321c60737ddcacd1ad7e056ef6de31879/packages/babel-helper-function-name/src/index.js#L206) is causing this issue.

This was added in https://github.com/babel/babel/pull/3298

The problem is the binding identifier is NOT registered (skipped) during crawl and the mangler finds the first safe identifier which ultimately collides with this name during runtime.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Pure Anonymous Function: Elementary Introduction ... - Wolfram
Learn to use pure functions in Wolfram Language code, thus simplifying your code and avoiding repetition. Written by Stephen Wolfram.
Read more >
anonymous functions considered harmful? [closed]
Closures (or anonymous functions) just help to break your code into slightly different ... Amusingly, JavaScript will let you name "anonymous" functions:
Read more >
Functions — reusable blocks of code - Learn web development
This is called an anonymous function, because it has no name. You'll often see anonymous functions when a function expects to receive ...
Read more >
purrr 1.0.0 - Tidyverse
These changes will break some existing code, but we've done our best to ... name for the anonymous function can often lead to...
Read more >
Anonymous Function JavaScript: Coding Concepts
Anonymous functions are often arguments being passed to higher-order functions, or used for constructing the result of a higher-order ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found