Skip to content

3rd Party Dependencies

Spencer edited this page Jan 28, 2016 · 3 revisions

While developing plugins for use in the Kibana front-end environment you will probably want to include a library or two (at least). While that should be simple to do 90% of the time, there are always outliers, and some of those outliers are very popular projects.

installation

Before you can use an external library with Kibana you have to install it. You do that using...

npm

With npm available pulling in a library will be very simple, most of the time. Unfortunately the trend of publishing browser libraries to npm is fairly new, and many mature browser-only libraries have not made the jump quite yet.

If you are able to find the library you want on npm then installing and using it looks like this:

# in your terminal, cd into your plugin
cd installedPlugins/your_plugin
# install the library and save it as a dependency
npm install --save some-neat-library
// in your_plugin_code.js just import the library using it's name
import someNeatLibrary from 'some-neat-library';

Just like working in node.js, front-end code can require node modules installed by npm without any additional configuration.

when something isn't available on npm

When a library you want to use is not available on npm you have several options. They are listed in the preferred order, but any of them should do.

publish it as a @scoped/package

If the code for a project would work perfectly with npm, but simply needs to be on npm, we prefer to publish it as a @scoped/package (see package.json). Unless you have coordinated with the library owner, or plan to maintain the mirror yourself, please don't publish libraries using their common name.

Once you have published the version of the library you want to use, simply install it in your project as outlined above.

copy the library to webpackShims

If you aren't comfortable publishing a library to npm, or are otherwise prevented from doing so, your other option is to save the library inside a webpackShims directory. For more information checkout the webpackShims article.

# in your terminal, cd into your plugin
cd installedPlugins/your_plugin
# create a directory for our new library to live
mkdir -p webpackShims/some-neat-library
# download the library you want to use into that directory
curl https://cdnjs.com/some-neat-library/library.js > webpackShims/some-neat-library/index.js
// in your_plugin_code.js just import the library using it's name
import someNeatLibrary from 'some-neat-library';

shimming third party code

As a user of common.js and the npm ecosystem it is easy to forget that lots of JavaScript code written today does not declare its dependencies in a way that tools like webpack can understand. It is also often the case that libraries do not export their provided values, but simply write them to a global variable name (or something to that effect).

When pulling code like this into Kibana we need to write "shims" that will adapt the third party code to work with our application, other libraries, and module system. To do this we can utilize the webpackShims directory, which is detailed in the webpackShims article.

The easiest way to explain how to write a shim is to show you some. Here is our webpack shim for jQuery:

// webpackShims/jquery.js

module.exports = window.jQuery = window.$ = require('node_modules/jquery/dist/jquery');
require('ui/jquery/findTestSubject')(window.$);

This shim is loaded up anytime an import 'jquery'; statement is found by webpack, because of the way that webpackShims behaves like node_modules. When that happens, the shim does two things:

  1. assign the exported value of the actual jQuery module to the window at $ and jQuery, allowing libraries like angular to detect that jQuery is available, and use it as the module's export value.
  2. finally, a jQuery plugin that we wrote is included so that every time a file imports jQuery it will get both jQuery and the $.findTestSubject helper function.

Here is what our webpack shim for angular looks like:

// webpackShims/angular.js

require('jquery');
require('node_modules/angular/angular');
require('node_modules/angular-elastic/elastic');
require('ui/modules').get('kibana', ['monospaced.elastic']);
module.exports = window.angular;

What this shim does is fairly simple if you go line by line:

  1. makes sure that jQuery is loaded before angular (which actually runs the shim above)
  2. load the angular.js file from the npm installation
  3. load the angular-elastic plugin, a plugin we want to always be included whenever we import angular
  4. use the ui/modules module to add the module exported by angular-elastic as a dependency to the kibana angular module
  5. finally, export the window.angular variable. This means that writing import angular from 'angular'; will properly set the angular variable to the angular library, rather than undefined which is the default behavior.