{"action":"created","issue":{"url":"https://api.github.com/repos/rollup/rollup/issues/869","repository_url":"https://api.github.com/repos/rollup/rollup","labels_url":"https://api.github.com/repos/rollup/rollup/issues/869/labels{/name}","comments_url":"https://api.github.com/repos/rollup/rollup/issues/869/comments","events_url":"https://api.github.com/repos/rollup/rollup/issues/869/events","html_url":"https://github.com/rollup/rollup/issues/869","id":172249021,"number":869,"title":"reflection about some tree shaking issue","user":{"login":"tnga","id":12436411,"avatar_url":"https://avatars.githubusercontent.com/u/12436411?v=3","gravatar_id":"","url":"https://api.github.com/users/tnga","html_url":"https://github.com/tnga","followers_url":"https://api.github.com/users/tnga/followers","following_url":"https://api.github.com/users/tnga/following{/other_user}","gists_url":"https://api.github.com/users/tnga/gists{/gist_id}","starred_url":"https://api.github.com/users/tnga/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tnga/subscriptions","organizations_url":"https://api.github.com/users/tnga/orgs","repos_url":"https://api.github.com/users/tnga/repos","events_url":"https://api.github.com/users/tnga/events{/privacy}","received_events_url":"https://api.github.com/users/tnga/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-08-20T02:32:20Z","updated_at":"2016-12-30T20:45:25Z","closed_at":"2016-12-30T20:45:25Z","body":"Let us thing about why rollup can provide unexpected result with some hacks like those we have when using _lodash-es_ or _underscore-es_. (#849)\n\nThe exemple bellow is a good way to start:\n- _main.js_\n  \n  ``` js\n  import {_initial} from './module';\n  \n  console.log(_initial([1, 2, 3]));\n  ```\n- _module.js_\n  \n  ``` js\n  import {slice, hasOwnProperty} from './quickaccess';\n  \n  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\n  let hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');\n  let nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',\n                    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];\n  \n  let escapeMap = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n  };\n  let isGTescaped = _has(escapeMap, \">\");\n  \n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N.\n  export function _initial (array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n  }\n  \n  // Shortcut function for checking if an object has a given property directly\n  // on itself (in other words, not on a prototype).\n  export function _has (obj, key) {\n    return obj != null && hasOwnProperty.call(obj, key);\n  }\n  ```\n- _quickaccess.js_\n  \n  ``` js\n  // Save bytes in the minified (but not gzipped) version:\n  export const ArrayProto = Array.prototype;\n  export const ObjProto = Object.prototype;\n  \n  // Create quick reference variables for speed access to core prototypes.\n  export const push = ArrayProto.push;\n  export const slice = ArrayProto.slice;\n  export const toString = ObjProto.toString;\n  export const hasOwnProperty = ObjProto.hasOwnProperty;\n  ```\n\n**considering exemple above, why have unexpected result from _main.js_ with rollup whatever the format ?**\n_**bellow the bundle in `es` format**_\n\n``` js\n// Save bytes in the minified (but not gzipped) version:\nconst ArrayProto = Array.prototype;\nconst ObjProto = Object.prototype; //<--- unexpected\n\nconst slice = ArrayProto.slice;\nconst hasOwnProperty = ObjProto.hasOwnProperty; //<--- unexpected\n\n// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.\nlet hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); //<--- unexpected\nlet escapeMap = {  //<--- unexpected\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#x27;',\n    '`': '&#x60;'\n};\nlet isGTescaped = _has(escapeMap, \">\"); //<--- unexpected\n\n// Returns everything but the last entry of the array. Especially useful on\n// the arguments object. Passing **n** will return all the values in\n// the array, excluding the last N.\nfunction _initial (array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n}\n\n// Shortcut function for checking if an object has a given property directly\n// on itself (in other words, not on a prototype).\nfunction _has (obj, key) { //<--- unexpected\n    return obj != null && hasOwnProperty.call(obj, key);\n}\n\nconsole.log(_initial([1, 2, 3]));\n```\n\nAs we can see with an indicated comment, there are unexpected outputs in the bundle. If we put in comment `let isGTescaped = _has(escapeMap, \">\")` or change it to something like `let isGTescaped = !!escapeMap[\">\"]`, everything wil be ok except the fact that the line `let hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');` will remain included ; unless it is set to a static value (`let hasEnumBug = false`).\n\n_Like we can see, it seems like rollup or it tree shaking have an issue with variables that are using as argument to a function for an evaluation or for variables which value have to be evaluated ; even if that variables or calling functions will not be used or imported (implicitly or explicitly) from the associated module_. isn't it ?\n\n**I precise that the expected result for the exemple above is:**\n\n``` js\n// Save bytes in the minified (but not gzipped) version:\nconst ArrayProto = Array.prototype;\n\nconst slice = ArrayProto.slice;\n\n// Returns everything but the last entry of the array. Especially useful on\n// the arguments object. Passing **n** will return all the values in\n// the array, excluding the last N.\nfunction _initial (array, n, guard) {\n    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));\n}\n\nconsole.log(_initial([1, 2, 3]));\n```\n"},"comment":{"url":"https://api.github.com/repos/rollup/rollup/issues/comments/269819931","html_url":"https://github.com/rollup/rollup/issues/869#issuecomment-269819931","issue_url":"https://api.github.com/repos/rollup/rollup/issues/869","id":269819931,"user":{"login":"Rich-Harris","id":1162160,"avatar_url":"https://avatars.githubusercontent.com/u/1162160?v=3","gravatar_id":"","url":"https://api.github.com/users/Rich-Harris","html_url":"https://github.com/Rich-Harris","followers_url":"https://api.github.com/users/Rich-Harris/followers","following_url":"https://api.github.com/users/Rich-Harris/following{/other_user}","gists_url":"https://api.github.com/users/Rich-Harris/gists{/gist_id}","starred_url":"https://api.github.com/users/Rich-Harris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Rich-Harris/subscriptions","organizations_url":"https://api.github.com/users/Rich-Harris/orgs","repos_url":"https://api.github.com/users/Rich-Harris/repos","events_url":"https://api.github.com/users/Rich-Harris/events{/privacy}","received_events_url":"https://api.github.com/users/Rich-Harris/received_events","type":"User","site_admin":false},"created_at":"2016-12-30T20:45:24Z","updated_at":"2016-12-30T20:45:24Z","body":"See https://github.com/rollup/rollup/wiki/Troubleshooting#tree-shaking-doesnt-seem-to-be-working. Unfortunately static analysis in JavaScript is difficult, and lodash contains a lot of code that is difficult to guarantee is side-effect free, so this isn't a bug per se, just something that will hopefully improve over time."}}
{"actor":{"display_login":"Rich-Harris"}}