UNPKG

5.76 kBMarkdownView Raw
1# Jenkins JavaScript Extensions
2
3Jenkins JavaScript Extensions are extensions which contribute to the UI in Jenkins BlueOcean.
4This module is used to define extension points - locations where the application accepts plugin-provided implementations.
5This module is also used to process the plugin extension point implementations to provide to BlueOcean.
6
7This module is published via npm as `@jenkins-cd/js-extensions` so that other plugins, external to the blueocean project, can make use of it.
8Plugins can themselves make use of extension points.
9
10Jenkins JavaScript Extensions are based on the extensibility model already established by Jenkins, based on data and views, with the ability to inherit views based on parent data types.
11
12Jenkins JavaScript Extensions: `@jenkins-cd/js-extensions` module exports:
13- `Renderer` - a React component to conveniently render extensions
14- `store` - the `ExtensionStore` instance (which must be initialized before it can be used)
15- `classMetadataStore` - class/capability metadata store
16- `dataType()` - function for filtering extensions based on the data type
17- `componentType()` - function for filtering extensions based on the required component type (e.g. React class)
18
19### ExtensionStore API
20
21The `ExtensionStore` API is very simple, all public methods are asynchronous:
22
23- `getExtensions(extensionPointName, [filter,] onload)`
24 This method will async load data, filter the extensions based on the provided `filter`s, and call the onload handler with a list of extension exports, e.g. the React classes or otherwise exported references.
25 `filter` - a filter function currently the module exports the following functions - see the exported functions for the commonly used filters
26
27### ClassMetadataStore API
28
29- `getClassMetadata(dataType, onload)`
30 This will return a list of type information, from the [classes API](../blueocean-rest/README.md#classes_API), this method also handles caching results locally.
31
32### Rendering extension points
33
34The most common usage pattern is to use the exported `Renderer`, specifying the extension point name, any necessary contextual data, and optionally specifying a data type.
35
36 import Extensions from '@jenkins-cd/js-extensions';
37 ...
38 <Extensions.Renderer extensionPoint="jenkins.navigation.top.menu" />
39
40For example, rendering the test results for a build may be scoped to the specific type of test results in this manner:
41
42 <Extensions.Renderer extensionPoint="test-results-view" filter={dataType(data)} testResults={data} />
43
44The `ExtensionRenderer` component optionally uses the [classes API](../blueocean-rest/README.md#classes_API) to look up an appropriate, specific set of views for the data being displayed.
45This should works seamlessly with other [capabilities](../blueocean-rest/README.md#capabilities).
46
47
48### Defining extension point implementations
49
50Extensions are defined in a `jenkins-js-extensions.yaml` file in the javascript source directory of a plugin by defining a list of extensions similar to this:
51
52 # Extensions in this plugin
53 extensions:
54 - component: AboutNavLink
55 extensionPoint: jenkins.topNavigation.menu
56 - component: components/tests/AbstractTestResult
57 extensionPoint: jenkins.test.result
58 dataType: hudson.tasks.test.AbstractTestResultAction
59
60Properties are:
61- `component`: a module from which the default export will be used
62- `extensionPoint`: the extension point name
63- `dataType`: an optional Java data type this extension handles
64
65For example, the `AboutNavLink` might be defined as a default export:
66
67 export default class NavLink extends React.Component {
68 ...
69 }
70
71#### Enforcing specific component types
72
73In order to ensure a specific component is returned, an extension point may also use the `componentType` filter - it accepts an object prototype (e.g. an ES6 class), e.g.:
74
75 import TestResults from './base-components/TestResults';
76 ...
77 <Extensions.Renderer extensionPoint="test-view" filter={componentType(TestResults)} ... />
78
79Extensions are not limited to React components.
80The `componentType` filter will attempt to match returned components by a series of prototype and typeof checks to appropriately filter returned types including ES6 classes.
81
82### i18n resource pre-loading
83
84By default, all `@jenkins-cd/js-extensions` generated JavaScript bundles will automatically preload the i18n resource bundles it finds in the
85 `src/main/resources/jenkins/plugins/[pluginId]`, where `pluginId` is the Jenkins HPI plugin ID with all hyphen characters replaced by a path separator
86 e.g. for `blueocean-dashboard`, the path that is searched is `src/main/resources/jenkins/plugins/blueocean/dashboard`.
87
88> See `findI18nBundles()` in [@jenkins-cd/subs/extensions-bundle.js](@jenkins-cd/subs/extensions-bundle.js)
89
90In some situations, a `@jenkins-cd/js-extensions` generated bundle may depend on i18n resources that are not in the default location or not in the host plugin (e.g. they may be defined in a "common" style utility plugin). In this situation,
91 your plugin needs to know about these i18n resources in order to generate the right pre-loading code into the generated bundle. To tell `@jenkins-cd/js-extensions` about the resources in the other plugin, you need to manually define a `i18nBundles`
92 list in the `jenkins-js-extensions.yaml` e.g.
93
94```yaml
95extensions:
96 # etc ....
97
98i18nBundles:
99 - jenkins.plugins.aaa.Messages
100 - hpiPluginId: acme-commons
101 resource: jenkins.plugins.acme.commons.Messages
102```
103
104> Note how `i18nBundles` entries can define a string or an object, allowing the loading of bundles from plugins other than the default (i.e. the same plugin as the `@jenkins-cd/js-extensions` generated JavaScript bundle).
105