webpack doesn’t eliminate module required under false condition

Related issue: mishoo/UglifyJS#3110

Bug report

What is the current behavior?

webpack include dev module in production bundle.

If the current behavior is a bug, please provide the steps to reproduce.

Re-pro: https://github.com/dangh/test-webpack-treeshaking

The dev.js is included in the bundle with the following code:

const __DEV__ = process.env.NODE_ENV === 'development'

if (__DEV__) {
  require('./dev.js')
}

But not this one:

if (process.env.NODE_ENV === 'development') {
  require('./dev.js')
}

UglifyJS/BabelMinify doesn’t help since it can optimize the calling site but doesn’t touch the bundled module.

See the output: https://github.com/dangh/test-webpack-treeshaking/blob/master/dist/main.js#L74-L79

What is the expected behavior?

The dev.js module shouldn’t be included in the bundle.

Other relevant information:
webpack version: 4.7.0
Node.js version: 9.11.1
Operating System: macOS
Additional tools:

Author: Fantashit

1 thought on “webpack doesn’t eliminate module required under false condition

  1. webpack is able to evaluate expressions but it does not memoize the bindings’ value.

    const __DEV__ = process.env.NODE_ENV === 'development'
    //              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    //           webpack understands this is 'false' or 'true'
    
    if (__DEV__) {
    //  ^^^^^^^
    //  webpack can't optimize the 'if' test because '__DEV__' is unknown since its
    //  value isn't tracked.
      require('./dev.js')
    }
    
    if (process.env.NODE_ENV === 'development') {
    //  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    //  webpack can optimize the 'if' test it is able to evaluate the test
      require('./dev.js')
    }

    tl;dr: webpack only optimizes constant expressions. Use DefinePlugin to replace variables.

Comments are closed.