Search code examples
javascriptecmascript-6webpacklodashumd

How can I get my module exported to the browser without using Module.default notation?


How can I make webpack expose my module to the browser directly to the Module name instead of using Module.default?

Here is my app setup in a simplified manner to hopefully portray what I am hoping to achieve.

webpack.config.js

module.exports = {
    entry: './src/app.js',
    devtool: 'source-map',
    output: {
        path: './lib',
        filename: 'app.js',
        library: 'App',
        libraryTarget: 'umd',
        umdNamedDefine: true
    },
    module: {
        loaders: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader'
        }]
    }
};

.babelrc

{
    "presets": ["es2015"],
    "plugins": ["babel-plugin-add-module-exports"]
}

app.js

export default function main() {
    console.log('The default function');
}

export function other() {
    console.log('A random function');
}

Because I specified "App" as the "library" in the output, my library is available in the browser as App.

The weird thing is... in order to use the default function that was exported I have to do App.default. But to use the other exported function I can do this: App.other. I would expect that I could do App() to call the default exported function, and the other would be the same App.other().

Is this standard behavior in the browser or a UMD wrapped library with webpack? This does not seem to mimic the behavior of the lodash library. Is my configuration off in some way?


However, if you take a look at the lodash library (repo) in the browser, you can see that they acheived it.

Lodash is built using webpack. If you take a look inside of the package.json for lodash, you can see that the main file is lodash.js. If you take a look at that file, it appears to be UMD wrapped (UMD definition at the bottom of the file). Therefore, when I do things like:

import _ from 'lodash';
// or
import {clamp} from 'lodash';

everything works fine.

The other thing that works fine is referencing that exact file in an HTML file:

<script src="node_modules/lodash/lodash.js"></script>

Which allows me access to the lodash object.

console.log(_) // function
console.log(_.clamp) // function clamp(number, lower, upper) { ... }

How can I get the same behavior. Lodash's webpack config is much more complicated than I need, and am not sure what I need to reverse engineer.


Solution

  • add libraryExport: 'default' to the output configuration of webpack; also you don't need babel-plugin-add-module-exports.