I am facing the exact same issue with my plugin Popup Maker. I found this select2 multiple versions on same page/site that may be useful, the only issue I forsee there is that we can't always control the order plugins load their JS using wp_enqueue_script.
Ok so what I did was made my script require select2 (DUH), then just inside my scripts enclosure I did something like this.
$.fn.pumSelect2 = $.fn.select2;
Then later instead of calling .select2() I use .pumSelect2().
This works great for my situation which is that I use v4, others use v3.5, some even bootstrap it into their own admin.js file so it loads even though select2 is already loaded.
So all in all its a hack but since we are doing it the right way by loading using wp_enqueue_script.
I also dequeue select2 if its enqueued.
// Deregister older versions, loaded by Types, Advanced Custom Fields etc.
if ( wp_script_is( 'select2', 'registered' ) ) {
wp_deregister_script( 'select2' );
}
wp_register_script( 'select2', $js_dir . 'select2.full' . $suffix, array( 'jquery' ), '4.0.1' );
`
Final Method For Now
After further testing and since so many other plugins use old versions with customizations that will likely break this is what I came up with.
In my select2.full.js file
For the opening section that loads jQuery and calls factory
(function (factory) {
var existingVersion = jQuery.fn.select2 || null;
if (existingVersion) {
delete jQuery.fn.select2;
}
if (typeof define === 'function' && define.amd !== undefined && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS
factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
jQuery.fn.pumselect2 = jQuery.fn.select2;
if (existingVersion) {
delete jQuery.fn.select2;
jQuery.fn.select2 = existingVersion;
}
}(function (jQuery) {
Basically I bootstrap it to a new name in this case pumselect2, and if there was previously a loaded version I restore it, otherwise I wipe the slate so that if another is loaded no conflict arises.
Also I modified my wp_enqueue_script handle to be pumselect2 so that it gets loaded even if someone else loads select2.
Hope that helps.