exporting ‘exports.default’ rather than ‘exports’

I’m writing a library with ES6 module notation. The main module exports only a default object:

// defining MainObject
//...
export default MainObject;

Inside other ES6 modules, Webpack seems to handle this well, extracting the exports.default when needed. But when exporting my library to, e.g., UMD, the entire exports object is exported.

I’d like the option to export exports.default instead. Right now, my build-process fixes this with a simple search/replace operation on the Webpack output:

.pipe(replace(
    'return __webpack_require__(0)',
    'return __webpack_require__(0).default'))

It works, but it’s not ideal.

Author: Fantashit

6 thoughts on “exporting ‘exports.default’ rather than ‘exports’

  1. I ran into this issue as well. I’m exposing a exported library with the output.library option. When I export the library like this, it works as expected:

    module.exports = Library;

    When I export the library like this, I get an exports object with a default key:

    export default Library;

    I believe this should become something like this:

    exports["default"] = Library;
    module.exports = exports["default"];

    Instead I get the same code as @mhelvens got:

    return __webpack_require__(0)
  2. Same issue!
    I had to fix it by using module.exports = lib instead of export default lib in the entry file for my code as suggested above.

  3. I’ve also faced this issue. I’ve written a library with Typescript + Babel + Wepack, and the libraryTarget: 'umd' exports an object with a default key, instead of my lib code.

    Unfortunately the workarounds above did’t work because:

    • Typescript with target es2015+ allows only export default x
    • add-module-exports is useless when babel modules: false is set

    So, I had to come up with a different solution: adding a custom UMD wrapper with wrapper-webpack-plugin. Just remove the library* options under output and add the plugin:

    const WrapperPlugin = require('wrapper-webpack-plugin');
    module.exports = {
      //...
      plugins: [
        //...
        new WrapperPlugin({
          test: /\.js$/,
          header: ('(function umdWrapper(root, factory) {' +
            '  if(typeof exports === "object" && typeof module === "object")' +
            '    module.exports = factory().default;' +
            '  else if(typeof define === "function" && define.amd)' +
            '    define("NAME", [], function() { return factory().default; });' +
            '  else if(typeof exports === "object")' +
            '    exports["NAME"] = factory().default;' +
            '  else' +
            '    root["NAME"] = factory().default;' +
            '})(this, function() {' +
            'return ').replace(/NAME/g, 'MyAwesomeLib'), // this is the name of your lib
          footer: '\n})',
        }),
      ],
    };

    (PS: The header code is almost entirely copied from the default Webpack UMD wrapper)

  4. Just for reference for anyone coming from a google search, Webpack 3 has an option called libraryExport that can be set to “default” which should hopefully fix this issue.

  5. Just for reference for anyone coming from a google search, Webpack 3 has an option called libraryExport that can be set to “default” which should hopefully fix this issue.

    Good solution, the output.libraryExport was the perfect solution. This worked for me:

        output: {
          // ... other options
          library: 'myLibNamespace',
          libraryExport: 'default',
          libraryTarget: 'umd'
        },

Comments are closed.