Search code examples
javascriptjquerytwitter-bootstrapwebpackwebpack-2

Webpack 2 loading, exposing, and bundling jquery and bootstrap


This has been asked in piecemeal but no one seems to be able to settle on an answer. I'm very simply trying to bundle jquery THEN bootstrap and have $, JQuery and bootstrap be exposed globally.

Here's my webpack.config.js

var webpack = require('webpack');

module.exports = {
    entry: {
        accountdetails: './src/main/webapp/public/js/accountdetails.js',
        vendor_jquerybs: ['jquery', 'bootstrap']
    }
    ,
    module:{
        loaders: [{
            test: /\.jsx?$/,
            exclude: /node-modules/,
            loader: 'babel-loader'
        }]
    },
    resolve: {
        extensions: ['.js', '.jsx']
    },
    output: {
        path: __dirname + '/src/main/webapp/public/js/dist',
        publicPath: '/',
        filename: '[name].bundle.js'
    },
    devServer: {
        contentBase: './dist'
    }
};

This bundles properly. It loads as my first <script> in the <head> But I get console issues like: "$ is not defined", "jQuery is not defined".

How do I write this config to expose jQuery/$ and bootstrap globally? The Webpack docs say, CommonChunksPlugin, expose-loader, etc. What is the best way to do this? I'm very confused by the documentation.

Thank you.


Solution

  • Found the answer here https://github.com/webpack-contrib/expose-loader

    the module is expose-loader and is apparently needed to expose objects, classes, etc to window.

    module: {
      rules: [{
              test: require.resolve('jquery'),
              use: [{
                  loader: 'expose-loader',
                  options: 'jQuery'
              },{
                  loader: 'expose-loader',
                  options: '$'
              }]
          }]
    }
    

    NOTE: Correct me if I'm wrong, but there is then no need to expose bootstrap globally. jQuery will suffice.

    Full config now:

    var webpack = require('webpack');
    
    module.exports = {
        entry: {
            accountdetails: './src/main/webapp/public/js/accountdetails.js',
            vendor_jquerybs: ['jquery', 'bootstrap']
        }
        ,
        module:{
            loaders: [
                {
                test: /\.jsx?$/,
                exclude: /node-modules/,
                loader: 'babel-loader'
                },
                {
                test: require.resolve('jquery'),
                use: [{
                    loader: 'expose-loader',
                    options: 'jQuery'
                    },
                    {
                    loader: 'expose-loader',
                    options: '$'
                    }]
                }
            ]
        },
        resolve: {
            extensions: ['.js', '.jsx']
        },
        output: {
            path: __dirname + '/src/main/webapp/public/js/dist',
            publicPath: '/',
            filename: '[name].bundle.js'
        },
        devServer: {
            contentBase: './dist'
        }
    };
    

    NOTE: You CANNOT remove 'jquery' from entry point.