node package manager
Painless code sharing. npm Orgs help your team discover, share, and reuse code. Create a free org »

@jenkins-cd/js-modules

JIRA

This is a JavaScript "module bundle" loader for Jenkins (NPM package) i.e. a loader for loading a JavaScript file that contains one or more CommonJS/node.js style modules in a single HTTP request (i.e. a "bundle").

For more information on "module bundle" loading, read the What does "module loading" mean FAQ.

Table of Contents:


Usage

For the most part, you don't actually use js-modules directly (aside from installing the package). In general, you use it via js-builder i.e. you use js-builder to build browser-loadable bundles, and those bundles will use js-modules to load/"import" the modules/packages that they depend on, but do not contain within their bundle.

js-builder

Install Package:

npm install --save @jenkins-cd/js-modules

After installing js-modules, your next step is to start using js-builder and, as stated above, that's mostly all you'll ever need to know about js-modules because the rest of it happens under the hood via js-builder.

That said, it's probably useful to have an understanding of how js-modules actually loads modules/packages. For that, take a look at MODULE_LOADING.md.

Problem / Motivation

For the most part, the Jenkins GUI is constructed on the server side from Jelly files (Stapler etc). Client-side JavaScript has not played a big part in the Jenkins GUI.

If the Jenkins GUI is to be modernized and improved (from a user experience perspective), client-side JavaScript needs to be able to play a bigger part. If that's so, we need to modernize/improve the development patterns around how JavaScript is currently used in Jenkins.

As we see it, the main issues today are:

  1. Modularity: Jenkins currently has no concept of modularity when it comes to the JavaScript code used in the GUI. All of the JavaScript is concentrated mainly in a single JavaScript file i.e. hudson-behaviour.js.
  2. Anti-Patterns: Too much JavaScript code is bound into the global scope, creating a litany of well known issues.
  3. Testability: Not easy to write JavaScript unit tests. The only way JavaScript is tested is via JenkinsRule (HtmlUnit and it's WebClient).
  4. Multiple versions of Framework Libraries: One version of Prototype/jQuery doesn’t fit all. We need a way of supporting multiple versions of the same library (e.g. jQuery) in a way that works in the browser, "detached" from the global scope. We need to be able to introduce new versions of libraries (and deprecate old versions) in an orderly fashion.

These are the problems that js-modules (this NPM package) is targeted at helping to solve.

It is hoped that js-modules will help those that are interested (see next section) in maintaining modular, unit testable, evolvable (see note below) JavaScript code that runs in a more predictable/stable environment that is more immune to plugin updates etc (e.g. an upgrade to the jQuery plugin doesn't break the plugin GUI). Using CommonJS style modularity also makes it possible to more easily leverage the growing set of publicly available NPM/node.js packages, which is a huge benefit.

What do we mean by "evolvable"?: js-modules makes it possible to safely run multiple versions of core JavaScript Framework libs on the same page (jQuery, Bootstrap etc). This makes it possible for modular code (built on js-modules) to depend on an explicit version of a JS lib that is guaranteed to remain available on e.g. plugin upgrades. Conversely, the same modular code can upgrade the version of a lib it depends on without effecting other modular code that still depends on an older version.

Do I need to learn all this "new" stuff?

No, this is totally optional. See FAQ

About Jenkins Modules

The following slides attempt to bring you through js-modules in some more detail.

About Jenkins Modules

Also check out the FAQs.

Support Modules

The following NPM packages are designed to aid the use and adoption of js-modules:

  • js-builder: See this package for details on how to create module bundles for js-modules.
  • js-test: See this package for details on how to test modules for module bundles for js-modules. This package's functionality is indirectly available via js-builder.

Framework Libs (jenkinsci/js-libs)

Framework libs are located in jenkinsci/js-libs.

As stated earlier, using CommonJS style modularity makes it possible to more easily leverage the growing set of publicly available NPM/node.js packages. If you want to use some really cool NPM package that you just found, all you need to do is follow the "standard" NPM package installation process, adding it to your "app" bundle e.g. npm install --save cool-new-lib.

This is great, but if followed all the way, your JavaScript "app" bundles will soon become quite heavy for the browser to load because they will contain all JavaScript required by all the modules in the bundle.

The main feature of js-modules is it's ability to load module bundles that can export / import modules to/from other modules bundles i.e. share common modules between bundles (see above slides). This means we can create js-modules style module bundles for different versions of all of the major JavaScript Framework libs out there (jQuery, Bootstrap etc), making it possible for "app" bundles to share common Framework libs and to not have them in their "app" bundle, making them considerably lighter for browser load and helping to avoid the bundle bloat problem.

We have already created Framework lib bundles for a number of common JavaScript libs (jQuery, Bootstrap and more).

Framework libs are located in jenkinsci/js-libs.