2.4 | The Cubbles Dependency API
Introduction
The Cubbles platform comes with an own dependency management mechanism. In the following we will describe how you can use the API provided by the platform to handle dependencies. This in particular means
- How to add additional dependencies
- How to exclude one or more dependencies
- How to replace existing dependencies
A dependency of an artifact is another required artifact. In most cases those required artifacts will be compound components, elementary components or utilities.
Note
We strongly recommend you to read and understand the section before you proceed!
Prerequisites
Assuming we do have included a <first-demo-component>
component instance into our index.html
. Furthermore in this example the <f
irst-demo-component>
should be a compound component. Thus we do have several dependencies that our compound component needs to work as expected.
The dependency tree of first-demo-component
looks as follows:
demo-package@1.0/first-demo-component // we call this a root dependency | |- another-demo-package@1.0/demo-elementary-component | | | |- third-party-lib@1.0/awesome-lib-util | |- demo-package@1.0/my-utility
As a page editor or html developer that just wants to use the first-demo-component
from the webpackage demo-package@1.0
you don't need to take care about including all the needed dependencies (and their coresponding resources) into the page's <head>
area.
The dependency resolving mechanism inside the RTE does all the magic to ensure all of these needed resources are included into the page's head
to make the first-demo-component
work as expected. Duplicated dependencies are also removed.
<head> ... </head> <body> ... <first-demo-component cubx-webpackage-id="demo-package@1.0"> </first-demo-component> ... </body>
<head> ... <!-- Note: this is just for explanation purposes! In fact each artifact comes with a list of ordinary web resources like JS, HTML or CSS files which will be included by DependencyManager of the RTE. --> <link rel="import" href="third-party-lib@1.0/awesome-lib-util"> <link rel="import" href="another-demo-package@1.0/demo-elementary-component"> <link rel="import" href="demo-package@1.0/my-utility"> <link rel="import" href="demo-package@1.0/first-demo-component"> ... </head> <body> ... <first-demo-component cubx-webpackage-id="demo-package@1.0"> </first-demo-component> ... </body>
Adding additional artifacts to existing dependencies
In some cases you might want to add some additional dependencies to the existing ones that come from the used components. Normally you are using components out-of-the-box and are not able or willing to manipulate their dependencies by editing the corresponding manifest.webpackage
file. This can be because you don't want to release a new version of the component only for the sake of adjusting their dependency list. Or simply because of the fact that you are not the owner of the used component.
The Cubbles API provides several ways of adding additional dependencies to the existing list of dependencies without changing the used components itself.
Adding a dependency using the Cubbles TAG API
One way to add dependencies is using the <cubx-dependencies>
and <cubx-dependency>
tags inside a custom tag of a cubbles component. This is useful when you are restricted to edit only small snippets of a page's html body. For example assume that you are editing content of a Wordpress post. In that case you normally don't have access to the whole html tree of a page but rather can edit html in content section.
In our example on the right hand side we use the Cubbles TAG API to add a new artifact dependency second-demo-utility
from webpackage third-party-pkg@1.0
. Internally the RTE adjusts the dependency tree by adding the new artifact as new root dependency (Note: the new dependency will be inserted before the existing dependencies into list of root dependencies). The resulting dependency tree will look as follows:
third-party-pkg@1.0/second-demo-utility // adding an new root dependency | |-- ... demo-package@1.0/first-demo-component | |- another-demo-package@1.0/demo-elementary-component | | | |- third-party-lib@1.0/awesome-lib-util | |- demo-package@1.0/my-utility
- Each custom html tag representing a cubbles component can have exactly one
<cubx-dependencies>
child - The
<cubx-dependencies>
element can have 1..n<cubx-dependency>
children with attributesartifact-id
(mandatory)webpackage-id
(optional. If no webpackage-id is given then the artifact will be searched in the same webpackacke like the parent cubbles component. In example above this would bedemo-package@1.0
endpoint-id
(optional, needed when referencing an artifact with webpackage.modelVersion < 9)
<head> ... </head> <body> ... <first-demo-component cubx-webpackage-id="demo-package@1.0"> <cubx-dependencies> <cubx-dependency artifact-id="second-demo-utility" webpackage-id="third-party-pkg@1.0"></cubx-dependency> </cubx-dependencies> </first-demo-component> ... </body>
Adding a dependency using the global window.cubx.CRCInit
object
Besides the Cubbles TAG API you can add dependencies using the global property window.cubx.CRCInit.rootDependencies
This property is an array of items where each item defines a root dependency holding the properties
webpackageId
(mandatory)artifactId
(mandatory)endpointId
(optional when referencing artifacts with webpackage.modelVersioin < 9)
The resulting dependency tree for the left hand side example will be equal to the one displayed in the last section above.
<head> ... <!-- The below script block needs to be placed before(!) the crc-loader script is included --> <script> window.cubx = { CRCInit: { rootDependencies: [ { webpackageId: 'third-party-pkg@1.0', artifactId: 'second-demo-utility' } ] } }; </script> ... </head> <body> ... <first-demo-component cubx-webpackage-id="demo-package@1.0"> </first-demo-component> ... </body>
Exclude certain artifacts from existing dependencies
Similar to adding dependencies it can be useful to exclude specific dependencies. Consider for example a scenario where you do already have the jQuery library on a web page but the cubbles component you want to use also comes with jQuery in it's own dependencies. Thus it would be great if you could exclude jQuery in the dependencies to avoid naming conflicts in global javascript scope.
Exclude a dependency using the Cubbles TAG API
Analogous to adding dependencies you can use the <cubx-dependency-excludes>
and <cubx-depdency-exclude>
to exclude one or more dependencies from an artifacts dependency tree.
demo-package@1.0/first-demo-component | |- another-demo-package@1.0/demo-elementary-component | | | |- third-party-lib@1.0/awesome-lib-util // this package is excluded! | |- demo-package@1.0/my-utility
The resulting dependency tree would look as follows:
demo-package@1.0/first-demo-component | |- another-demo-package@1.0/demo-elementary-component | |- demo-package@1.0/my-utility
- Each custom html tag representing a cubbles component can have exactly one
<cubx-dependency-excludes>
child - The
<cubx-dependency-excludes>
element can have 1..n<cubx-dependency-exclude>
children with attributesartifact-id
(mandatory)webpackage-id
(optional. If no webpackage-id is given then the artifact will be searched in the same webpackacke like the parent cubbles component. In example above this would bedemo-package@1.0
endpoint-id
(optional, needed when referencing an artifact with webpackage.modelVersion < 9)
<head> ... </head> <body> ... <first-demo-component cubx-webpackage-id="demo-package@1.0"> <cubx-dependency-excludes> <cubx-dependency-exclude artifact-id="awesome-lib-util" webpackage-id="third-party-lib@1.0"> </cubx-dependency-exclude> </cubx-dependency-excludes> </first-demo-component> ... </body>
Exclude a dependency using the global window.cubx.CRCInit
object
Dependency excludes can also be added using the global window.cubx.CRCInit.rootDependencyExcludes
property.
This property is an array of items where each item defines a root dependency exclude holding the properties
webpackageId
(mandatory)artifactId
(mandatory)endpointId
(optional when referencing artifacts with webpackage.modelVersioin < 9)
<head> ... <!-- The below script block needs to be placed before(!) the crc-loader script is included --> <script> window.cubx = { CRCInit: { rootDependencyExcludes: [ { webpackageId: 'third-party-lib@1.0', artifactId: 'awesome-lib-util' } ] } }; </script> ... </head> <body> ... <first-demo-component cubx-webpackage-id="demo-package@1.0"> </first-demo-component> ... </body>
The scope of dependency excludes
There is a difference between rootDependencyExcludes
and dependency excludes which are defined for a specific artifact. The main difference is that rootDependencyExcludes
always apply to the whole dependency tree. So you could say so they are global. An artifact that added into rootDependencyExcludes
array will always be ignored.
In contrast if you define a dependency exclude on artifact level using the Cubbles TAG API then this exclude is only valid within the dependencies of that artifact the exclude is bound to. Let's see an example for pointing out the differences.
<body> ... <my-first-cubble webpackage-id="..."> <cubx-dependency-excludes> <cubx-dependency-exclude artifact-id="another-artifact" webpackage-id="another-package@1.0"></cubx-dependency-exclude> </cubx-dependency-excludes> </my-first-cubble> ... <my-second-cubble webpackage-id="..."></my-second-cubble> ... </body>
In the example above there are two different Cubble components instantiated. Assuming that my-first-cubble
as well as my-second-cubble
does use artifact another-artifact
from webpackage another-package@1.0.
The exclude defined for this shared artifact is only valid within the dependencies of my-first-cubble
. Because it is only declared for my-first-cubble
. And because my-second-cubble
does need this artifact the exclude will be ignored by the Dependency Manager of the RTE.
Replace artifacts in existing dependencies
When combining dependency addition and dependency excludes it it possible to replace artifacts in existing dependencies.
The example on the ride hand side replaces the artifact awesome-lib-util
from webpackage third-party-lib@1.0
with artifact awesome-lib-util
from webpackage third-party-lib@2.0
In fact here we replaced an existing dependency with a newer version of it's own.
<head> ... </head> <body> ... <first-demo-component cubx-webpackage-id="demo-package@1.0"> <cubx-dependencies> <cubx-dependency webpackage-id="third-party-lib@2.0" artifact-id="awesome-lib-util"> </cubx-dependency> </cubx-dependencies> <cubx-dependency-excludes> <cubx-dependency-exclude webpackage-id="third-party-lib@1.0" artifact-id="awesome-lib-util"> </cubx-dependency-exclude> </cubx-dependency-excludes> </first-demo-component> ... </body>