The Mysterious Case of webpack, AngularJS and jQuery
You may know that Angular ships with a cutdown version of jQuery called jQLite. It's still possible to use the full-fat jQuery; to quote the docs:
To use
jQuery
, simply ensure it is loaded before theangular.js
file.
Now the wording rather implies that you're not using any module loader / bundler. Rather that all files are being loaded via script
tags and relies on the global variables that result from that. True enough, if you take a look at the Angular source you can see how this works:
// bind to jQuery if present;
var jqName = jq();
jQuery = isUndefined(jqName)
? window.jQuery // use jQuery (if present)
: !jqName
? undefined // use jqLite
: window[jqName]; // use jQuery specified by `ngJq`
Amongst other things it looks for a jQuery
variable which has been placed onto the window
object. If it is found then jQuery is used; if it is not then it's jqLite
all the way.
But wait! I'm using webpack
Me too! And one of the reasons is that we get to move away from reliance upon the global scope and towards proper modularisation. So how do we get Angular to use jQuery given the code we've seen above? Well, your first thought might be to npm install
yourself some jQuery
and then make sure you've got something like this in your entry file:
import 'jquery'; // This'll fix it... Right?
import * as angular from 'angular';
Wrong.
You need the ProvidePlugin
In your webpack.config.js
you need to add the following entry to your plugins:
new webpack.ProvidePlugin({
"window.jQuery": "jquery"
}),
This uses the webpack ProvidePlugin
and, at the point of webpackification (© 2016 John Reilly) all references in the code to window.jQuery
will be replaced with a reference to the webpack module that contains jQuery. So when you look at the bundled file you'll see that the code that checks the window
object for jQuery
has become this:
jQuery = isUndefined(jqName)
? __webpack_provided_window_dot_jQuery // use jQuery (if present)
: !jqName
? undefined // use jqLite
: window[jqName]; // use jQuery specified by `ngJq`
That's right; webpack is providing Angular with jQuery whilst still not placing a jQuery
variable onto the window
. Neat huh?