I have a gulp task to run webpack to bundle my files. I'm trying to use jQuery with typeahead.js, but the call to require('jquery')
inside the typeahead.js file seems to be loading a new jQuery object instead of using the one at the "global" scope as created by ProvidePlugin
. How do I add a jQuery plugin to the jQuery instance created by ProvidePlugin
?
Here is my gulp task:
gulp.task("bundlejs", function(cb) {
pump([
gulp.src("js/index.js"),
webpack({
output: { filename: BUNDLE_NAME },
plugins: [
new webpack.webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
],
devtool: 'source-map'
}),
gulp.dest(OUTPUT_JS)
], cb);
});
And inside an imported module:
require("imports-loader?define=>false!typeahead.js");
console.info($.fn.typeahead); // <== prints 'undefined'
Just for some additional information, the top of the typeahead bundle looks like this (full file here):
(function(root, factory) {
if (typeof define === "function" && define.amd) {
define("bloodhound", [ "jquery" ], function(a0) {
return root["Bloodhound"] = factory(a0);
});
} else if (typeof exports === "object") {
module.exports = factory(require("jquery")); // <== this line gets called
} else {
root["Bloodhound"] = factory(jQuery);
}
})( ... );
What am I doing wrong?
Update
Per the comment stream, here is what I'm getting with my unique ID code.
Here is my /path/to/unique-id.js file:
var id = 0;
module.exports = function(o) {
if (typeof o.__uniqueid == "undefined") {
Object.defineProperty(o, "__uniqueid", {
value: ++id,
enumerable: false,
writable: false
});
}
return o.__uniqueid;
};
Using var u = require('/path/to/unique-id.js')
...
In my Application.js file (the one where I use require("imports-loader?define=>false!typeahead.js")
:
console.info(u($)); // <== prints 1
console.info(u(jQuery)); // <== prints 1
console.info(u(window.jQuery)); // <== prints 1
console.info(u(require('jquery'))); // <== prints 1
I modified typeahead.bundle.js to include some calls as well:
(function(root, factory) {
if (typeof define === "function" && define.amd) {
define("bloodhound", [ "jquery" ], function(a0) {
return root["Bloodhound"] = factory(a0);
});
} else if (typeof exports === "object") {
console.info(u(window.$)); // <== this prints 1, like I want
console.info(u(require('jquery')); // <== this prints 2
console.info(u(require('jquery')); // <== this prints 2
module.exports = factory(require("jquery")); // <== original module code
} else {
root["Bloodhound"] = factory(jQuery);
}
})( ... );
Update 2 (lame solution)
In the spirit of progressive problem solving and transparency, I got it to work in this kludgey way:
require("imports-loader?exports=>false,define=>false,jQuery=>window.$!typeahead.js");
I don't like this way at all, so any other answers would be appreciated.
Update 3 (another solution using another library)
I ended up switching to selectize and had to use an even lamer solution, but I thought it might help someone else going through the same problems as me:
In the module:
var selectizeRoot = {
jQuery: require('jquery'),
Sifter: require('sifter'),
MicroPlugin: require('microplugin')
};
require('imports-loader?define=>false,exports=>false,this=>selectizeRoot!selectize');
This forced the jQuery used in my modules (and apparently the ProvidePlugin) into the function that adds the selectize plugin to jQuery.