14

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',
   }
...
calbear47
  • 1,060
  • 2
  • 18
  • 38

1 Answers1

5

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`,
        }),
    ],
};
Calder White
  • 1,287
  • 9
  • 21