webpack: Tree shaking not working in 2.1.0-beta.25

I’m submitting a bug report

Webpack version: 2.1.0-beta.25

Please tell us about your environment: macOS Sierra 10.12.1 Beta

Current behavior:

Tree shaking doesn’t seem to be working. In the 901kb file that’s generated in my live production (obviously more code than is shown below), a search on the generated bundle reveals the youshouldnevereverseethis string in the source code.

Expected/desired behavior:

Tree shaking should happen, and the exported test1 function should not be visible in source code.

Config

Language:

  • ES6 via babel-core 6.17.0
  • Babel loader config:
{
  test: /\.jsx?$/,
  loader: 'babel',
  query: {
    presets: [
      ['es2015', {
        modules: false,
      }],
      'react',
      'stage-1',
    ],
    plugins: [
      'transform-decorators-legacy',
      path.join(PATHS.app, '../plugins/relay'),
    ],
  },
},

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 30 (8 by maintainers)

Most upvoted comments

As @GianlucaGuarini mentioned, I’m seeing a lot of dependencies come in via node-browser-libs that weren’t there before which is significantly increasing my build size. It seems to be pulling in many which I don’t use at all as far as I can tell (e.g. bn.js via crypto-browserify) and weren’t pulled in by webpack 1. Is this expected behaviour?

I can exclude these manually with NormalModuleReplacementPlugin, but it seems a bit flaky because perhaps some of these are required somewhere else in my dependencies. It would be better if those that really aren’t needed simply weren’t pulled in.

@leebenson you are not giving ES6 modules to webpack; you are giving commonjs as transformed by babel. https://github.com/leebenson/wp-tree-shaking/blob/master/dist/server.js#L124-L126

There’s also a leftover Object.defineProperty(n,"__esModule",{value:!0}) in the minified public bundle, in same module the leftover functions are defined; meaning that this was commonjs-ified by babel.

Try giving babelrc: false to the babel-loader settings; babel plugins are additive, and babel might be loading the commonjs transform from the "presets": [ "es2015" ] in your project root.

For anyone interested in how replacing node-uuid with uuid fixes this. Here is what I learnt. (Valid only at the time of writing!)

node-uuid and uuid used to be separate projects, but are now merged. The npm package node-uuid is deprecated. The new npm package is called uuid.

The old node-uuid package requires the crypto module, which in webpack’s case will introduce node-libs-browser into the dependency graph. https://github.com/broofa/node-uuid/blob/309512573ec1c60143c257157479a20f7f1f51cd/uuid.js#L59

The new uuid package rewires module IDs for the browser to avoid requiring the crypto module: https://github.com/kelektiv/node-uuid/blob/bba940235d5c4778ec289f9e65dae0cd526038ef/package.json#L25. In place of crypto, it will use the browser crypto API if available and fallback to using Math.random: https://github.com/kelektiv/node-uuid/blob/bba940235d5c4778ec289f9e65dae0cd526038ef/lib/rng-browser.js#L1.

Since we’re on the topic of tree shaking, is there any way to convert CommonJS into ES6?

98% of my resulting bundle is pulled from older NPM modules that use module.exports, so the benefits of tree shaking are unfortunately limited to a few lines of code.

Rollup has this plugin; is there anything similar in the webpack world?

@leebenson I was wondering the same thing, and found this issue this morning: #2372 With this trick my build contains 553 chunks instead 800+ earlier.

I have a similar problem. This is my webpack config file and I realized it generates a bundle 3.2MB (1.3MB minified) big. I don’t understand why in my output code there seem to be core node modules like Buffer or process (https://github.com/webpack/node-libs-browser) even if they never were required. This issue does not only appear in webpack@2.1.0-beta.25 but it was present also in webpack@2.1.0-beta.19. I am also on Sierra 10.12. Side note: I was pinged on twitter by @TheLarkInn offering help on the issue

@elyobo had the exact same issue – bn.js etc. being bundled together with the rest of the JS (in)effectively doubling the bundle’s size.

Replacing the node-uuid package with uuid package helped.

Try giving babelrc: false to the babel-loader settings; babel plugins are additive, and babel might be loading the commonjs transform from the “presets”: [ “es2015” ] in your project root.

I saw your edit after posting. This actually fixed it. Genius! Thanks @Kovensky