[webpack2] Tree shaking and "unused harmony default export" #2866

tleunen opened this Issue Aug 13, 2016 · 9 comments


None yet

5 participants

tleunen commented Aug 13, 2016 edited

I'm running webpack 2 beta 20 and for a development build, I can see a lot of unused harmony default export in my UI library (which is normal since I don't use everything that is available in the library).

I checked the code and instead of exporting the class with the webpack require function, i see this, which seems ok.

/* unused harmony default export */ var _unused_webpack_default_export = ComponentA;

But when I build the app in a production environment, the component is still there, even if it has been marked as unused.

The component is imported and exported from another file before my app really uses it.

export { default as ComponentA } from './ComponentA';

and inside that file, it's marked like this:

/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__ComponentA__ = __webpack_require__(622);
/* unused harmony reexport ComponentA */

I also checked the compiled code in production, and the code is there but as it's mentioned with the unused reexport, nothing is exported... No t.default = ...

From what I see, it seems there's an issue in the tree-shaking/code elimination. Can you confirm, or tell me what would be wrong in what I'm trying to do?

tleunen commented Aug 19, 2016

Tested with latest beta 21 and same issue.

sokra commented Sep 7, 2016

I need a bit more information to fix this.

How does the app import module which is reexporting the ComponentA?

Could you create a minimal test repo which allows me to reproduce the issue?

tleunen commented Sep 7, 2016 edited

@sokra See this repo: https://github.com/tleunen/webpack-2866 with this file resulted file: https://github.com/tleunen/webpack-2866/blob/master/dist/build.js

Only util31 is used in app.js, but all util1, util2 and util32 are in the resulted file.

sokra commented Sep 8, 2016

Looks correct to me. The functions itself are removed by UglifyJs once you minimize the file.

Minimized file:

!function(t){function n(e){if(r[e])return r[e].exports
var u=r[e]={i:e,l:!1,exports:{}}
return t[e].call(u.exports,u,u.exports,n),u.l=!0,u.exports}var r={}
return n.m=t,n.c=r,n.i=function(t){return t},n.d=function(t,n,r){Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},n.n=function(t){var r=t&&t.__esModule?function(){return t["default"]}:function(){return t}
return n.d(r,"a",r),r},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="/",n(n.s=4)}([function(t,n,r){"use strict"
var e=(r(1),r(2),r(3))
r.d(n,"a",function(){return e.a})},function(t,n,r){"use strict"},function(t,n,r){"use strict"},function(t,n,r){"use strict"
function e(){console.log("util 3.1")}n.a=e},function(t,n,r){"use strict"
var e=r(0)

The minimized file only contains console.log("util 3.1").

@sokra sokra closed this Sep 8, 2016

@sokra so was it a misunderstanding? Or was it fixed by someone recently?

jippi commented Sep 8, 2016

I assume the problem was not applying Uglifyjs ?

tleunen commented Sep 8, 2016

Hmm Ok, I didn't know webpack wasn't supposed to remove them, even in a dev mode. But in my real use case, it still doesn't work after uglify.

I updated the code with a more complex code @sokra,and everything is still in the final bundle.
See https://github.com/tleunen/webpack-2866

sokra commented Sep 8, 2016

yeah, uglify-js is not that clever as you would except it to be. We are working on a solution, but this will take time. There is already another issue, so I'll keep this closed.

tleunen commented Sep 8, 2016

Can you point me to the issue you have in mind so I can keep tracking it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment