Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exported function is undefined in bundle.js after webpack build

I have have build process that is managed by Webpack. It bundles all my files up and generates a single bundle.js file. Very typical pattern.

However, when I include that file bundle.js in a webpage, the exported default function is undefined. Why can't I access that exported function from the global scope on a webpage?

Here is my webpack config:

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    entry: './src/js/index.js',
    output: {
        path: path.resolve('dist'),
        filename: 'bundle.js',
    },
    performance: {
        hints: false,
    },
    resolve: {
        modules: ['node_modules', path.join(__dirname, 'src'), 'assets'],
    },
    module: {
        rules: [
            {
                test: /\.(sa|sc|c)ss$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: 'babel-loader',
            },
            {
                test: /\.(eot|svg|ttf|woff|woff2)$/,
                use: 'file-loader',
            },
        ],
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: `bundle.css`,
        }),
    ],
};

Here is a simplified src/js/index.js:

import util from './util';
import as dependency from 'external-library';
import EventEmitter from 'events';

/**
 * MyLibrary module
 * @module MyLibrary
 * @class
 * @param {MyLibraryOptions} options - Options to initialize the module with
 * @returns {Object} MyLibrary instance
 */
export default function MyLibrary(options) {
    if (!(this instanceof MyLibrary)) {
        return new MyLibrary(options);
    }
    
    //...Do a bunch of stuff.

}

The goal is to include bundle.js on a webpage and access in a script tag such as:

var instance = new MyLibrary({option_1: value, ...})

However, when I do this MyLibrary is always undefined.

UPDATE:

After adding the library property as in the webpack config, MyLibrary is not undefined, but I can't call it. It's a module now.

enter image description here

UPDATE 2 --> SOLUTION:

module.exports = {
    entry: './src/js/index.js',
    output: {
        library: 'MyLibrary',
        libraryTarget: 'umd',
        libraryExport: 'default',
        path: path.resolve('dist'),
        filename: 'bundle.js',
   }
...
like image 663
calbear47 Avatar asked Jul 13 '19 21:07

calbear47


1 Answers

In webpack the default scope is not global. It contains all your code in an anonymous function. To expose your library to the global scope of the browser, use this answer.

Your webpack config would look like this:

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    entry: './src/js/index.js',
    output: {
        library: 'MyLibrary',
        path: path.resolve('dist'),
        filename: 'bundle.js',
    },
    performance: {
        hints: false,
    },
    resolve: {
        modules: ['node_modules', path.join(__dirname, 'src'), 'assets'],
    },
    module: {
        rules: [
            {
                test: /\.(sa|sc|c)ss$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: 'babel-loader',
            },
            {
                test: /\.(eot|svg|ttf|woff|woff2)$/,
                use: 'file-loader',
            },
        ],
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: `bundle.css`,
        }),
    ],
};
like image 116
Calder White Avatar answered Nov 06 '22 02:11

Calder White