Module bundles for jQuery and jQuery UI (via jquery-detached and jqueryui-detached) (see jenkins-js-modules).
Note: DEPRECATED This JavaScript library can now be easily externalized via the package.json.
import this bundle (see jenkins-js-modules) into your application bundle (in your plugin etc) instead of bundling
jQuery or jQuery UI in your application bundle, making your app bundle considerably lighter.
importing the jQuery UI bundle will also result in the jQuery UI CSS being added to the page (namespaced).
See below for more details.
HPI Dependency
Your plugin needs to add a dependency on this plugin (to ensure it gets installed in Jenkins).
<artifactItem>
<groupId>org.jenkins-ci.ui</groupId>
<artifactId>jquery-detached</artifactId>
<version>[VERSION]</version>
</artifactItem>
See wiki.jenkins-ci.org to get the latest version.
Using jQuery v2:
(Scroll down for jQuery UI docs)
- Bundle Id:
jquery-detached:jquery2
There are 2 ways of using jquery-detached:jquery2 in your app bundle:
- Normal
requiresyntax (synchronous) on thejquery-detached@2NPM module, and then using awithExternalModuleMappinginstruction (jenkins-js-builder) in the app bundle'sgulpfile.js. - Lower level
importsyntax (asynchronous).
require (sync)
If using jenkins-js-builder to create yor application bundle, you can code your application's CommonJS modules to
use the more simple CommonJS style require syntax (synch), as opposed to the lower level import syntax (async)
of jenkins-js-modules.
When doing it this way, your module code should require the jquery-detached@2 NPM module and
call getJQuery to get the jQuery ($) instance e.g.
var $ = require('jquery-detached').getJQuery();
var header = $('#header');
Note: You should install
jquery-detached@2as a dev dependency i.e.npm install --save-dev jquery-detached@2
The above code will work fine as is, but the only downside is that your app bundle will be very bloated as it will
include jQuery. To lighten your bundle for the browser (by using a shared instance of jQuery),
use jenkins-js-builder to create your app bundle (in your gulpfile.js), telling it to "map" (transform) all
synchronous require calls for jquery-detached to async imports of the jquery-detached:jquery2
bundle module (which actually exports jquery-detached) e.g.
var builder = require('jenkins-js-builder');
//
// Use the predefined tasks from jenkins-js-builder.
//
builder.defineTasks(['test', 'bundle']);
//
// Create the app bundle, mapping sync require calls for 'jquery-detached' to
// async imports of 'jquery-detached:jquery2'.
//
builder.bundle('src/main/js/myapp.js')
.withExternalModuleMapping('jquery-detached', 'jquery-detached:jquery2')
.inDir('src/main/webapp/bundles');
All of the above "magically" translates the appropriate bits of your app bundle's JS code to use async import calls
(see below) in a way that just works.
import (async)
You can also use the lower level asynchronous import call (jenkins-js-modules) to get your $ reference.
require('jenkins-js-modules')
.import('jquery-detached:jquery2')
.onFulfilled(function(jQuery) {
var $ = jQuery.getJQuery();
var header = $('#header');
});
Note: Using this async
importapproach makes unit testing of your JavaScript modules more tricky because your test scaffolding code will need to manuallyexportthejquery-detachedmodule asjquery-detached:jquery2in order for the subsequentimportto work without failure. This is not an issue when using the synchronousrequireapproach (see above) because the bundleimportis only introduced to the JS code as the bundle is being created.
Using jQuery UI v1:
- Bundle Id:
jquery-detached:jqueryui1 - CSS Namespace:
jquery-ui-1(see below for more details)
There are 2 ways of using jquery-detached:jqueryui1 in your app bundle:
- Normal
requiresyntax (synchronous) on thejqueryui-detached@1NPM module, and then using awithExternalModuleMappinginstruction (jenkins-js-builder) in the app bundle'sgulpfile.js. - Lower level
importsyntax (asynchronous).
require (sync)
If using jenkins-js-builder to create yor application bundle, you can code your application's CommonJS modules to
use the more simple CommonJS style require syntax (synch), as opposed to the lower level import syntax (async)
of jenkins-js-modules.
When doing it this way, your module code should require the jqueryui-detached NPM module and
call getJQueryUI to get the jQuery UI instance (a clean/pristine jQuery instance decorated with the
jQuery UI plugin) e.g.
var $ui = require('jqueryui-detached').getJQueryUI();
$ui("#dialog").dialog();
Note: You should install
jqueryui-detachedas a dev dependency i.e.npm install --save-dev jqueryui-detached@1
The above code will work fine as is, but the only downside is that your app bundle will be very bloated as it will
include both jQuery and jQuery UI. To lighten your bundle for the browser (by using a shared instance of jQuery UI),
use jenkins-js-builder to create your app bundle (in your gulpfile.js), telling it to "map" (transform) all
synchronous require calls for jqueryui-detached to async imports of the jquery-detached:jqueryui1
bundle (which actually exports jqueryui-detached) e.g.
var builder = require('jenkins-js-builder');
//
// Use the predefined tasks from jenkins-js-builder.
//
builder.defineTasks(['test', 'bundle']);
//
// Create the app bundle, mapping sync require calls for 'jqueryui-detached' to
// async imports of 'jquery-detached:jqueryui1'.
//
builder.bundle('src/main/js/myapp.js')
.withExternalModuleMapping('jqueryui-detached', 'jquery-detached:jqueryui1')
.inDir('src/main/webapp/bundles');
All of the above "magically" translates the appropriate bits of your app bundle's JS code to use async import calls
(see below) in a way that just works.
import (async)
You can also use the lower level asynchronous import call (jenkins-js-modules) to get your $ui reference.
require('jenkins-js-modules')
.import('jquery-detached:jqueryui1')
.onFulfilled(function(jQueryUI) {
$ui = jQueryUI.getJQueryUI();
$ui("#dialog").dialog();
});
Note: Using this async
importapproach makes unit testing of your JavaScript modules more tricky because your test scaffolding code will need to manuallyexportthejqueryui-detachedmodule asjquery-detached:jqueryui1in order for the subsequentimportto work without failure. This is not an issue when using the synchronousrequireapproach (see above) because the bundleimportis only introduced to the JS code as the bundle is being created.
CSS Namespacing / Scoping
importing this bundle will also result in the jQuery UI CSS being added to the page (namespaced).
In order to apply jQuery UI v1 CSS rules to portions of page markup, the markup will need to be enclosed in an element
containing the jquery-ui-1 class.
<div class="jquery-ui-1">
<!-- content in here can use jQuery UI v1 CSS rules. -->
<div>
Note: Namespacing the CSS rules makes it safer to use multiple versions of the same CSS lib on the same page.
Namespacing pitfalls
The above trick of wrapping the content in a <div class="jquery-ui-1"> will not work for all jQuery UI
widgets because, in some cases, jQuery UI will unwrap the content and move it somewhere else before rendering. The
Dialog is one such widget that exhibits this behaviour (and apparently
Autocomplete too).
Working around this is not all that difficult, but is a bit of a pain. The trick is to do the namespace wrapping
via JavaScript after the Dialog has been rendered (and jQuery UI has done it's thing). In the case of the
Dialog widget, it offers a dialogClass configuration option which can help with locating of the dialog
post rendering.
$('#modal-dialog-content').dialog({
dialogClass: "jenkins-plugin-XYZ-dialog",
modal: true,
buttons: {
Ok: function () {
$(this).dialog("close");
// etc
}
}
});
// Use the dialogClass (from the options - see above) to locate
// the dialog and then wrap...
$('.jenkins-plugin-XYZ-dialog').wrap('<div class="jquery-ui-1"></div>');