[javascript] Managing jQuery plugin dependency in webpack

I'm using Webpack in my application, in which I create two entry points - bundle.js for all my JavaScript files/codes, and vendors.js for all libraries like jQuery and React. What do I do in order to use plugins which have jQuery as their dependencies and I want to have them also in vendors.js? What if those plugins have multiple dependencies?

Currently I'm trying to use this jQuery plugin here - https://github.com/mbklein/jquery-elastic. The Webpack documentation mentions providePlugin and imports-loader. I used providePlugin, but still the jQuery object is not available. Here is how my webpack.config.js looks like-

var webpack = require('webpack');
var bower_dir = __dirname + '/bower_components';
var node_dir = __dirname + '/node_modules';
var lib_dir = __dirname + '/public/js/libs';

var config = {
    addVendor: function (name, path) {
        this.resolve.alias[name] = path;
        this.module.noParse.push(new RegExp(path));
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jquery: "jQuery",
            "window.jQuery": "jquery"
        }),
        new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', Infinity)
    ],
    entry: {
        app: ['./public/js/main.js'],
        vendors: ['react','jquery']
    },
    resolve: {
        alias: {
            'jquery': node_dir + '/jquery/dist/jquery.js',
            'jquery.elastic': lib_dir + '/jquery.elastic.source.js'
        }
    },
    output: {
        path: './public/js',
        filename: 'bundle.js'
    },
    module: {
        loaders: [
            { test: /\.js$/, loader: 'jsx-loader' },
            { test: /\.jquery.elastic.js$/, loader: 'imports-loader' }
        ]
    }
};
config.addVendor('react', bower_dir + '/react/react.min.js');
config.addVendor('jquery', node_dir + '/jquery/dist/jquery.js');
config.addVendor('jquery.elastic', lib_dir +'/jquery.elastic.source.js');

module.exports = config;

But in spite of this, it still throws an error in the browser console:

Uncaught ReferenceError: jQuery is not defined

Similarly, when I use the imports-loader, it throws an error,

require is not defined'

in this line:

var jQuery = require("jquery")

However, I could use the same plugin when I don't add it to my vendors.js file and instead required it in the normal AMD way as how I include my other JavaScript code files, like-

define(
[
    'jquery',
    'react',
    '../../common-functions',
    '../../libs/jquery.elastic.source'
],function($,React,commonFunctions){
    $("#myInput").elastic() //It works

});

But this is not what I want to do, as this would mean that jquery.elastic.source.js is bundled along with my JavaScript code in bundle.js, and I want all my jQuery plugins to be in the vendors.js bundle. So how do I go about achieving this?

This question is related to javascript jquery amd webpack

The answer is


In your webpack.config.js file add below:

 var webpack = require("webpack");
 plugins: [
    new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery"
    })
 ],

Install jQuery using npm:

$ npm i jquery --save

In app.js file add below lines:

import $ from 'jquery';
window.jQuery = $;
window.$ = $;

This worked for me. :)


This works in webpack 3:

in the webpack.config.babel.js file:

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

And use ProvidePlugin

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

I got things working nicely while exposing $ and jQuery as global variables with Webpack 3.8.1 and the following.

Install jQuery as a project dependency. You can omit @3.2.1 to install the latest version or specify another version.

npm install --save [email protected]

Install expose-loader as a development dependency if not installed already.

npm install expose-loader --save-dev

Configure Webpack to load and expose jQuery for us.

// webpack.config.js
const webpack = require('webpack')

module.exports = {
  entry: [
    // entry bits
  ],
  output: {
    // output bits
  },
  module: {
    rules: [
      // any other rules
      {
        // Exposes jQuery for use outside Webpack build
        test: require.resolve('jquery'),
        use: [{
          loader: 'expose-loader',
          options: 'jQuery'
        },{
          loader: 'expose-loader',
          options: '$'
        }]
      }
    ]
  },
  plugins: [
    // Provides jQuery for other JS bundled with Webpack
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    })
  ]
}

Add this to your plugins array in webpack.config.js

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

then require jquery normally

require('jquery');

If pain persists getting other scripts to see it, try explicitly placing it in the global context via (in the entry js)

window.$ = jQuery;

This works for me on the webpack.config.js

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

in another javascript or into HTML add:

global.jQuery = require('jquery');

For global access to jquery then several options exist. In my most recent webpack project, I wanted global access to jquery so I added the following to my plugins declarations:

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

This then means that jquery is accessible from within the JavaScript source code via global references $ and jQuery.

Of course, you need to have also installed jquery via npm:

$ npm i jquery --save

For a working example of this approach please feel free to fork my app on github


The best solution I've found was:

https://github.com/angular/angular-cli/issues/5139#issuecomment-283634059

Basically, you need to include a dummy variable on typings.d.ts, remove any "import * as $ from 'jquery" from your code, and then manually add a tag to jQuery script to your SPA html. This way, webpack won't be in your way, and you should be able to access the same global jQuery variable in all your scripts.


I don't know if I understand very well what you are trying to do, but I had to use jQuery plugins that required jQuery to be in the global context (window) and I put the following in my entry.js:

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

The I just have to require wherever i want the jqueryplugin.min.js and window.$ is extended with the plugin as expected.


Edit: Sometimes you want to use webpack simply as a module bundler for a simple web project - to keep your own code organized. The following solution is for those who just want an external library to work as expected inside their modules - without using a lot of time diving into webpack setups. (Edited after -1)

Quick and simple (es6) solution if you’re still struggling or want to avoid externals config / additional webpack plugin config:

<script src="cdn/jquery.js"></script>
<script src="cdn/underscore.js"></script>
<script src="etc.js"></script>
<script src="bundle.js"></script>

inside a module:

const { jQuery: $, Underscore: _, etc } = window;

I tried some of the supplied answers but none of them seemed to work. Then I tried this:

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

Seems to work no matter which version I'm using


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to amd

Managing jQuery plugin dependency in webpack Relation between CommonJS, AMD and RequireJS? Is it possible to run CUDA on AMD GPUs?

Examples related to webpack

Error: Node Sass version 5.0.0 is incompatible with ^4.0.0 Support for the experimental syntax 'classProperties' isn't currently enabled npx command not found where is create-react-app webpack config and files? How can I go back/route-back on vue-router? webpack: Module not found: Error: Can't resolve (with relative path) Refused to load the font 'data:font/woff.....'it violates the following Content Security Policy directive: "default-src 'self'". Note that 'font-src' The create-react-app imports restriction outside of src directory How to import image (.svg, .png ) in a React Component How to include css files in Vue 2