title: Can Webpack tree-shake to remove imports already removed by tree-shaking
body: <p>Can Webpack be configured so that its tree-shaking is smart enough to remove imports depended on by only other tree-shaken exports?</p>
  <p>Example:</p>
  <p><strong>entry.js</strong></p>
  <pre class="lang-js prettyprint-override"><code>import { apple } from './appleBanana';
  console.log(apple());
  </code></pre>
  <p><strong>appleBanana.js</strong></p>
  <pre class="lang-js prettyprint-override"><code>import { mango, orange } from './mangoOrange';
  
  export function apple() {
    console.log('apple');
    mango();
  }
  
  export function banana() {
    console.log('banana');
    orange();
  }
  </code></pre>
  <p><strong>mangoOrange.js</strong></p>
  <pre class="lang-js prettyprint-override"><code>export function mango() {
    console.log('mango');
  }
  
  export function orange() {
    console.log('orange');
  }
  </code></pre>
  <p><strong>webpack.config.js</strong> optimization</p>
  <pre class="lang-json prettyprint-override"><code>optimization: {
    concatenateModules: false,
    usedExports: true,
    sideEffects: true
  }
  </code></pre>
  <p>When compiling with the above, we get:</p>
  <pre class="lang-js prettyprint-override"><code>
  /***/ &quot;./client/entry/Test.ts&quot;:
  /*!******************************!*\
    !*** ./client/entry/Test.ts ***!
    \******************************/
  /*! no exports provided */
  /*! all exports used */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  &quot;use strict&quot;;
  __webpack_require__.r(__webpack_exports__);
  /* harmony import */ var _appleBanana__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./appleBanana */ &quot;./client/entry/appleBanana.ts&quot;);
  
  console.log(Object(_appleBanana__WEBPACK_IMPORTED_MODULE_0__[/* apple */ &quot;a&quot;])());
  
  /***/ }),
  
  /***/ &quot;./client/entry/appleBanana.ts&quot;:
  /*!*************************************!*\
    !*** ./client/entry/appleBanana.ts ***!
    \*************************************/
  /*! exports provided: apple, banana */
  /*! exports used: apple */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  &quot;use strict&quot;;
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, &quot;a&quot;, function() { return apple; });
  /* unused harmony export banana */
  /* harmony import */ var _mangoOrange__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mangoOrange */ &quot;./client/entry/mangoOrange.ts&quot;);
  
  function apple() {
    console.log('apple');
    return Object(_mangoOrange__WEBPACK_IMPORTED_MODULE_0__[/* mango */ &quot;a&quot;])();
  }
  function banana() {
    console.log('banana');
    return Object(_mangoOrange__WEBPACK_IMPORTED_MODULE_0__[/* orange */ &quot;b&quot;])();
  }
  
  /***/ }),
  
  /***/ &quot;./client/entry/mangoOrange.ts&quot;:
  /*!*************************************!*\
    !*** ./client/entry/mangoOrange.ts ***!
    \*************************************/
  /*! exports provided: mango, orange */
  /*! exports used: mango, orange */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  &quot;use strict&quot;;
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, &quot;a&quot;, function() { return mango; });
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, &quot;b&quot;, function() { return orange; });
  function mango() {
    console.log('mango');
  }
  function orange() {
    console.log('orange');
  }
  
  /***/ })
  
  /******/ });
  </code></pre>
  <p>Note that both <code>mango</code> and <code>orange</code> are marked as used, even though <code>banana()</code> (which calls <code>orange()</code>) got removed by tree-shaking. As a result, in the Terser/Uglify minified bundle, they both get included.</p>
  <p>Is there a way to make Webpack or Terser/UglifyJS smarter and also remove imports to symbols that are not used in the post-tree-shaking?</p>