Hello World,
Helios Kernel is a library for managing dependencies between javascript modules, implementing the “classic” approach, often found in other languages and environments - using the include () function.
This method differs from other approaches in its simplicity: dependencies are listed at the beginning of the module along the exact path to the file, the module body contains code that is executed after loading the module dependencies.
')
Helios Kernel adheres to the
KISS principle, so there are some missing opportunities here that are commonly expected from a dependency management library. When using Helios Kernel, you do not need to describe the config with the rules for finding paths for different modules, or export library functions through a special object. But this library was written just because I wanted to simply plug in the necessary modules and write code, without running into abrupt opportunities with the indication of each new dependency.
Helios Kernel supports dynamic loading (and unloading) of dependencies in runtime, and the library itself and the format of the modules are compatible between nodejs and the browser environment — that is, the modules can be used without modification or translation.
In this article, the classic approach implemented in Helios Kernel is compared with dependency management using
RequireJS and shows how the Helios Kernel approach allows you to avoid some difficulties.
Introduction
Helios Kernel has such features:
- Dependencies are determined using the include () function in the module header. The exact relative path to the file is used as an argument.
- After listing the dependencies, the init () function is defined, which contains the module code. This code will be executed after all dependencies are loaded.
Therefore, the description of the relationship between the two modules is as follows.
The library module myLibrary.js, which declares some functionality:
init = function() {
And the module connects and uses this library:
include("path/to/myLibrary.js"); init = function() {
Here, to “export” a library object, the definition of the myLibrary global variable in the first module is used. Now this method is considered to be “wrong”, because global objects can be accessed from anywhere. But I use it here because it is most illustrative as an example. Helios Kernel does not impose any restrictions on the way objects are transferred between modules: there can be any code inside the init function. Including there you can define a function-factory, which will return only the “exported object”.
But if you only need to define the local variables of the module, for this you can use the scope of the function init ().
Next, I will give examples in which the use of Helios Kernel makes the code easier compared to RequireJS
Module descriptions
The description format of the module with dependencies is as follows:
RequireJS | Helios kernel |
---|
define(
|
|
The way of exporting library objects used in RequireJS makes it necessary to specify the name of the dependency twice - once the name of the module where the dependency is located, the second time - the name of the argument where this dependency will be exported.
This especially complicates the readability of RequireJS modules when there are more dependencies:
RequireJS | Helios kernel |
---|
define( [ 'dep1', 'dep2', 'dep3', 'dep4', 'dep5', 'dep6', 'dep7' ], function ( dep1, dep2, dep3, dep4, dep5, dep6, dep7) {
| include("deps/dep1.js"); include("deps/dep2.js"); include("deps/dep3.js"); include("deps/dep4.js"); include("deps/dep5.js"); include("deps/dep6.js"); include("deps/dep7.js"); include("deps/dep8.js"); init = function() {
|
In order to simplify such code, RequireJS even came up with an alternative way to describe dependencies, the
simplified CommmonJS . Using this technique, you can describe dependencies as follows:
define( [ 'dep1', 'dep2', 'dep3', 'dep4', 'dep5', 'dep6', 'dep7' ], function (require) { var dep1 = require('dep1'), dep2 = require('dep2'), dep3 = require('dep3'), dep4 = require('dep4'), dep5 = require('dep5'), dep6 = require('dep6'), dep7 = require('dep7');
Such a record allows you to slightly simplify the formatting and improve readability, but even here you have to mention the name of dependencies several times. In addition, this syntactic sugar adds another complication in the form of another way of addressing dependencies.
Helios Kernel allows you to avoid all this. Additional dependency requires only one mention with include ().
Creating Collecting Modules
Suppose there are several modules that are often used together in many parts of a project. Or there is a library that consists of several parts, and you need to get all these parts at once. The easiest way to get multiple modules is to connect them all clearly every time where they are needed.
But a big project is divided into modules in order not to duplicate the extra code. Therefore, you can write one common module that will connect the rest.
However, in the case of RequireJS, it will be necessary to still export the required dependencies and “forward” them through the exported common module object.
In the case of Helios Kernel, it’s enough just to list the dependencies:
RequireJS | Helios kernel |
---|
define( 'depCommon', [ 'dep1', 'dep2', 'dep3' ], function( dep1, dep2, dep3 ) { return { dep1 : dep1, dep2 : dep2, dep3 : dep3 } } );
| include('deps/dep1.js'); include('deps/dep2.js'); include('deps/dep3.js');
|
For a common module written in the Helios Kernel format, it is not even necessary to describe the function init (). It also simplifies readability - if you look at the code of this module - you can immediately see that it does not perform any actions, but only connects additional modules.
But in the case of the common module with RequireJS, you will also have to rewrite all cases of its export. If earlier it was necessary to refer to the individual exported parts as dep1, dep2, ..., now it needs to be replaced by depCommon.dep1, depCommon.dep2, ...
Ease of use of regular javascript libraries
We are talking about libraries that are supposed to be connected to an html page using the script tag.
The format of the Helios Kernel module is much closer to regular libraries, because any code can be contained within the init () function. Therefore, in order to turn a regular library into a module, it is enough to wrap it in the definition of the function init (), and after that it can be connected using include ().
In the case of RequireJS, converting the library into a module is much more difficult, because the module must export the objects to be defined and refactoring would have to be done. Instead, it is proposed to describe the module in the config using the
shim attribute. However, even this approach
can lead to problems .
Easy porting between the web and nodejs
In order to use the RequireJS modules on the server in the nodejs environment, you can use the
r.js library, which allows you to connect such modules to nodejs.
In the opposite direction: a project written in the format of the CommonJS modules used in the node can be converted to a web library using
browserify . But it will not be a module, but a big bundle, connected with the script tag (or the shim config in RequireJS).
Helios Kernel simplifies this task due to the fact that the modules work without changes and conversions on both platforms.
Website:
http://asvd.imtqy.com/helios-kernel/Code:
https://github.com/asvd/helios-kernel/releases/download/v0.9.5/helios-kernel-0.9.5.tar.gzGitHub:
https://github.com/asvd/helios-kernel