13

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?

3 Answers 3

12

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

Sign up to request clarification or add additional context in comments.

Comments

0

attach jquery.js file before JS Bundle

2 Comments

If you check my code, you will see the jquery.js file is added into the bundle.
it happens bundle load all JS files as one so other files use "$" that's why $ is not defined
0

Based on the long discussion here, it looks like you need to resolve jquery module with a alias as $ or jQuery rather than defining it as a plugin.

here is the webpack config for that:

 resolve : {
    alias: {
        jquery: "./vendor/jquery/jquery.js",
    }
},

WebPack documentation page

3 Comments

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.
are you saying your getting same error with alias ?
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.