'jquery is not defined' when using webpack to load bootstrap

47,443

Solution 1

Add this as plugin

  new webpack.ProvidePlugin({
   $: "jquery",
   jQuery: "jquery"
  })

and you should be able to have jquery in your whole project.

If issue persists after adding the plugin, try restarting your nodejs server. Remember to install jquery using npm install --save jquery.

Solution 2

I know this is a bit old, but I managed to do it like that :

global.jQuery = require('jquery'); require('bootstrap');

Solution 3

Plugin is not needed. Just use following as entry:

entry: [
    'jquery', //will load jquery from node_modules
    './assets/js/index',
]

Then in ES6+ file use:

import $ from "jquery";

Solution 4

I want to share my findings for any future developer who might have the same use-case I do.

I had the requirement to only create a vendor bundle and not an app bundle for an AngularJS (1.7.2) app, using Webpack 4 (4.16.4). I think because I was only creating a vendor bundle, none of the other solutions worked. Only expose-loader worked for me, like so:

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

For more information: https://github.com/webpack-contrib/expose-loader

Share:
47,443
Junchao Gu
Author by

Junchao Gu

Updated on October 15, 2020

Comments

  • Junchao Gu
    Junchao Gu over 3 years

    I am just starting to learn to use Webpack (previously I just use the manual way to include individual scripts separately). And I used bootstrap-loader for loading bootstrap. Here is my webpack.config.js

    var path = require("path")
    var webpack = require('webpack')
    var BundleTracker = require('webpack-bundle-tracker')
    
    module.exports = {
        context: __dirname,
    
        entry: './assets/js/index', // entry point of our app. assets/js/index.js should require other js modules and dependencies it needs
    
        output: {
            path: path.resolve('./assets/bundles/'),
            filename: "[name]-[hash].js",
        },
    
        plugins: [
            new BundleTracker({filename: './webpack-stats.json'})
        ],
    
        module: {
            loaders: [
                { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'}, // to transform JSX into JS
                { test: /\.css$/, loader: 'style-loader!css-loader'}, // to transform css
                // images
                { test: /\.png$/, loader: 'url-loader?limit=100000'},
                { test: /\.jpg$/, loader: 'file-loader'},
                // bootstrap image files
                { test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/font-woff'},
                { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream'},
                { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file'},
                { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml'}
            ],
        },
    
        resolve: {
            modulesDirectories: ['node_modules', 'bower_components'],
            extensions: ['', '.js', '.jsx'],
            jquery: './vendor/jquery/jquery.js',
        },
    }
    

    And here is my entry.js

    global.jQuery = global.$ = require('jquery');
    require('bootstrap-loader');
    

    This seems to work. However, I used this before and it did not work:

    window.jQuery = window.$ = require('jquery');
    

    I found the line above suggested by so many people. But I just simply get errors when load the page. Just some examples: some SO question, webpack issue, another SO question.

    Later I found this question, and this question. So the page actually works with bootstrap js functionality working as well.

    I will add my package.json as well in case it is relevant:

    {
      "author": "franklingu",
      "dependencies": {
        "babel": "^6.5.2",
        "babel-core": "^6.13.2",
        "babel-loader": "^6.2.4",
        "bootstrap-loader": "^1.2.0-beta.1",
        "bootstrap-sass": "^3.3.7",
        "extract-text-webpack-plugin": "^1.0.1",
        "jquery": "^3.1.0",
        "node-sass": "^3.8.0",
        "resolve-url-loader": "^1.6.0",
        "sass-loader": "^4.0.0",
        "webpack": "^1.13.1",
        "webpack-bundle-tracker": "0.0.93"
      },
      "devDependencies": {
        "babel-core": "^6.13.2",
        "babel-loader": "^6.2.4",
        "css-loader": "^0.23.1",
        "file-loader": "^0.9.0",
        "node-sass": "^3.8.0",
        "resolve-url-loader": "^1.6.0",
        "sass-loader": "^4.0.0",
        "style-loader": "^0.13.1",
        "url-loader": "^0.5.7",
        "webpack": "^1.13.1"
      }
    }
    

    I am new to webpack but I am not new to JS. I am wondering why window.$ is not working.

    And I wonder, for webpack, why some people suggested this in plugins:

            new webpack.ProvidePlugin({
                'window.jQuery': 'jquery',
                'window.$': 'jquery',
            })
    

    Some people are suggesting this (did not work for me either):

     resolve: {
        alias: {
            jquery: "jquery/src/jquery"
        }
    }
    

    I played with node for a while back then and I remembered that node makes use of request js for loading(I am not very clear about differences between common vs require vs amd though). But why some people mention common js?

    I was developing backend for some time and just started frontend--so many questions are popping up. It would just enough if you provide me with some link to some guide to read which can clear my doubts/build my basic understanding of these.

  • Junchao Gu
    Junchao Gu almost 8 years
    I did put this in my question. maybe you can just read it again. Did not work for me this solution
  • Jorawar Singh
    Jorawar Singh almost 8 years
    if you using this plugin it should work and you don't need to set alias.. check this seed
  • Jorawar Singh
    Jorawar Singh almost 8 years
    Note: once you have pluged jquery with webpack plugin you don't need to import it with require and you can go to dev tools and type $ to see that jquery has loaded. i don't see anything else strange in you code it should just work :-)
  • Junchao Gu
    Junchao Gu almost 8 years
    chrome actually ships with its own $--according to what I know. But I will go back and try it again. Just this solution
  • Junchao Gu
    Junchao Gu almost 8 years
    weird. I definitely have tried this approach before and it did not work for me. but now it seems to be fine
  • Entea
    Entea over 7 years
    @JunchaoGu Had the same issue, restarting node server did the trick.
  • Flimm
    Flimm over 7 years
    Does this work in Webpack 2? Does this make sure that index will not be executed until jquery has been executed?
  • Niels Steenbeek
    Niels Steenbeek over 7 years
    @Flimm Webpack 2 has no change on the 'entry' part, so should work there as well.
  • Niels Steenbeek
    Niels Steenbeek over 7 years
    @Flimm Good one, put 'jquery' as first record :). I updated my answer.
  • klewis
    klewis almost 6 years
    This is not working for me with Webpack 4.8.3. Did a process recently change? I have the plugin set in place. I also have jquery 3.3.1 installed via npm. I can run npm start, but the browser does not load jquery.
  • klewis
    klewis almost 6 years
    never-mind, I had to restart my entire environment. thanks for posting this answer!
  • user1063287
    user1063287 almost 6 years
    Are there any other steps required other than using code above and npm install jquery?
  • user1063287
    user1063287 almost 6 years
    When using single entry file with jQuery import, I get jQuery is not defined in chrome dev tools for this file (imported after jquery) : css-tricks.com/examples/Loadingdotdotdot/js/…
  • Niels Steenbeek
    Niels Steenbeek almost 6 years
    @user1063287 the import is local scope. When import statement is not in your mentioned file, it will not be available. Hack is maybe to import in the entry file and set global: window.jQuery = $. I have not enough background info to give a better suggestion.
  • rosinghal
    rosinghal about 5 years
    Thanks a lot. I was on the verge of beating my head against the wall.
  • hermeslm
    hermeslm over 4 years
    Just add that is needed to add "expose-loader" dependency to the project
  • Eugen Konkov
    Eugen Konkov over 2 years
    Also note, that you need to install expose-loader: ^1.0.0 other wise you will get: TypeError: this.getOptions is not a function, because expose-loader ^2.0.0 requires webpack 5