Uncaught ReferenceError: $ is not defined Webpack and embedded script

12,061

One solution it seems to work is to expose the jQuery module outside of the webpack bundle.

module: {
    rules: [
        {
            test: /\.tsx?$/,
            loader: 'ts-loader',
            exclude: /node_modules/,
        },
        {
            test: /\.css$/,
            loader: ExtractTextPlugin.extract({
                fallback: 'style-loader',
                use: 'css-loader'
            })
        },
        {
            // Exposes jQuery for use outside Webpack build
            test: require.resolve('jquery'),
            use: [{
                loader: 'expose-loader',
                options: 'jQuery'
            }, {
                loader: 'expose-loader',
                options: '$'
            }]
        }
    ]
},

Solution found here: Managing jQuery plugin dependency in webpack @harlemsquirrel

Share:
12,061
blfuentes
Author by

blfuentes

Software engineer on the wrong side of the wall SOreadytohelp

Updated on July 25, 2022

Comments

  • blfuentes
    blfuentes almost 2 years

    I am using webpack to create a *.js bundle

    var path = require('path');
    var webpack = require('webpack');
    
    const ExtractTextPlugin = require("extract-text-webpack-plugin");
    
    module.exports = {
        entry: {
            site: [
                './wwwroot/js/site.js',
                './node_modules/jquery/dist/jquery.js',
                './Scripts/jquery.global.js',
                './node_modules/jquery-validation/dist/jquery.validate.js',
                './node_modules/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js',
                './node_modules/popper.js/dist/popper.js',
                './node_modules/bootstrap/dist/js/bootstrap.js',
            ]
        },
        output: {
            filename: 'bundle.js',
            path: path.resolve(__dirname, 'wwwroot/dist/')
        },
        module: {
            rules: [
                {
                    test: /\.tsx?$/,
                    loader: 'ts-loader',
                    exclude: /node_modules/,
                },
                {
                    test: /\.css$/,
                    loader: ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: 'css-loader'
                    })
                },
            ]
        },
        resolve: {
            extensions: [".tsx", ".ts", ".js", ".css"]
        },
        plugins: [
            new ExtractTextPlugin('../css/bundle.css'),
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery",
                Popper: ['popper.js', 'default']
            })
        ]
    };
    

    Then in the _Layout.cshtml I have the following code:

     ...
    
        <div class="container body-content">
            @RenderBody()
            <hr />
            <footer>
                <p>&copy; 2017 - MVC_Movie</p>
            </footer>
        </div>
    
        <environment include="Development">
            <script src="~/js/site.js" asp-append-version="true"></script>
            <script src="~/dist/bundle.js" asp-append-version="true"></script>
        </environment>
        <environment exclude="Development">
            <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"
                    asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                    asp-fallback-test="window.jQuery"
                    crossorigin="anonymous"
                    integrity="">
            </script>
            <script src="http://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
                    asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                    asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                    crossorigin="anonymous"
                    integrity="">
            </script>
            <script src="~/js/site.min.js" asp-append-version="true"></script>
        </environment>
    
        @RenderSection("Scripts", required: false)
    
        <script>
            $(document).ready(function () {
                debugger;
                //Ask ASP.NET what culture we prefer, because we stuck it in a meta tag
                var data = $("meta[name='accept-language']").attr("content")
                //Tell jQuery to figure it out also on the client side.
                $.global.preferCulture(data);
                //Tell the validator, for example,
                // that we want numbers parsed a certain way!
                $.validator.methods.number = function (value, element) {
                    if ($.global.parseFloat(value)) {
                        return true;
                    }
                    return false;
                }
            });
        </script>
    </body>
    </html>
    

    So far I don't get any errors to generate the bundle.js file looks fine, but the section at the bottom of the _Layout.cshtml raises an exception

    Uncaught ReferenceError: $ is not defined

    I thought by defining in the webpack.config.js the plugin section the symbol $ would be recognized:

    plugins: [
            new ExtractTextPlugin('../css/bundle.css'),
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery",
                Popper: ['popper.js', 'default']
            })
        ]
    

    Any idea how to get it working?

  • blfuentes
    blfuentes over 6 years
    If you check my code, you will see the jquery.js file is added into the bundle.
  • Faisal
    Faisal over 6 years
    it happens bundle load all JS files as one so other files use "$" that's why $ is not defined
  • blfuentes
    blfuentes over 6 years
    Actually the bundle is generated without error when using the plugin. I have tried using the alias, but didn't help. stackoverflow.com/questions/28969861/… Trying to implement the options here also didn't work.
  • dreamweiver
    dreamweiver over 6 years
    are you saying your getting same error with alias ?
  • blfuentes
    blfuentes over 6 years
    yes, I get the same error of undefined. I have found a solution using the expose-loader. I will post the answer, in case another solution fits it better.