问题
On a website, I bundle all the javascript with Gulp into one bundle file. This includes jQuery, which I import into all the JS files that require it.
I include the Google Tag Manager (GTM) directly in the HTML. However, some of the custom tags require jQuery, which is undefined according to browser console output. I assume jQuery is not exposed outside the bundle.
How do I expose jQuery from the bundle so external scripts such as GTM can use it?
回答1:
Solution
Got the idea from jqfundamental's jQuery Basics Guide:
import $ from 'jquery';
// make jquery available to all imports using `window` to load jQuery
window.jQuery = window.$ = $;
With these two lines, the jQuery version loaded via import (in my case the one I specified in my Node package.json) will be assigned to the window object, from which most jQuery plugins as well as GTM custom tags load jQuery.
I put this statement on top of my main js file. This way I make sure that all imported jQuery plugins can access jQuery via window, as well.
Why this works
For everyone not completely aware of it: All properties of the window object are globally available with their key name:
window.foo = 'someValue';
console.log(foo);
// outputs 'someValue' even if used in a different scope/file/module
If this doesn't work
Check the last line of your plugin code: Some plugins load jQuery from this.jQuery instead of window.jQuery.
Usually, this in JS scripts on the top level points to window, so above approach works. However, in ES6 modules - and as such the bundle code is run in the browser - this is undefined (see this exploringjs table for reference).
I haven't found a good solution other than adjusting the plugin code to use window.jQuery. See this related question (unanswered at the time of writing).
Reason for this issue
Stumbled upon this issue which explains the reason for this behavior quite well: The jQuery code contains a conditional testing for module being defined and an object:
if ( typeof module === "object" && typeof module.exports === "object" ){
// set jQuery in `module`
} else {
// set jQuery in `window`
}
In Nodejs, module is an object even in the browser, thus jQuery is not globally available by default, but only in the current scope of the import.
来源:https://stackoverflow.com/questions/47057729/how-do-i-make-jquery-from-a-es6-bundle-available-to-external-scripts-loaded-in-t