default exports bug

Do you want to request a feature or report a bug? Bug

What is the current behavior? Default exports seem to make it hard for webpack to do proper tree shaking.

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

Please see https://github.com/jmlopez-rod/lodash-webpack2
This repo contains 3 files: app.bundle.ts, custom.ts and random.ts.

random.ts only has one simple function that returns a string which we can look up in our final bundle. custom.ts imports a collection of functions that we can use, in this case, it imports and exports random as well as lodash-ts/isArray.

To see the issue first run npm install then webpack. This will generate the file dist/app.js. In this file you will see

/* 14 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/**
 * Checks if `value` is classified as an `Array` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
 * @example
 *
 * _.isArray([1, 2, 3]);
 * // => true
 *
 * _.isArray(document.body.children);
 * // => false
 *
 * _.isArray('abc');
 * // => false
 *
 * _.isArray(_.noop);
 * // => false
 */
var isArray = Array.isArray;

/* harmony default export */ __webpack_exports__["a"] = (isArray);

And if we search for from random.ts you we’ll find

/* 54 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* unused harmony export random */
function random() {
    return 'from random.ts';
}



/***/ }),

Here we can clearly see how using named exports helped webpack know that we did not use the function. Now, here is where we can see something interesting. Modify the file node_modules/lodash-es/isArray.js so that it may do named exports. That is, make it like this:

/**
 * Checks if `value` is classified as an `Array` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
 * @example
 *
 * _.isArray([1, 2, 3]);
 * // => true
 *
 * _.isArray(document.body.children);
 * // => false
 *
 * _.isArray('abc');
 * // => false
 *
 * _.isArray(_.noop);
 * // => false
 */
var isArray = Array.isArray;
// default export isArray;
export { isArray };

and modify custom.ts to properly import isArray:

import { default as assign } from 'lodash-es/assign';
import { isArray } from 'lodash-es/isArray';
import { random } from './random';

export {
  assign,
  isArray,
  random,
};

After running webpack again we should see that isArray is now considered an unused function:

/* 14 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* unused harmony export isArray */
/**
 * Checks if `value` is classified as an `Array` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
 * @example
 *
 * _.isArray([1, 2, 3]);
 * // => true
 *
 * _.isArray(document.body.children);
 * // => false
 *
 * _.isArray('abc');
 * // => false
 *
 * _.isArray(_.noop);
 * // => false
 */
var isArray = Array.isArray;
// export default isArray;

What is the expected behavior?

export default should work? There just seems to be strange behaviours with export default, for this reason I just never use them (babel and typescript treat them differently).

If this is a feature request, what is motivation or use case for changing the behavior?

Please mention other relevant information such as the browser version, Node.js version, webpack version and Operating System.

  • node: 6.10.2
  • webpack: 2.4.1
  • OS: macOSX 10.12

Author: Fantashit

1 thought on “default exports bug

  1. The lib itself won’t be exported through 'lodash' at all. You’ll have to specify import castArray from 'lodash/castArray'. As for a time, I’m hoping in the next couple of months. There’s some ecosystem things I need to get in place first.

Comments are closed.